深入webpack4配置笔记(必备/可选配置 单页/多页配置)

必备配置

  1. 自动生成html文件,使用html-webpack-plugin 插件

  2. 重新打包时前删除dist目录,然后再执行打包,使用clean-webpack-plugin插件

  3. entryoutput配置,占位符[name]publicPath(比如配置js文件等资源的cdn地址,使得打包后的html中引入的js地址为cdn地址)

  4. 三种提升开发效率的即时打包:watch(使用file协议)、devServer开启本地服务器(使用http协议,需安装webpack-dev-server,本地代码修改后实时打包自动更新刷新页面)、自己用node写服务器(使用http协议,不足是本地代码修改后虽然实时打包但页面仍需手动刷新才能看见最新显示)。除此还可以安装http-server包,然后打包项目到dist目录后,再运行scripts命令"start": "htt-server dist",这样的操作和将项目打包后dist目录丢到服务器上访问类似。

  5. 打包静态文件:

    • 图片 png/jpg/gif等静态图片资源 使用 file-loader 或者 url-loader,推荐使用 url-loader,因为后者可通过 options 进行额外配置
    • css/scss 按顺序使用postcss-loader(配合autoprefixer插件) / sass-loader(依赖node-sass) / css-loader / style-loader 来进行 css3代码前缀自动添加、scss代码转成css代码、插入html页面head的style中
    • css模块化打包 开启css文件模块化打包,可以在某个js文件中 通过 import xxx from "./yyy.scss" 文件来进行模块化打包scss文件,在js中可以通过 xxx.classSelecter来引用某个具体的样式选择器进行样式class的添加
    • 字体文件打包 就是使用file-loader把eot/svg等从src目录移到dist目录
  6. 将ES6/7语法转换为ES5语法,安装babel-loader@babel/core(babel V7开始为@babel)、配置文件.babelrc中配置presets,它使用@babel/preset-env来将ES6/7语法转译成兼容低版本浏览器的兼容代码。如果要编译Promise、部分原型方法可以使用@babel/polyfill,然后通过入口js文件中import @babel/polyfill即可(这种方法会把所有转译ES6/7高级API的兼容代码一口气全打包出来),或者可以在.babelrcpresets@babel/preset-env配置属性对象里添加useBuiltIns: "usage"(这种办法就是按需打包出兼容代码,注意在我当前使用的babelV7版本中此时还需配置corejs版本)。使用@babel/polyfill有个问题,它的兼容代码会污染全局变量,在写普通业务代码项目中没问题,但如果babel用于写组件类库,就需要换个方法来避免污染全局环境:可以使用@babel/plugin-transform-runtime(安装于devDepend)和@babel/runtime-corejs2(安装于depend),然后在.babelrc中配置plugins,它的原理是通过闭包的形式挂载兼容代码,从而不会污染全局变量。babelJavaScript的编译器。

  7. 代码分割(CodeSplitting)/异步引入模块。通过同步引入的模块进行代码分割时需配置optimization.splitChunks对象配置(配置参数看这里,也可以看webpack.common.js中这部分的配置注释);通过异步引入的模块(仅import("xxx module"))则只需在添加@babel/plugin-syntax-dynamic-import这个官方插件并在.babelrc文件中的plugins里配置引入该插件就行,这里要注意异步引入import("xxx module")是一个Promise,可以通过调用then方法执行后续逻辑。

  8. css文件的代码分割:安装插件mini-css-extract-plugin,在生产环境对应的配置文件中const MiniCssExtractPlugin = require("mini-css-extract-plugin");引入该插件后,在plugins中启用该插件,同时设置样式文件loader的最后一步由style-loader替换为MiniCssExtractPlugin.loader。这里有个地方要注意,由于该插件尚未支持HMR功能,所以webpack4建议在生产环境中使用该插件,开发环境开启HMR后就无需配置css代码分割了。

  9. css代码的压缩:安装插件optimize-css-assets-webpack-plugin,引入该插件并配置,可以查看官方文档DOCUMENTATION -> PLUGINS -> MiniCssExtractPlugin -> Minimizing For Production Analysis

  10. 设置webpack打包的环境变量,可以安装cross-env模块并在scripts配置项中设置cross-env NODE_ENV=production,如此可在webpack配置文件中获取当前打包环境变量值。

  11. 开启Hot Module Replacement 热模块更新(HMR), 需配置webpack.config.js文件中两个地方:devServer中配置hothotOnlyHotModuleReplacementPlugin插件

  12. devtool配置sourceMap,它是一种映射关系,用于指出源代码中具体出错位置,弄明白source-mapinline-source-mapcheap-source-map等关系,并给出开发环境与生产环境的devtool的sourceMap配置最佳实践(开发环境为cheap-module-eval-source-map,生产环境为cheap-module-source-map)

  13. developmentproduction模式打包区别,安装第三方模块webpack-merge进行配置文件合并。

  14. 懒加载:通过import异步加载模块就是属于一种懒加载,但是到底什么时候加载这个模块,则取决于什么时候真正执行import语句。借助这种方法,可以更快加载页面。异步加载模块采用ES Module的动态加载ES模块的方法:import()

  15. PreLoading优化:webpack推荐前端js更多使用异步加载来提高页面首次加载速度,这从它的optimization.splitChunks.chunks值默认是async就可以看出,即默认配置只分割异步模块代码,这样打包出来的页面首次加载js只会加载同步代码,异步模块代码会等到满足异步触发条件时再另外加载对应的异步js文件,这样能明显提高页面首次加载的速度和所加载js代码的使用率。分割同步模块代码只能是优化缓存提高页面二次加载时的速度,对页面首次加载速度提升并无帮助。所以优化页面首次、多次加载速度需要分割打包异步和同步模块,分别对应优化页面js代码使用率和缓存。查看js代码使用率可以打开chrome浏览器的控制台 -> Coverage,快捷键是Ctrl + Shift + P。写高性能页面时,重点考虑的应是页面代码的使用率,而不是缓存。

  16. PreFetching优化:当通过Preloading优化的页面加载完毕后,此时带宽释放,可以利用这段空闲的带宽来预先加载异步模块文件,如此当用户交互触发异步加载条件时就会有与一次性加载所有模块一样的响应体验,因为此时浏览器中已经有异步模块文件的缓存。比较典型的案例就是页面加载后点击登录展示登录模态框,当页面首次加载时不会加载登录模态框的模块代码,页面加载完毕后利用带宽释放空档提前加载登录模态框的模块代码文件,如此当用户点击登录按钮时,可以直接调用相应的登录模态模块代码。实现方法是使用到魔法注释 /* webpackPrefetch: true */,使用详情可以访问webpack官方文档的DOCUMENTATION -> GUIDES -> Code Splitting -> Prefetching/Preloading modules。所以如果要提高页面加载性能,可以使用ES Modules异步模块加载来进行懒加载,同时添加Prefetching优化,利用页面主逻辑加载完毕后带宽释放空档提前加载异步模块文件,来达到明显提升页面加载速度的目的。

  17. webpack帮浏览器做合理缓存:在output.filenameoutput.chunkFilename值中添加占位符contenthash,它的意思是当文件内容没变时打包生成文件的hash值不变,如果文件内容变了那么打包生成文件的hash值就会改变。

  18. Shimming预置依赖,指的就是预先配置第三方库垫片,比如jQuery,可以在配置文件plugins数组中添加new webpack.ProvidePlugin({ $: "jQuery" })插件,这样当项目js中用到关键字$时程序就能理解为jQuery对象。

  19. Tree shaking 作用:在模块引入打包中,引入什么就打包什么,未引入的模块代码就会被忽略掉;或者当一个模块文件中会export多个模块,但只被引入某些个模块,另有部分模块可能未被引用时,Tree Shaking 也会把这个模块文件中的未被引用的模块给摇掉,也就是不打包它们,而只打包该模块文件中被引用的那些模块。注意 Tree Shaking只支持ES Module这种模块引入方法,对其他模块引入方式(如CommonJS/AMD等)不起作用。在开发环境中默认不开启,如需开启需配置optimization中的usedExports: true,同时在package.json中配置"sideEffects": false,,意思是Tree Shaking 对所有模块都进行treeShaking操作,这里也可以将值改为数组,数组项即被用来配置需要忽略treeShaking操作的模块,例如在js页面中引入import "@babel/polyfill"时就可以配置"sideEffects": [ "@babel/polyfill" ],。但现在一般不用这样配置,因为已经在.babelrc中配置了"useBuiltIns": "usage"这样表示默认所有js都已添加import "@babel/polyfill"。所以既然页面js中无需做这样的引入,就不需要添加treeShaking默认忽略列表项。当然如果引入的模块是scss或css之类的样式文件模块,则为防止部分样式代码未被引用导致被treeShaking误忽略打包造成不可控错误,可以进行类似sideEffects: [*.css]的配置。(这样在开发环境中就算是配置好Tree Shaking,但是打包后其实仍会将未引入的模块打包进dist里,只是相比未配置,会多加一句注释表明使用的模块是哪些,其原因是为了开发环境下的调试方便,避免因删除未引入模块代码导致的行数错乱从而误导错误提示行数。)在生产环境中Tree Shaking 默认就已经开启了,所以无需配置optimization中的usedExports: true,但还是需要在package.json中配置sideEffects的忽略列表,这里要注意。

可选配置

  1. 打包分析,可以查看打包模块之间的关系,官方提供的可以访问webpack-analyse这个地址,它提供用于生成打包分析的JSON文件的命令,还可在该页面获取可视化分析该JSON文件的入口地址。可将--profile --json > stats.json这个命令片段添加至package.json文件的script脚本命令中,例如"dev-build": "webpack --profile --json > stats.json --config ./build/webpack.dev.js",配置好后运行npm run dev-build命令完成后会在项目根目录生成stats.json文件,这个json文件中会有打包过程的各项信息。可以将这个json文件上传至http://webpack.github.com/analyse查看打包过程信息的可视化展示(注意这个地址说是需要科学上网才能访问,不过我即使科学上网也不能访问?)。如果上面的官方分析工具始终无法访问,也可以使用其他方法,可以访问webpack官方文档的DOCUMENTATION -> GUIDES -> Code Splitting -> Bundle Analysis查看其他分析工具,推荐使用Webpack Bundle Analyzer

  2. webpack构建项目的js模块文件中的this默认指向模块本身,而不是指向window对象,如果要想将this指向window对象,需要通过imports-loader来解决。

  3. 用webpack打包库代码,方法与打包业务代码差不多,只是在output配置中添加libraryTarget: "umd"library: library,前者作用是为打包后的库添加支持ES ModuleAMDCMD模块引入方式,后者作用是当库代码直接被页面用

你可能感兴趣的:(前端小二)