【专项学习】 —— Webpack5从入门到精通课程学习(四)
这篇主要介绍《webpack优化环境配置(上)》。(demo代码github地址)
知识点包括:
一、开发环境性能优化(HMR)
1、将webpack生产环境配置汇总工程完整复制一份,并重命名。
在终端输入npx webpack serve
启动热更新服务。
然后我们简单修改index.less内的样式,会发现只单独更新了样式模块。
2、此时在简单修改index.js和index.html文件,则不会仅仅更新js或者html模块,而是整个工程进行更新。
在webpack.config.js内代码中有注释说明。
/** * 启动devServer命令: * npx webpack serve * 开发环境的性能优化(HMR):hot module replacement热模块替换/模块热替换 作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块)极大提升构建速度. 样式文件:可以使用HMR功能:因为style-loader内部实现了~ js文件:默认不能使用HMR功能,我们可以在入口文件中引入其他js文件,实现修改其他js文件,达成HMR功能 html文件:默认不能使用HMR功能.同时会导致问题: html文件不能热更新了~,在入口entry属性中配置上html文件即可解决 */
const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: ['./src/index.js', './src/index.html'], output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ // loader的配置 { //处理less资源 test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ], }, { //处理css资源 test: /\.css$/, use: [ 'style-loader', 'css-loader' ], }, { //处理图片资源Ⅰ test: /\.(jpg|png|gif)$/, loader: 'url-loader', options: { limit: 8 * 1024, // 关闭ES6模块化 esMoudle: false }, type: 'javascript/auto' }, { //处理html中img资源 test: /\.html$/, loader: 'html-loader', options: { esModule: false, } }, { //处理其他资源 exclude: /\.(html|js|css|less|jpg|png|gif)$/, loader: 'file-loader', options: { esModule: false, }, type: 'javascript/auto' } ] }, plugins: [ // plugins的配置 new HtmlWebpackPlugin({ template: './src/index.html' }) ], devServer: { compress: true, port: 3000, open: true, // 开启hmr功能,webpack5默认开启了 // hot: true }, mode: 'development' }
3、入口文件index.js不能使用HMR功能,那么在入口文件中,引入其他的js则可以使用,不过要修改代码。
index.js:
import '../src/iconfont'; import '../src/index.less'; import print from './print'; console.log('index.js文件被加载了'); function add(x, y) { return x + y; } console.log(add(1, 8)); if (module.hot) { // 一旦 module.hot为true,说明开启了HMR功能。--> 让HMR功能代码生效 module.hot.accept('../src/print.js', function () { //方法会监听 print.js文件的变化,一旦发生变化,其他模块不会重新打包构建。 //会执行后面的回调函数 print(); }) }
4、我们新建的另一个print.js
function print() { const content = 'print.js被加载了'; console.log(content); } export default print;
此时修改print.js文件,则会发生HMR热更新模块功能。
但是,注意:入口文件index.js一修改是只能整个工程全部更新。
二、source-map
source-map:一种提供源代码到构建后(打包)代码映射技术(如果构建后(打包)代码出错了,通过映射可以追踪源代码错误)。
1、将上一小节工程文件复制,并重命名。修改webpack.config.js代码
/** * 启动devServer命令: * npx webpack serve * 开发环境的性能优化(HMR):hot module replacement热模块替换/模块热替换 作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块)极大提升构建速度. 样式文件:可以使用HMR功能:因为style-loader内部实现了~ js文件:默认不能使用HMR功能 html文件:默认不能使用HMR功能.同时会导致问题: html文件不能热更新了~,在入口entry属性中配置上html文件即可解决 */ const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: ['./src/index.js', './src/index.html'], output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ // loader的配置 { //处理less资源 test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ], }, { //处理css资源 test: /\.css$/, use: [ 'style-loader', 'css-loader' ], }, { //处理图片资源Ⅰ test: /\.(jpg|png|gif)$/, loader: 'url-loader', options: { limit: 8 * 1024, // 关闭ES6模块化 esMoudle: false }, type: 'javascript/auto' }, { //处理html中img资源 test: /\.html$/, loader: 'html-loader', options: { esModule: false, } }, { //处理其他资源 exclude: /\.(html|js|css|less|jpg|png|gif)$/, loader: 'file-loader', options: { esModule: false, }, type: 'javascript/auto' } ] }, plugins: [ // plugins的配置 new HtmlWebpackPlugin({ template: './src/index.html' }) ], devServer: { compress: true, port: 3000, open: true, // 开启hmr功能,webpack5默认开启了 // hot: true }, // source-map:一种提供源代码到构建后(打包)代码映射技术(如果构建后(打包)代码出错了, //通过映射可以追踪源代码错误)。 // 开启source-map,打包后会生成一个.js.map文件 devtool: 'source-map', // 测试不同种类的source-map // devtool: 'eval-source-map', mode: 'development' } /* 有如下几个组合source-map [inline-|hidden-|eval-] [nosources-] [cheap-[ module-]] source-map inline-source-map:把原本单独生成的built.js.map文件,整体内嵌到了built.js中尾部去了 hidden-source-map:单独生成一个built.js.map文件, eval-source-map:内嵌到built.js中,但是是以分段的形式,从头至尾,遍布于整个.js文件中 nosources-source-map:单独生成一个built.js.map文件 cheap-source-map:单独生成一个built.js.map文件 cheap-module-source-map:单独生成一个built.js.map文件。 */
2、输入npm run dev
进行打包。
3、然后输入npx webpack serve
开启热更新。效果如下
4、那么我们为了验证代码出错时是否有映射关系。把print.js中代码人为制造一个错误。
function print() { // 人为制造一个log的错误 —— 多加两个逗号 const content = 'print.js被加载了',, console.log(content) } export default print;
自动热更新后,网页报错的提示。
小结,不同的sourece-map对比:
三、oneOf
1、将webpack生产环境配置工程复制,并重命名oneOf。
oneOf功能是:使每个类型的文件,只匹配到一个适用的loader即可,不会把代码中写的所有loader挨个匹配一遍,优化了构建速度。
2、在webpack.config.js代码如下,把相关的loader放入oneOf选项中。
const { resolve } = require('path'); const minicssextractplugin = require('mini-css-extract-plugin'); // css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码 process.env.NODE_ENV = 'development' const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin'); const Htmlwebpackplugin = require('html-webpack-plugin'); const Eslintwebpackplugin = require('eslint-webpack-plugin'); module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build') }, module: { rules: [{ // oneOf是每一个文件,只匹配到一个loader即可, //不像之前,每个文件都要把下列loader全部匹配一遍 // 注意不能有两个loader处理同一个类型文件 oneOf: [ { // 检测css文件,并打包 test: /\.css$/, use: [ minicssextractplugin.loader, 'css-loader', { // 对css做兼容性处理 // 还需要在package.json中定义browserslist loader: 'postcss-loader', options: { postcssOptions: { plugins: [require('postcss-preset-env')()] } } } ] }, { // 检测less文件,并打包 test: /\.less$/, // use内代码,是从下往上的顺序执行的 use: [ minicssextractplugin.loader, 'css-loader', { // 还需要在package.json中定义browserslist loader: 'postcss-loader', options: { postcssOptions: { plugins: [require('postcss-preset-env')()] } } }, 'less-loader' ] }, // 正常来讲,一个文件只能被一个loader处理,比如一个index.js文件。 //当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序 // { // //在package.json中定义eslintConfig --> airbnb // // js语法检查,webpack4写法 // test: /\.js$/, // exclude: /node_modules/, // // 优先执行eslint-loader,对js文件进行处理 // enforce: 'pre', // loader: 'eslint-loader', // options: { // // 自动修复语法检查的报错 // fix: true // } // }, { // js兼容性处理 test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { presets: [ [ '@babel/preset-env', { useBuiltIns: 'usage', corejs: { version: 3 }, targets: { // 浏览器兼容的版本 chrome: '60', firefox: '50' } } ] ] } }, { //对图片进行打包处理 test: /\.(jpg|png|gif)$/, loader: 'url-loader', options: { limit: 8 * 1024, outputPath: 'imgs', esModule: false }, type: 'javascript/auto' }, { // 处理html中的图片文件 test: /\.html$/, loader: 'html-loader', options: { esModule: false, } }, { // 处理其他文件,如字体图标等 exclude: /\.(js|css|less|html|jpg|png|gif)$/, loader: 'file-loader', options: { outputPath: 'media', esModule: false, }, type: 'javascript/auto' } ] } ] }, plugins: [ new minicssextractplugin({ // 打包提取成单独文件 filename: 'css/built.css' }), new cssminimizerwebpackplugin( // 压缩css文件 ), new Htmlwebpackplugin({ template: './src/index.html', // 压缩html minify: { collapseWhitespace: true, removeComments: true } }), new Eslintwebpackplugin({ // 使用默认配置 fix: true }) ], // 生产环境下,js自动压缩 mode: 'production' }
注:笔记转载自疯子的梦想@博客,课程来自尚硅谷b站Webpack5实战课程