node-sass 生成sourcemap/监听文件

本文介绍如何使用Node-Sass生成sourcemap,包括编译时、监听整个文件夹及监听单个文件时生成sourcemap的具体命令。帮助开发者在不同场景下实现源代码映射。

node-sass 生成sourcemap/监听文件

0.无关紧要的叨叨(可跳过)

遇到问题->>
不知道怎么用node-sass生成sourcemap文件,我本地的ruby环境下是可以直接生成的
这里写图片描述
但是现在做的项目就是要求把之前用ruby编译的saas文件全部改成用node-sass的,然后我以为只要在生成的css文件后加一个/*# sourceMappingURL=style.css.map */就好了,而且浏览器是可以看到定位到的.scss的(后来才发现是之前编译的map文件,难怪对不上号,点进去是空白0.0),网上找了好一会儿都没找到相关的命令,全是webpack或者ruby
,然后看了node-sass --help才解决,之前看help里有--source-map,没看到后面的内容有Emit source map (boolean, or path to output .map file),明明是很简单的东西,绕了一圈才解决,看来以后有问题要先看help


  Wrapper around libsass

  Usage:
    node-sass [options] <input.scss>
    cat <input.scss> | node-sass [options] > output.css

  Example: Compile foobar.scss to foobar.css
    node-sass --output-style compressed foobar.scss > foobar.css
    cat foobar.scss | node-sass --output-style compressed > foobar.css

  Example: Watch the sass directory for changes, compile with sourcemaps to the css directory
    node-sass --watch --recursive --output css
      --source-map true --source-map-contents sass

  Options
    -w, --watch                Watch a directory or file
    -r, --recursive            Recursively watch directories or files
    -o, --output               Output directory
    -x, --omit-source-map-url  Omit source map URL comment from output
    -i, --indented-syntax      Treat data from stdin as sass code (versus scss)
    -q, --quiet                Suppress log output except on error
    -v, --version              Prints version info
    --output-style             CSS output style (nested | expanded | compact | compressed)
    --indent-type              Indent type for output CSS (space | tab)
    --indent-width             Indent width; number of spaces or tabs (maximum value: 10)
    --linefeed                 Linefeed style (cr | crlf | lf | lfcr)
    --source-comments          Include debug info in output
    --source-map               Emit source map (boolean, or path to output .map file)
    --source-map-contents      Embed include contents in map
    --source-map-embed         Embed sourceMappingUrl as data URI
    --source-map-root          Base path, will be emitted in source-map as is
    --include-path             Path to look for imported files
    --follow                   Follow symlinked directories
    --precision                The amount of precision allowed in decimal numbers
    --error-bell               Output a bell character on errors
    --importer                 Path to .js file containing custom importer
    --functions                Path to .js file containing custom functions
    --help                     Print usage info

1.node-sass编译时生成sourcemap

node-sass --source-map map文件路径 sass文件路径 css文件路径

2. 监听整个文件夹 时生成sourcemap

node-sass --source-map map文件路径 --watch -r sass文件夹路径 -o css文件夹路径

3. 监听单个文件 时生成sourcemap

node-sass --source-map map文件路径 --watch sass文件夹路径 css文件夹路径

这里写图片描述

{ "name": "edx", "version": "0.1.0", "repository": "https://github.com/openedx/edx-platform", "scripts": { "postinstall": "scripts/copy-node-modules.sh", "build": "npm run webpack && npm run compile-sass", "build-dev": "cross-env npm run webpack-dev && npm run compile-sass-dev", "webpack": "cross-env NODE_ENV=development webpack --config webpack.dev.config.js", "webpack-dev": "NODE_ENV=development webpack --config=webpack.dev.config.js", "compile-sass": "scripts/compile_sass.py --env=${NODE_ENV:-production}", "compile-sass-dev": "scripts/compile_sass.py --env=development", "watch": "{ npm run watch-webpack& npm run watch-sass& } && sleep infinity", "watch-webpack": "npm run webpack-dev -- --watch", "watch-sass": "scripts/watch_sass.sh", "test": "npm run test-jest && npm run test-karma", "test-jest": "jest", "test-karma": "npm run test-karma-vanilla && npm run test-karma-require && echo 'WARNING: Skipped broken webpack tests. For details, see: https://github.com/openedx/edx-platform/issues/35956'", "test-karma-vanilla": "npm run test-cms-vanilla && npm run test-xmodule-vanilla && npm run test-common-vanilla", "test-karma-require": "npm run test-cms-require && npm run test-common-require", "test-karma-webpack": "npm run test-cms-webpack && npm run test-lms-webpack && npm run test-xmodule-webpack", "test-karma-conf": "${NODE_WRAPPER:-xvfb-run --auto-servernum} node --max_old_space_size=4096 node_modules/.bin/karma start --single-run=true --capture-timeout=60000 --browsers=FirefoxNoUpdates", "test-cms": "npm run test-cms-vanilla && npm run test-cms-require && npm run test-cms-webpack", "test-cms-vanilla": "npm run test-karma-conf -- cms/static/karma_cms.conf.js", "test-cms-require": "npm run test-karma-conf -- cms/static/karma_cms_squire.conf.js", "test-cms-webpack": "npm run test-karma-conf -- cms/static/karma_cms_webpack.conf.js", "test-lms": "npm run test-jest && npm run test-lms-webpack", "test-lms-webpack": "npm run test-karma-conf -- lms/static/karma_lms.conf.js", "test-xmodule": "npm run test-xmodule-vanilla && npm run test-xmodule-webpack", "test-xmodule-vanilla": "npm run test-karma-conf -- xmodule/js/karma_xmodule.conf.js", "test-xmodule-webpack": "npm run test-karma-conf -- xmodule/js/karma_xmodule_webpack.conf.js", "test-common": "npm run test-common-vanilla && npm run test-common-require", "test-common-vanilla": "npm run test-karma-conf -- common/static/karma_common.conf.js", "test-common-require": "npm run test-karma-conf -- common/static/karma_common_requirejs.conf.js" }, "dependencies": { "@babel/core": "7.26.0", "@babel/plugin-proposal-object-rest-spread": "^7.18.9", "@babel/plugin-transform-object-assign": "^7.18.6", "@babel/preset-env": "^7.19.0", "@edx/brand": "npm:@openedx/brand-openedx@^1.2.2", "@edx/edx-bootstrap": "1.0.4", "@edx/edx-proctoring": "^4.18.1", "@edx/frontend-component-cookie-policy-banner": "2.2.0", "@edx/paragon": "2.6.4", "@edx/studio-frontend": "^2.1.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^12.8.3", "babel-loader": "^9.1.3", "babel-plugin-transform-class-properties": "6.24.1", "babel-polyfill": "6.26.0", "backbone": "1.6.0", "backbone-associations": "0.6.2", "backbone.paginator": "2.0.8", "bootstrap": "4.0.0", "camelize": "1.0.1", "classnames": "2.5.1", "cross-env": "^10.0.0", "css-loader": "7.1.2", "datatables": "1.10.18", "datatables.net-fixedcolumns": "5.0.4", "edx-ui-toolkit": "1.8.7", "exports-loader": "0.6.4", "file-loader": "^6.2.0", "font-awesome": "4.7.0", "hls.js": "0.14.17", "imports-loader": "0.8.0", "jest-environment-jsdom": "^29.0.0", "jquery": "2.2.4", "jquery-migrate": "1.4.1", "jquery.scrollto": "2.1.3", "js-cookie": "3.0.5", "moment": "2.30.1", "moment-timezone": "0.5.47", "node-gyp": "11.1.0", "popper.js": "1.16.1", "prop-types": "15.8.1", "raw-loader": "0.5.1", "react": "16.14.0", "react-dom": "16.14.0", "react-focus-lock": "^1.19.1", "react-redux": "5.1.2", "react-router-dom": "5.3.4", "react-slick": "0.30.3", "redux": "3.7.2", "redux-thunk": "2.2.0", "requirejs": "2.3.7", "rtlcss": "4.3.0", "sass": "^1.54.8", "sass-loader": "^16.0.0", "scriptjs": "2.5.9", "style-loader": "4.0.0", "svg-inline-loader": "0.8.2", "uglify-js": "3.19.3", "underscore": "1.13.7", "underscore.string": "3.3.6", "webpack": "^5.90.3", "webpack-bundle-tracker": "3.2.0", "webpack-merge": "6.0.1", "which-country": "1.0.0" }, "devDependencies": { "@babel/preset-react": "^7.27.1", "@edx/mockprock": "1.0.2", "@edx/stylelint-config-edx": "2.3.3", "babel-jest": "29.7.0", "jasmine-core": "2.6.4", "jasmine-jquery": "2.1.1", "jest": "29.7.0", "karma": "^6.4.4", "karma-chrome-launcher": "^3.2.0", "karma-coverage": "2.2.1", "karma-firefox-launcher": "2.1.3", "karma-jasmine": "^5.1.0", "karma-jasmine-html-reporter": "0.2.2", "karma-junit-reporter": "2.0.1", "karma-requirejs": "1.1.0", "karma-selenium-webdriver-launcher": "latest", "karma-sourcemap-loader": "0.4.0", "karma-spec-reporter": "0.0.20", "karma-webpack": "^5.0.1", "plato": "1.7.0", "react-test-renderer": "16.14.0", "selenium-webdriver": "^2.44.0", "sinon": "19.0.2", "squirejs": "0.1.0", "string-replace-loader": "^3.1.0", "stylelint-formatter-pretty": "4.0.1", "underscore-template-loader": "^1.2.0", "webpack-cli": "^5.1.4" } } 如何运行起来
最新发布
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、付费专栏及课程。

余额充值