gitlab error compiling css asset

用户在使用apt-get upgrade后遇到GitLab无法访问的问题。错误提示显示node_module未找到,尝试通过重新安装nodejs和npm来解决,但在运行npminstall --only=production时遇到安装失败的情况。
部署运行你感兴趣的模型镜像

我在进行了apt-get upgrade之后, gitlab访问不了了……

所以不要随变upgrade啊!!!

出错如下:


搜到解决方法如下:参考链接:https://gitlab.com/gitlab-org/omnibus-gitlab/issues/2142


貌似问题是node_module找不到了,解决的方法是重新安装nodejs,npm

但是!我没有安装成功。

$ cd /
$ cd /opt/gitlab/embedded/service/gitlab-rails
$ apt-get update && apt-get install npm
$ npm install --only=production
$ vim /opt/gitlab/embedded/service/gitlab-rails/config/enviroments/production.rb


- config.serve_static_files = false
+ config.serve_static_files = true


$ gitlab-ctl restart


在npm install --only=production卡住,安装不成功……。

您可能感兴趣的与本文相关的镜像

Dify

Dify

AI应用
Agent编排

Dify 是一款开源的大语言模型(LLM)应用开发平台,它结合了 后端即服务(Backend as a Service) 和LLMOps 的理念,让开发者能快速、高效地构建和部署生产级的生成式AI应用。 它提供了包含模型兼容支持、Prompt 编排界面、RAG 引擎、Agent 框架、工作流编排等核心技术栈,并且提供了易用的界面和API,让技术和非技术人员都能参与到AI应用的开发过程中

#!/usr/bin/env python """ Defines a CLI for compiling Sass (both default and themed) into CSS. Should be run from the root of edx-platform using `npm run` wrapper. Requirements for this scripts are stored in requirements/edx/assets.in. Get more details: npm run compile-sass -- --help npm run compile-sass -- --dry Setup (Tutor and Devstack will do this for you): python -m venv venv . venv/bin/activate pip install -r requirements/edx/assets.txt Usage: npm run compile-sass # prod, no args npm run compile-sass -- ARGS # prod, with args npm run compile-sass-dev # dev, no args npm run compile-sass-dev -- ARGS # dev, with args This script is intentionally implemented in a very simplistic way. It prefers repetition over abstraction, and its dependencies are minimal (just click and libsass-python, ideally). We do this because: * If and when we migrate from libsass-python to something less ancient like node-sass or dart-sass, we will want to re-write this script in Bash or JavaScript so that it can work without any backend tooling. By keeping the script dead simple, that will be easier. * The features this script supports (legacy frontends & comprehensive theming) are on the way out, in favor of micro-frontends, branding, and Paragon design tokens. We're not sure how XBlock view styling will fit into that, but it probably can be much simpler than comprehensive theming. So, we don't need this script to be modular and extensible. We just need it to be obvious, robust, and easy to maintain until we can delete it. See docs/decisions/0017-reimplement-asset-processing.rst for more details. """ from __future__ import annotations import glob import os import subprocess import sys from pathlib import Path import click # Accept both long- and short-forms of these words, but normalize to long form. # We accept both because edx-platform asset build scripts historically use the short form, # but NODE_ENV uses the long form, so to make them integrate more seamlessly we accept both. NORMALIZED_ENVS = { "prod": "production", "dev": "development", "production": "production", "development": "development", } @click.option( "-T", "--theme-dir", "theme_dirs", metavar="PATH", multiple=True, envvar="COMPREHENSIVE_THEME_DIRS", type=click.Path(path_type=Path), help=( "Consider sub-dirs of PATH as themes. " "Multiple theme dirs are accepted. " "If none are provided, we look at colon-separated paths on the COMPREHENSIVE_THEME_DIRS env var." ), ) @click.option( "-t", "--theme", "themes", metavar="NAME", multiple=True, type=str, help=( "A theme to compile. " "NAME should be a sub-dir of a PATH provided by --theme-dir. " "Multiple themes are accepted. " "If none are provided, all available themes are compiled." ), ) @click.option( "--skip-default", is_flag=True, help="Don't compile default Sass.", ) @click.option( "--skip-themes", is_flag=True, help="Don't compile any themes (overrides --theme* options).", ) @click.option( "--skip-lms", is_flag=True, help="Don't compile any LMS Sass.", ) @click.option( "--skip-cms", is_flag=True, help="Don't compile any CMS Sass.", ) @click.option( "--env", type=click.Choice(["dev", "development", "prod", "production"]), default="prod", help="Optimize CSS for this environment. Defaults to 'prod'.", ) @click.option( "--dry", is_flag=True, help="Print what would be compiled, but don't compile it.", ) @click.option( "-h", "--help", "show_help", is_flag=True, help="Print this help.", ) @click.command() @click.pass_context def main( context: click.Context, theme_dirs: list[Path], themes: list[str], skip_default: bool, skip_themes: bool, skip_lms: bool, skip_cms: bool, env: str, dry: bool, show_help: bool, ) -> None: """ Compile Sass for edx-platform and its themes. Default Sass is compiled unless explicitly skipped. Additionally, any number of themes may be specified using --theme-dir and --theme. Default CSS is compiled to css/ directories in edx-platform. Themed CSS is compiled to css/ directories in their source themes. """ def compile_sass_dir( message: str, source_root: Path, target_root: Path, includes: list[Path], tolerate_missing: bool = False, ) -> None: """ Compile a directory of Sass into a target CSS directory, and generate any missing RTL CSS. Structure of source dir is mirrored in target dir. IMPLEMENTATION NOTES: ===================== libsass is a C++ library for compiling Sass (ref: https://github.com/sass/libsass). libsass-python is a small PyPI package wrapping libsass, including: * The `_sass` module, which provides direct Python bindings for the C++ library. (ref: https://github.com/sass/libsass-python/blob/0.10.0/pysass.cpp) * The `sass` module, which adds some friendly Pythonic wrapper functions around `_sass`, notably `sass.compile_dirname(...)`. (ref: https://github.com/sass/libsass-python/blob/0.10.0/sass.py#L198-L201) Our legacy Sass code only works with a super old version of libsass (3.3.2,) which is provided to us by a super old version of libsass-python (0.10.0). In this super old libsass-python version: * the `sass` module DOESN'T support Python 3.11+, but * the `_sass` module DOES support Python 3.11+. Upgrading our Sass to work with newer a libsass version would be arduous and would potentially break comprehensive themes, so we don't want to do that. Forking libsass-python at v0.10.0 and adding Python 3.11+ support would mean adding another repo to the openedx org. Rather than do either of those, we've decided to hack around the problem by just reimplementing what we need of `sass.compile_dirname` here, directly on top of the `_sass` C++ binding module. Eventually, we may eschew libsass-python altogether by switching to SassC@3.3.2, a direct CLI for libsass@3.3.2. (ref: https://github.com/sass/sassc). This would be nice because it would allow us to remove Python from the Sass build pipeline entirely. However, it would mean explicitly compiling & installing both libsass and SassC within the edx-platform build environment, which has its own drawbacks. """ # Constants from libsass-python SASS_STYLE_NESTED = 0 _SASS_STYLE_EXPANDED = 1 _SASS_STYLE_COMPACT = 2 SASS_STYLE_COMPRESSED = 3 SASS_COMMENTS_NONE = 0 SASS_COMMENTS_LINE_NUMBERS = 1 # Defaults from libass-python precision = 5 source_map_filename = None custom_functions = [] importers = None use_dev_settings: bool = NORMALIZED_ENVS[env] == "development" fs_encoding: str = sys.getfilesystemencoding() or sys.getdefaultencoding() output_style: int = SASS_STYLE_NESTED if use_dev_settings else SASS_STYLE_COMPRESSED source_comments: int = SASS_COMMENTS_LINE_NUMBERS if use_dev_settings else SASS_COMMENTS_NONE include_paths: bytes = os.pathsep.join(str(include) for include in includes).encode(fs_encoding) click.secho(f" {message}...", fg="cyan") click.secho(f" Source: {source_root}") click.secho(f" Target: {target_root}") if not source_root.is_dir(): if tolerate_missing: click.secho(f" Skipped because source directory does not exist.", fg="yellow") return else: raise FileNotFoundError(f"missing Sass source dir: {source_root}") click.echo(f" Include paths:") for include in includes: click.echo(f" {include}") click.echo(f" Files:") for dirpath, _, filenames in os.walk(str(source_root)): for filename in filenames: if filename.startswith('_'): continue if not filename.endswith(('.scss', '.sass')): continue source = Path(dirpath) / filename target = (target_root / source.relative_to(source_root)).with_suffix('.css') click.echo(f" {source} -> {target}") if not dry: # Import _sass late so that this script can be dry-run without installing # libsass, which takes a while as it must be compiled from its C source. from _sass import compile_filename # pylint: disable=protected-access success, output, _ = compile_filename( str(source).encode(fs_encoding), output_style, source_comments, include_paths, precision, source_map_filename, custom_functions, importers, ) output_text = output.decode('utf-8') if not success: raise Exception(f"Failed to compile {source}: {output_text}") target.parent.mkdir(parents=True, exist_ok=True) with open(target, 'w', encoding="utf-8") as target_file: target_file.write(output_text) click.secho(f" Done.", fg="green") # For Sass files without explicit RTL versions, generate # an RTL version of the CSS using the rtlcss library. for sass_path in glob.glob(str(source_root) + "/**/*.scss"): if Path(sass_path).name.startswith("_"): # Don't generate RTL CSS for partials continue if sass_path.endswith("-rtl.scss"): # Don't generate RTL CSS if the file is itself an RTL version continue if Path(sass_path.replace(".scss", "-rtl.scss")).exists(): # Don't generate RTL CSS if there is an explicit Sass version for RTL continue click.echo(" Generating missing right-to-left CSS:") source_css_file = sass_path.replace(str(source_root), str(target_root)).replace( ".scss", ".css" ) target_css_file = source_css_file.replace(".css", "-rtl.css") click.echo(f" Source: {source_css_file}") click.echo(f" Target: {target_css_file}") if not dry: subprocess.run(["rtlcss", source_css_file, target_css_file]) click.secho(" Generated.", fg="green") # Information click.secho(f"USING ENV: {NORMALIZED_ENVS[env]}", fg="blue") if dry: click.secho(f"DRY RUN: Will print compile steps, but will not compile anything.", fg="blue") click.echo() # Warnings if show_help: click.echo(context.get_help()) return if skip_lms and skip_cms: click.secho("WARNING: You are skipping both LMS and CMS... nothing will be compiled!", fg="yellow") if skip_default and skip_themes: click.secho("WARNING: You are skipped both default Sass and themed Sass... nothing will be compiled!", fg="yellow") click.echo() # Build a list of theme paths: if skip_themes: theme_paths = [] else: theme_paths = [ theme_dir / theme # For every theme dir, for theme_dir in theme_dirs for theme in ( # for every theme name (if theme names provided), themes or # or for every subdir of theme dirs (if no theme name provided), (theme_dir_entry.name for theme_dir_entry in theme_dir.iterdir()) ) # consider the path a theme if it has a lms/ or cms/ subdirectory. if (theme_dir / theme / "lms").is_dir() or (theme_dir / theme / "cms").is_dir() ] # We expect this script to be run from the edx-platform root. repo = Path(".") if not (repo / "xmodule").is_dir(): # Sanity check: If the xmodule/ folder is missing, we're definitely not at the root # of edx-platform, so save the user some headache by exiting early. raise Exception(f"{__file__} must be run from the root of edx-platform") # Every Sass compilation will use have these directories as lookup paths, # regardless of theme. common_includes = [ repo / "common" / "static", repo / "common" / "static" / "sass", repo / "node_modules" / "@edx", repo / "node_modules", ] if not skip_default: click.secho(f"Compiling default Sass...", fg="cyan", bold=True) if not skip_lms: compile_sass_dir( "Compiling default LMS Sass", repo / "lms" / "static" / "sass", repo / "lms" / "static" / "css", includes=[ *common_includes, repo / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass", ], ) compile_sass_dir( "Compiling default certificate Sass", repo / "lms" / "static" / "certificates" / "sass", repo / "lms" / "static" / "certificates" / "css", includes=[ *common_includes, repo / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass", ], ) if not skip_cms: compile_sass_dir( "Compiling default CMS Sass", repo / "cms" / "static" / "sass", repo / "cms" / "static" / "css", includes=[ *common_includes, repo / "lms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass", ], ) click.secho(f"Done compiling default Sass!", fg="cyan", bold=True) click.echo() for theme in theme_paths: click.secho(f"Compiling Sass for theme at {theme}...", fg="cyan", bold=True) if not skip_lms: compile_sass_dir( "Compiling default LMS Sass with themed partials", repo / "lms" / "static" / "sass", theme / "lms" / "static" / "css", includes=[ *common_includes, theme / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass", ], tolerate_missing=True, ) compile_sass_dir( "Compiling themed LMS Sass as overrides to CSS from previous step", theme / "lms" / "static" / "sass", theme / "lms" / "static" / "css", includes=[ *common_includes, theme / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass" / "partials", repo / "lms" / "static" / "sass", ], tolerate_missing=True, ) compile_sass_dir( "Compiling themed certificate Sass", theme / "lms" / "static" / "certificates" / "sass", theme / "lms" / "static" / "certificates" / "css", includes=[ *common_includes, theme / "lms" / "static" / "sass" / "partials", theme / "lms" / "static" / "sass", ], tolerate_missing=True, ) if not skip_cms: compile_sass_dir( "Compiling default CMS Sass with themed partials", repo / "cms" / "static" / "sass", theme / "cms" / "static" / "css", includes=[ *common_includes, repo / "lms" / "static" / "sass" / "partials", theme / "cms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass", ], tolerate_missing=True, ) compile_sass_dir( "Compiling themed CMS Sass as overrides to CSS from previous step", theme / "cms" / "static" / "sass", theme / "cms" / "static" / "css", includes=[ *common_includes, repo / "lms" / "static" / "sass" / "partials", theme / "cms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass" / "partials", repo / "cms" / "static" / "sass", ], tolerate_missing=True, ) click.secho(f"Done compiling Sass for theme at {theme}!", fg="cyan", bold=True) click.echo() # Report what we did. click.secho("Successfully compiled:", fg="green", bold=True) if not skip_default: click.secho(f" - {repo.absolute()} (default Sass)", fg="green") for theme in theme_paths: click.secho(f" - {theme}", fg="green") if skip_lms: click.secho(f"(skipped LMS)", fg="yellow") if skip_cms: click.secho(f"(skipped CMS)", fg="yellow") if __name__ == "__main__": main(prog_name="npm run compile-sass --") 这个 subprocess.run(["rtlcss", source_css_file, target_css_file]) 无法执行
最新发布
09-25
@[TOC](目录) ## webpack5和webpack4之间重要的区别 1. 性能改进:webpack5在构建速度和打包体积方面进行了一些优化。它引入了持久缓存,可以减少构建时间。 此外,webpack5还引入了更好的树摇(tree shaking)算法,可以更好地优化打包体积。 2. 模块联邦(Module Federation)新增特性:这是webpack5中最重要的新功能之一。模块联邦允许不同的应用程序共享模块,从而实现更好的代码复用和拆分。这对于构建大型的微服务架构非常有用。 ```javascript new ModuleFederationPlugin({ name: 'myApp', filename: 'remoteEntry.js', remotes: {}, exposes: { './Button': './src/Button', }, shared: { react: { singleton: true } }, }); ``` 4. 支持WebAssembly:webpack5对WebAssembly提供了更好的支持。它可以直接导入和导出WebAssembly模块,并且可以通过配置进行优化。 5. 缓存策略增强:webpack5引入了更好的缓存策略,可以更好地利用浏览器缓存。这可以减少用户在更新应用程序时需要下载的文件数量。 6. Tree Shaking 改进:webpack5引入了更好的Tree Shaking算法,可以更好地识别和删除未使用的代码。这可以进一步减少打包体积。 7. 改进的持久缓存:webpack5引入了更好的持久缓存策略,可以更好地利用缓存。这可以减少构建时间。 ## 安装 ```powershell npm init -y // 初始化package.json npm install webpack webpack-cli --save-dev npx webpack --watch // 监听文件修改 npx webpack-dev-server // 以server的方式启动项目,不会打包物理文件,而是输出到内存 ``` ## 生命周期 ### 生命周期hooks beforeRun:在webpack开始运行之前调用,可以在此处执行一些准备工作。 run:在webpack开始运行时调用,可以在此处执行一些初始化操作。 beforeCompile:在webpack开始编译之前调用,可以在此处执行一些准备工作。 compile:在webpack开始编译时调用,可以在此处执行一些初始化操作。 make:在webpack开始构建编译器时调用,可以在此处执行一些准备工作。 afterCompile:在webpack完成编译之后调用,可以在此处执行一些后处理操作。 emit:在webpack生成最终的资源之前调用,可以在此处执行一些额外的操作,如生成额外的文件。 afterEmit:在webpack生成最终的资源之后调用,可以在此处执行一些后处理操作。 done:在webpack完成构建之后调用,可以在此处执行一些清理工作。 ### 使用hooks ```javascript module.exports = { // ... plugins: [ { apply: (compiler) => { compiler.hooks.beforeRun.tap('MyPlugin', () => { console.log('Before run'); }); compiler.hooks.done.tap('MyPlugin', () => { console.log('Build done'); }); } } ] }; //在上述示例中,我们定义了一个自定义插件,并在其中使用了beforeRun和done两个生命周期钩子函数。 //在这些钩子函数中,我们可以执行一些自定义的操作,如输出日志信息。 ``` ## webpack中的loader(转换器) ### 工作原理 webpack loader 在 webpack 构建过程中的生命周期中的工作主要分为以下几个阶段: - 解析阶段:webpack 会根据配置文件中的入口文件,递归解析所有的依赖模块。在这个阶段,webpack 会根据文件的后缀名来确定使用哪个 loader 来处理该文件。 - 编译阶段:在这个阶段,webpack 会将解析后的模块转换成 AST(抽象语法树),并且根据配置文件中的规则,将模块中的代码进行转换和处理。 这个阶段是 loader 的主要工作阶段,loader 可以对模块进行各种处理,例如转换代码、添加额外的功能等。 - 生成阶段:在这个阶段,webpack 会根据处理后的模块生成最终的输出文件。输出文件的格式和路径可以通过配置文件进行配置。 在这些阶段中,loader 主要在编译阶段发挥作用。loader 可以通过导出一个函数来定义自己的处理逻辑,这个函数接收一个参数,即待处理的模块的源代码,然后返回处理后的代码。 ### 常用loader 以下是一些常用的webpack loader: - babel-loader:用于将ES6+的JavaScript代码转换为ES5代码,以便在旧版本浏览器中运行。 - css-loader:用于解析CSS文件,并处理其中的import和url()等语法。 - style-loader:将解析后的CSS代码以`<style>`标签的形式插入到HTML文件中。 - file-loader:用于处理文件资源(如图片、字体等),并将其复制到输出目录中。 - url-loader:类似于file-loader,但可以根据文件大小将文件转换为DataURL,以减少HTTP请求。 - sass-loader:用于将Sass/SCSS代码转换为CSS代码。 - less-loader:用于将Less代码转换为CSS代码。 - postcss-loader:用于对CSS代码进行后处理,如自动添加浏览器前缀等。 - vue-loader:用于解析和转换Vue单文件组件。 - ts-loader:用于将TypeScript代码转换为JavaScript代码。 ### 自定义loader ```javascript // 核心代码: function clearConsoleLoader(source) { // 使用正则表达式匹配并替换console语句 const modifiedSource = source.replace(/console\.[a-z]+\(.+\);?/g, ''); return modifiedSource; } module.exports = clearConsoleLoader; //使用 module.exports = { // ... module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: [ 'babel-loader', './path/to/clearConsoleLoader.js' ] } ] } }; ``` ## webpack中的plugins(插件) ### 工作原理 webpack 插件是用来扩展 webpack 功能的工具,它可以在 webpack 构建过程中的不同阶段执行一些额外的操作。 插件的工作原理是通过在 webpack 的构建过程中的不同生命周期中注册一些钩子函数,然后在对应的阶段执行这些钩子函数中的逻辑。 webpack 的构建过程中有以下几个生命周期: - 初始化阶段:在这个阶段,webpack 会初始化配置参数,加载插件,并准备开始编译。 - 编译阶段:在这个阶段,webpack 会从入口文件开始递归解析所有的依赖模块,并将模块转换成 AST(抽象语法树),然后根据配置文件中的规则进行转换和处理。 - 完成编译阶段:在这个阶段,webpack 已经完成了所有的模块的转换和处理,并且生成了最终的输出文件。 - 输出阶段:在这个阶段,webpack 会将生成的输出文件写入到磁盘上。 插件可以在这些生命周期中的任意阶段注册对应的钩子函数,并在钩子函数中执行一些额外的操作。 ### 自定义plugins ```javascript class MyPlugin { apply(compiler) { // 注册初始化阶段的钩子函数 compiler.hooks.initialize.tap('MyPlugin', () => { console.log('MyPlugin initialized'); }); // 注册编译阶段的钩子函数 compiler.hooks.compile.tap('MyPlugin', () => { console.log('MyPlugin compiling'); }); } } module.exports = MyPlugin; // 使用 const MyPlugin = require('./my-plugin'); module.exports = { // ... plugins: [ new MyPlugin(), ], }; ``` ## 打包过程 - 读取配置文件:Webpack会首先读取配置文件,根据配置文件中的入口、出口等信息进行打包。 - 解析模块依赖:Webpack会从指定的入口文件开始递归解析所有的模块依赖,直到找到所有的模块。 - 加载器处理:对于不同类型的模块,Webpack会使用相应的加载器对其进行处理。例如,对于JavaScript模块,Webpack会使用Babel加载器将ES6语法转换为ES5语法;对于CSS模块,Webpack会使用CSS加载器将CSS代码打包进JS文件中。 - 插件处理:在模块加载完成之后,Webpack会执行一系列插件,用于完成一些额外的任务,例如生成HTML文件、提取CSS文件等。 - 编译打包:Webpack将经过处理的模块和插件生成最终的打包文件。通常情况下,Webpack会生成一个或多个JavaScript文件,同时也可以生成其他类型的文件,例如CSS、图片等。 - 输出打包文件:Webpack将生成的打包文件输出到指定的目录中。通常情况下,Webpack会将打包文件输出到dist目录下。 ### 加速webpack打包速度和减小打包体积的优化 以下是一些加速Webpack打包和减小打包体积的技巧: 1. 优化Webpack配置:使用Tree shaking来减小打包体积,设置Webpack的mode为production以启用UglifyJsPlugin等插件进行代码压缩和优化。 2. 使用Webpack的code splitting功能:将代码分割成较小的块,以便在需要时动态加载。 3. 压缩图片和字体文件:使用ImageMinWebpackPlugin和FontminWebpackPlugin等插件来压缩图片和字体文件,减小打包体积。 4. 缓存:启用Webpack的缓存功能,以便在修改代码时只重新打包修改的文件,而不是重新打包所有文件。 5. 使用DLLPlugin和DllReferencePlugin:将一些第三方库打包成单独的文件,以便在每次打包应用程序时不必重新打包这些库。 6. 使用HappyPack插件:使用多线程来加速Webpack打包,以便同时处理多个任务。 7. 使用externals选项:将一些不需要打包的库从打包中排除,以便减小打包体积。 8. 使用Webpack-bundle-analyzer插件:分析打包后的文件,以便找出冗余的代码和依赖关系,进行优化。 这些技巧可以帮助优化Webpack的打包速度和打包体积。 ### webpack配置 ```javascript const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); // 自动引入资源插件 npm install --save-dev html-webpack-plugin const MiniCssExtracPlugin = require("mini-css-extrac-plugin"); // css抽离 const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); //css压缩 npm install css-minimizer-webpack-plugin --save-dev const TerserPlugin = require("terser-webpack-plugin"); // js压缩 npm install --save-dev terser-webpack-plugin //加载toml、yarm、json5数据资源 npm install toml yarm json5 -D const toml = require("toml"); const yarm = require("yarm"); const json5 = require("json5"); module.exports = (env) => { return { // 手动分离公共文件,通过配置成对象的方式实现多入口代码分割 // entry: { // index:{ // import:"./src/index.js", // dependOn: "shared" // 抽离公共文件 // }, // shared: "lodash" // 公共的js文件 // }, // 多入口 // entry: { // pageOne: './src/pageOne/index.js', // pageTwo: './src/pageTwo/index.js', // pageThree: './src/pageThree/index.js', // }, // 单入口 entry: { index: "./src/index.js", }, output: { filename: "scripts/[name].[contenthash].js", // 将所有的js放入同一个文件夹,并且根据文件名自动命名 path: path.resolve(__dirname, "./dist"), clean: true, // 清除上一次的垃圾文件 assetModuleFilename: "images/[contenthash][ext]", // 在images目录下,根据文件内容自动生成hash文件名 publicPath: "https://*****.com/", // 公共路径(cdn域名或者本地localhost) }, mode: env.prodection ? "prodection" : "development", // 生产环境或者开发环境 package.json 启动命令:npx webpack --env prodection devtool: "cheap-module-source-map", // 真实报错文件指向,生产环境一般不开启sourcemap // 插件(非必要的,缺少也不影响项目打包) plugins: [ new HtmlWebpackPlugin({ template: "./index.html", // 模板 filename: "app.html", inject: "body", // script 存在的位置 hash: true, // 解决缓存 minify: { removeAttributeQuotes: true, // 压缩,去掉引号 }, }), new MiniCssExtracPlugin({ filename: "style/[contenthash].css", }), ], devServer: { static: "./dist", // 监听根目录文件变化,自动刷新页面插件 npm install --save-dev webpack-dev-server //反向代理 proxy: { "/ajax": { target: "https:**********", ws: true, changeOrigin: true, }, }, }, // 模块(必要的,缺少影响项目打包) module: { rules: [ //资源模块类型我们称之为Asset Modules Type,总共有四种,来代替loader,分别是: // asset/resource:发送一个单独的文件并导出URL,替代file-loader // asset/inline:导出一个资源的data URI(base64),替代url-loader // asset/source:导出资源的源代码,之前通过使用raw-loader实现 // asset:介于asset/resource和asset/inline之间, 之前通过url-loader+limit属性实现。 { test: /\.(png|gif|jp?g|svg|webp|ico)$/, // 正则图片文件 type: "asset", generator: { filename: "images/[contenthash][ext]", // 优先级高于 assetModuleFilename }, }, { // 支持less // npm install style-loader css-loader less-loader less --save-dev // 抽离 npm install mini-css-extrac-plugin --save-dev webpack5环境下构建的插件 test: /\.(le|c)ss$/, // .less and .css use: [MiniCssExtracPlugin.loader,/* "style-loader", */ "css-loader","less-loader"], }, { test: /\.(woff|woff2|eot|ttf|oft)$/, // 正则字体文件 type: "asset/resource", }, //加载csv、xml数据资源 npm install csv-loader xml-loader -D { test: /\.(csv|tsv)$/, use: "csv-loader", }, { test: /\.xml$/, use: "xml-loader", }, //加载toml、yarm、json5数据资源 { test: /\.toml$/, type: "json", parser: { parse: toml.parse, }, }, { test: /\.yarm$/, type: "json", parser: { parse: yarm.parse, }, }, { test: /\.json5$/, type: "json", parser: { parse: json5.parse, }, }, // loader工具 支持数组方式链式调用,数组靠后的元素先执行 { // 压缩图片 //图片小于一定大小使用base64 否则使用file-loader产生真实图片 npm install url-loader --save-dev test: /\.(png|gif|jp?g|svg|webp|ico)$/, // 正则 use: [ { loader: "url-loader", options: { limit: 5000, //小于限定使用base64 name: "home/images/[name].[hash:8].[ext]", publicPath: `../../`, esModule: false, }, }, ], }, // 使用babel-loader npm install -D babel-loader @babel/core @babel/preset-env // regeneratorRuntime是webpack打包生成的全局辅助函数,由babel生成,用于兼容 async/await 的语法 // npm install --save @babel/runtime // npm install --save-dev @babel/plugin-transform-runtime { test: /\.js$/, exclude: /node_modules/, // *业务代码里面可能会引入node_modules外部js,这些js不需要babel-loader编译,因此需要排除掉 use: { loader: "babel-loader", // *引入babel-loader options: { presets: ["@babel/preset-env"], // *引入预设 plugins: [ [ "@babel/plugin-transform-runtime", // *配置插件信息 ], ], }, }, }, ], }, optimization: { minimizer: [new CssMinimizerPlugin(),new TerserPlugin()], //代码压缩 mode改为 production splitChunks: { // 缓存 cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: "vendors", chunks: "all", // 自动重复代码抽离 }, }, }, }, }; }; ``` ### webpack配置拆分 #### webpack.config.common.js文件公共环境配置 ```javascript const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); // 自动引入资源插件 npm install --save-dev html-webpack-plugin const MiniCssExtracPlugin = require("mini-css-extrac-plugin"); // css抽离 const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); //css压缩 npm install css-minimizer-webpack-plugin --save-dev const TerserPlugin = require("terser-webpack-plugin"); // js压缩 npm install --save-dev terser-webpack-plugin //加载toml、yarm、json5数据资源 npm install toml yarm json5 -D const toml = require("toml"); const yarm = require("yarm"); const json5 = require("json5"); module.exports = { entry: { index: "./src/index.js", }, output: { path: path.resolve(__dirname, "./dist"), clean: true, // 清除上一次的垃圾文件 assetModuleFilename: "images/[contenthash][ext]", // 在images目录下,根据文件内容自动生成hash文件名 }, // 插件(非必要的,缺少也不影响项目打包) plugins: [ new HtmlWebpackPlugin({ template: "./index.html", // 模板 filename: "app.html", inject: "body", // script 存在的位置 hash: true, // 解决缓存 minify: { removeAttributeQuotes: true, // 压缩,去掉引号 }, }), new MiniCssExtracPlugin({ filename: "style/[contenthash].css", }), ], // 模块(必要的,缺少影响项目打包) module: { rules: [ //资源模块类型我们称之为Asset Modules Type,总共有四种,来代替loader,分别是: // asset/resource:发送一个单独的文件并导出URL,替代file-loader // asset/inline:导出一个资源的data URI(base64),替代url-loader // asset/source:导出资源的源代码,之前通过使用raw-loader实现 // asset:介于asset/resource和asset/inline之间, 之前通过url-loader+limit属性实现。 { test: /\.(png|gif|jp?g|svg|webp|ico)$/, // 正则图片文件 type: "asset", generator: { filename: "images/[contenthash][ext]", // 优先级高于 assetModuleFilename }, }, { // 支持less // npm install style-loader css-loader less-loader less --save-dev // 抽离 npm install mini-css-extrac-plugin --save-dev webpack5环境下构建的插件 test: /\.(le|c)ss$/, // .less and .css use: [ MiniCssExtracPlugin.loader, /* "style-loader", */ "css-loader", "less-loader", ], }, { test: /\.(woff|woff2|eot|ttf|oft)$/, // 正则字体文件 type: "asset/resource", }, //加载csv、xml数据资源 npm install csv-loader xml-loader -D { test: /\.(csv|tsv)$/, use: "csv-loader", }, { test: /\.xml$/, use: "xml-loader", }, //加载toml、yarm、json5数据资源 { test: /\.toml$/, type: "json", parser: { parse: toml.parse, }, }, { test: /\.yarm$/, type: "json", parser: { parse: yarm.parse, }, }, { test: /\.json5$/, type: "json", parser: { parse: json5.parse, }, }, // loader工具 支持数组方式链式调用,数组靠后的元素先执行 { // 压缩图片 //图片小于一定大小使用base64 否则使用file-loader产生真实图片 npm install url-loader --save-dev test: /\.(png|gif|jp?g|svg|webp|ico)$/, // 正则 use: [ { loader: "url-loader", options: { limit: 5000, //小于限定使用base64 name: "home/images/[name].[hash:8].[ext]", publicPath: `../../`, esModule: false, }, }, ], }, // 使用babel-loader npm install -D babel-loader @babel/core @babel/preset-env // regeneratorRuntime是webpack打包生成的全局辅助函数,由babel生成,用于兼容 async/await 的语法 // npm install --save @babel/runtime // npm install --save-dev @babel/plugin-transform-runtime { test: /\.js$/, exclude: /node_modules/, // *业务代码里面可能会引入node_modules外部js,这些js不需要babel-loader编译,因此需要排除掉 use: { loader: "babel-loader", // *引入babel-loader options: { presets: ["@babel/preset-env"], // *引入预设 plugins: [ [ "@babel/plugin-transform-runtime", // *配置插件信息 ], ], }, }, }, ], }, optimization: { splitChunks: { // 缓存 cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: "vendors", chunks: "all", // 自动重复代码抽离 }, }, }, }, }; ``` #### webpack.config.common.js文件公共环境配置 ```javascript const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); // 自动引入资源插件 npm install --save-dev html-webpack-plugin const MiniCssExtracPlugin = require("mini-css-extrac-plugin"); // css抽离 const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); //css压缩 npm install css-minimizer-webpack-plugin --save-dev const TerserPlugin = require("terser-webpack-plugin"); // js压缩 npm install --save-dev terser-webpack-plugin //加载toml、yarm、json5数据资源 npm install toml yarm json5 -D const toml = require("toml"); const yarm = require("yarm"); const json5 = require("json5"); module.exports = { entry: { index: "./src/index.js", }, output: { path: path.resolve(__dirname, "./dist"), clean: true, // 清除上一次的垃圾文件 assetModuleFilename: "images/[contenthash][ext]", // 在images目录下,根据文件内容自动生成hash文件名 }, // 插件(非必要的,缺少也不影响项目打包) plugins: [ new HtmlWebpackPlugin({ template: "./index.html", // 模板 filename: "app.html", inject: "body", // script 存在的位置 hash: true, // 解决缓存 minify: { removeAttributeQuotes: true, // 压缩,去掉引号 }, }), new MiniCssExtracPlugin({ filename: "style/[contenthash].css", }), ], // 模块(必要的,缺少影响项目打包) module: { rules: [ //资源模块类型我们称之为Asset Modules Type,总共有四种,来代替loader,分别是: // asset/resource:发送一个单独的文件并导出URL,替代file-loader // asset/inline:导出一个资源的data URI(base64),替代url-loader // asset/source:导出资源的源代码,之前通过使用raw-loader实现 // asset:介于asset/resource和asset/inline之间, 之前通过url-loader+limit属性实现。 { test: /\.(png|gif|jp?g|svg|webp|ico)$/, // 正则图片文件 type: "asset", generator: { filename: "images/[contenthash][ext]", // 优先级高于 assetModuleFilename }, }, { // 支持less // npm install style-loader css-loader less-loader less --save-dev // 抽离 npm install mini-css-extrac-plugin --save-dev webpack5环境下构建的插件 test: /\.(le|c)ss$/, // .less and .css use: [ MiniCssExtracPlugin.loader, /* "style-loader", */ "css-loader", "less-loader", ], }, { test: /\.(woff|woff2|eot|ttf|oft)$/, // 正则字体文件 type: "asset/resource", }, //加载csv、xml数据资源 npm install csv-loader xml-loader -D { test: /\.(csv|tsv)$/, use: "csv-loader", }, { test: /\.xml$/, use: "xml-loader", }, //加载toml、yarm、json5数据资源 { test: /\.toml$/, type: "json", parser: { parse: toml.parse, }, }, { test: /\.yarm$/, type: "json", parser: { parse: yarm.parse, }, }, { test: /\.json5$/, type: "json", parser: { parse: json5.parse, }, }, // loader工具 支持数组方式链式调用,数组靠后的元素先执行 { // 压缩图片 //图片小于一定大小使用base64 否则使用file-loader产生真实图片 npm install url-loader --save-dev test: /\.(png|gif|jp?g|svg|webp|ico)$/, // 正则 use: [ { loader: "url-loader", options: { limit: 5000, //小于限定使用base64 name: "home/images/[name].[hash:8].[ext]", publicPath: `../../`, esModule: false, }, }, ], }, // 使用babel-loader npm install -D babel-loader @babel/core @babel/preset-env // regeneratorRuntime是webpack打包生成的全局辅助函数,由babel生成,用于兼容 async/await 的语法 // npm install --save @babel/runtime // npm install --save-dev @babel/plugin-transform-runtime { test: /\.js$/, exclude: /node_modules/, // *业务代码里面可能会引入node_modules外部js,这些js不需要babel-loader编译,因此需要排除掉 use: { loader: "babel-loader", // *引入babel-loader options: { presets: ["@babel/preset-env"], // *引入预设 plugins: [ [ "@babel/plugin-transform-runtime", // *配置插件信息 ], ], }, }, }, ], }, optimization: { splitChunks: { // 缓存 cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: "vendors", chunks: "all", // 自动重复代码抽离 }, }, }, }, }; ``` #### webpack.config.dev.js文件开发环境配置 npx webpack -c ./webpack.config.dev.js ```javascript module.exports = { output: { filename: "scripts/[name].js", // 将所有的js放入同一个文件夹,并且根据文件名自动命名 }, mode: "development", // 生产环境或者开发环境 package.json 启动命令:npx webpack --env prodection devtool: "cheap-module-source-map", // 真实报错文件指向,生产 devServer: { static: "./dist", // 监听根目录文件变化,自动刷新页面插件 npm install --save-dev webpack-dev-server //反向代理 proxy: { "/ajax": { target: "https:**********", ws: true, changeOrigin: true, }, }, }, }; ``` #### webpack.config.prod.js文件生产环境配置 npx webpack -c ./webpack.config.prod.js ```javascript const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); //css压缩 npm install css-minimizer-webpack-plugin --save-dev const TerserPlugin = require("terser-webpack-plugin"); // js压缩 npm install --save-dev terser-webpack-plugin module.exports = { output: { filename: "scripts/[name].[contenthash].js", // 将所有的js放入同一个文件夹,并且根据文件名自动命名 publicPath: "https://*****.com/", // 公共路径(cdn域名或者本地localhost) }, mode: "prodection", // 生产环境或者开发环境 package.json 启动命令:npx webpack --env prodection optimization: { minimizer: [new CssMinimizerPlugin(), new TerserPlugin()], //代码压缩 mode改为 production }, performance: { hints: false, // 关闭性能提示 }, }; ``` #### webpack.config.js 运行:webpack -c ./webpack.config.js --env development ```javascript const { merge } = require ('webpack-merge') // npm install webpack-merge -D const commonConfig = require ('./webpack.config.common') const productionConfig = require ('./webpack.config.prod') const developmentConfig = require ('./webpack.config.dev') module.exports = (env) => { switch (true) { case env.development : return merge(commonConfig,developmentConfig) case env.production : return merge(commonConfig,productionConfig) defult: return new Error() } } ``` ### 封装webpack自定义插件 1. 创建一个 JavaScript 文件,并导出一个函数。这个函数将作为你的插件的构造函数。 2. 在函数中定义一个 apply 方法,该方法接收一个 compiler 参数。这个 compiler 对象是 Webpack 的核心,它包含了 Webpack 的所有配置和工作流程。 3. 在 apply 方法中,可以通过 compiler.hooks 对象访问 Webpack 的生命周期钩子。通过这些钩子,你可以在 Webpack 运行的不同阶段执行自定义代码。 4. 实现你的插件逻辑,例如在特定的 Webpack 钩子上注册回调函数,向编译器添加自定义插件等。 5. 将你的插件打包成一个 npm 模块,并在项目中引入和使用它。 下面是一个简单的 Webpack 插件示例: ```javascript const MyPlugin = function() {}; MyPlugin.prototype.apply = function(compiler) { compiler.hooks.done.tap('MyPlugin', stats => { console.log('Webpack is done!'); }); }; module.exports = MyPlugin; 在这个示例中,我们定义了一个 MyPlugin 插件,它在 Webpack 编译完成后输出一条信息。 在 apply 方法中,我们使用 compiler.hooks.done 钩子注册了一个回调函数,在编译完成后输出一条消息。 要使用这个插件,你需要将它打包成一个 npm 模块,并在 Webpack 配置文件中引入和使用它: const MyPlugin = require('my-plugin'); module.exports = { plugins: [ new MyPlugin() ] }; ``` 这个示例中,我们在 Webpack 配置文件中引入了 MyPlugin 插件,并将它作为插件数组的一项传递给 plugins 选项。这样,当 Webpack 编译时,MyPlugin 将会被启用并执行它的逻辑。
06-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值