Webpack 是目前前端开发中最常用的打包工具之一。在开发过程中,随着项目规模不断扩大,打包后的文件体积也会不断增大,影响页面加载速度。为了优化打包后的文件体积,我们可以采用去重和提取公共模块的方式。
去重
在 Webpack 打包过程中,可能会出现同一个模块被多次打包的情况。这会导致打包后的文件体积增大,影响页面加载速度。为了避免这种情况的发生,我们可以采用去重的方式。
使用 optimization.splitChunks 配置项
Webpack 4 中提供了 optimization.splitChunks 配置项,可以用来去重和提取公共模块。该配置项有以下几个选项:
- chunks:表示需要提取哪些 chunk,默认为 async,表示只提取异步加载的 chunk。
- minSize:表示提取出来的公共模块的最小体积,默认为 30000。
- maxSize:表示提取出来的公共模块的最大体积,默认为 0,表示不限制。
- minChunks:表示一个模块被多少个 chunk 引用时才会被提取,默认为 1。
- maxAsyncRequests:表示异步加载的 chunk 中,最多有多少个 chunk 可以同时加载,默认为 5。
- maxInitialRequests:表示入口 chunk 中,最多有多少个 chunk 可以同时加载,默认为 3。
- automaticNameDelimiter:表示分离出来的 chunk 名称中的连接符,默认为 ~。
- name:表示分离出来的 chunk 名称,默认为 true,表示自动生成名称。
下面是一个示例:
// javascriptcn.com 代码示例 const path = require('path'); module.exports = { entry: { app: './src/app.js', vendor: ['react', 'react-dom'] }, output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') }, optimization: { splitChunks: { chunks: 'all', name: 'vendor' } } };
上面的示例中,我们将 React 和 React-DOM 作为公共模块提取出来,并将它们打包到 vendor.[chunkhash].js 中。这样,每次打包时,vendor.[chunkhash].js 中的内容都会根据文件内容生成不同的 hash 值,避免了浏览器缓存的问题。
使用 DllPlugin 和 DllReferencePlugin
另一种去重的方式是使用 DllPlugin 和 DllReferencePlugin。这两个插件可以将第三方库打包成一个单独的文件,并在后续的打包过程中引用该文件,避免了重复打包的问题。
首先,我们需要创建一个名为 vendor.dll.js 的文件,用于打包第三方库。在该文件中,我们需要指定需要打包的库和输出文件的路径。
// javascriptcn.com 代码示例 const path = require('path'); const webpack = require('webpack'); module.exports = { entry: { vendor: ['react', 'react-dom'] }, output: { filename: '[name].dll.js', path: path.resolve(__dirname, 'dist'), library: '[name]_[hash]' }, plugins: [ new webpack.DllPlugin({ name: '[name]_[hash]', path: path.join(__dirname, 'dist', '[name].manifest.json') }) ] };
上面的示例中,我们将 React 和 React-DOM 打包到 vendor.dll.js 文件中,并生成一个名为 vendor.manifest.json 的清单文件。
接下来,在我们的应用程序中,我们需要使用 DllReferencePlugin 来引用 vendor.dll.js 和 vendor.manifest.json。
// javascriptcn.com 代码示例 const path = require('path'); const webpack = require('webpack'); module.exports = { entry: { app: './src/app.js' }, output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') }, plugins: [ new webpack.DllReferencePlugin({ manifest: require('./dist/vendor.manifest.json') }) ] };
上面的示例中,我们使用 DllReferencePlugin 引用了 vendor.dll.js 和 vendor.manifest.json。这样,在打包应用程序时,Webpack 会自动忽略 vendor.dll.js 中已经打包过的模块,从而避免了重复打包的问题。
提取公共模块
除了去重,我们还可以通过提取公共模块的方式来优化打包后的文件体积。提取公共模块可以将多个入口文件中相同的模块提取出来,打包成一个单独的文件,从而减小打包后的文件体积。
使用 optimization.splitChunks 配置项
我们可以使用 optimization.splitChunks 配置项来提取公共模块。该配置项的 chunks 和 minChunks 选项可以用来指定需要提取的模块和最小引用次数。
// javascriptcn.com 代码示例 const path = require('path'); module.exports = { entry: { app1: './src/app1.js', app2: './src/app2.js' }, output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') }, optimization: { splitChunks: { chunks: 'all', minChunks: 2 } } };
上面的示例中,我们将入口文件 app1.js 和 app2.js 中引用次数大于等于 2 的模块提取出来,并打包到一个单独的文件中。
使用 CommonsChunkPlugin 插件
Webpack 4 中已经废弃了 CommonsChunkPlugin 插件,但是在 Webpack 3 中仍然可以使用该插件来提取公共模块。
// javascriptcn.com 代码示例 const path = require('path'); const webpack = require('webpack'); module.exports = { entry: { app1: './src/app1.js', app2: './src/app2.js' }, output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'common' }) ] };
上面的示例中,我们将 app1.js 和 app2.js 中相同的模块提取出来,并打包到一个名为 common.[chunkhash].js 的文件中。
总结
通过去重和提取公共模块的方式,我们可以优化 Webpack 打包后的文件体积,提高页面加载速度。在实际开发中,我们可以根据项目的具体情况选择合适的优化方式,从而达到更好的优化效果。
以上就是本文介绍的 Webpack 打包优化:去重与提取公共模块。希望本文能够对读者有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/657eee8ed2f5e1655d9cfbc7