[前端进阶课] 构建自己的 webpack 知识体系 (2)

apply 方法中接收一个 compiler 参数,也就是 webpack实例。由于该参数的存在 plugin 可以很好的运用 webpack 的生命周期钩子,在不同的时间节点做一些操作。

Webpack 优化概况

Webpack 加快打包速度的方法

使用 include 或 exclude 加快文件查找速度

使用 HappyPack 开启多进程 Loader 转换

使用 ParallelUglifyPlugin 开启多进程 JS 压缩

使用 DllPlugin + DllReferencePlugin 分离打包

将 库 和 项目代码 分离打包

需要 dll 映射文件

配置缓存(插件自带 loader,不支持的可以用 cache-loader)

Webpack 加快代码运行速度方法

代码压缩

抽离公共模块

懒加载模块

将小图片转成 base64 以减少请求

预取(prefetch) || 预加载(preload)

精灵图

webpack-bundle-analyzer 代码分析

Webpack 优化细节 webpack 4.6.0+增加了对预取和预加载的支持。

动态导入

import(/* webpackChunkName: "lodash" */ 'lodash') // 注释中的使用webpackChunkName。 // 这将导致我们单独的包被命名,lodash.bundle.js // 而不是just [id].bundle.js。

预取(prefetch):将来可能需要一些导航资源

只要父chunk加载完成,webpack就会添加 prefetch

import(/* webpackPrefetch: true */ 'LoginModal'); // 将<link href="http://www.likecs.com/login-modal-chunk.js">其附加在页面的开头

预加载(preload):当前导航期间可能需要资源

preload chunk 会在父 chunk 加载时,以并行方式开始加载

不正确地使用 webpackPreload 会有损性能,

import(/* webpackPreload: true */ 'ChartingLibrary'); // 在加载父 chunk 的同时 // 还会通过 <link> 请求 charting-library-chunk DllPlugin + DllReferencePlugin

为了极大减少构建时间,进行分离打包。

DllReferencePlugin 和 DLL插件DllPlugin 都是在_另外_的 webpack 设置中使用的。

DllPlugin这个插件是在一个额外的独立的 webpack 设置中创建一个只有 dll 的 bundle(dll-only-bundle)。 这个插件会生成一个名为 manifest.json 的文件,这个文件是用来让 DLLReferencePlugin 映射到相关的依赖上去的。

webpack.vendor.config.js

new webpack.DllPlugin({ context: __dirname, name: "[name]_[hash]", path: path.join(__dirname, "manifest.json"), })

webpack.app.config.js

new webpack.DllReferencePlugin({ context: __dirname, manifest: require("./manifest.json"), name: "./my-dll.js", scope: "xyz", sourceType: "commonjs2" }) CommonsChunkPlugin

通过将公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存到缓存中供后续使用。这个带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。

如果把公共文件提取出一个文件,那么当用户访问了一个网页,加载了这个公共文件,再访问其他依赖公共文件的网页时,就直接使用文件在浏览器的缓存,这样公共文件就只用被传输一次。

entry: { vendor: ["jquery", "other-lib"], // 明确第三方库 app: "./entry" }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: "vendor", // filename: "http://www.likecs.com/vendor.js" // (给 chunk 一个不同的名字) minChunks: Infinity, // (随着 entry chunk 越来越多, // 这个配置保证没其它的模块会打包进 vendor chunk) }) ] // 打包后的文件 <script src="http://www.likecs.com/vendor.js" charset="utf-8"></script> <script src="http://www.likecs.com/app.js" charset="utf-8"></script> UglifyJSPlugin

基本上脚手架都包含了该插件,该插件会分析JS代码语法树,理解代码的含义,从而做到去掉无效代码、去掉日志输入代码、缩短变量名等优化。

const UglifyJSPlugin = require('webpack/lib/optimize/UglifyJsPlugin'); //... plugins: [ new UglifyJSPlugin({ compress: { warnings: false, //删除无用代码时不输出警告 drop_console: true, //删除所有console语句,可以兼容IE collapse_vars: true, //内嵌已定义但只使用一次的变量 reduce_vars: true, //提取使用多次但没定义的静态值到变量 }, output: { beautify: false, //最紧凑的输出,不保留空格和制表符 comments: false, //删除所有注释 } }) ] ExtractTextPlugin + PurifyCSSPlugin

ExtractTextPlugin 从 bundle 中提取文本(CSS)到单独的文件,PurifyCSSPlugin纯化CSS(其实用处没多大)

module.exports = { module: { rules: [ { test: /\.css$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: [ { loader: 'css-loader', options: { localIdentName: 'purify_[hash:base64:5]', modules: true } } ] }) } ] }, plugins: [ ..., new PurifyCSSPlugin({ purifyOptions: { whitelist: ['*purify*'] } }) ] }; DefinePlugin

DefinePlugin能够自动检测环境变化,效率高效。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygsyy.html