前言
我的webpack打包好像有点慢,而且领导也发现,在一个历史悠久的项目中,由于功能不断减少,代码变得庞大臃肿,项目依赖复杂,导致时间启动并打包项目变得越来越长。 来得越来越长。
webpack 构建这个项目能有多慢?大约在我构建项目的时候,我可以“吃早餐、泡茶、上厕所”。 当我做完这件事后,就快完成了。
虽然最初考虑使用微后端来拆分项目,但项目负责人出于各种考虑(担心推卸责任)拒绝了这些计划。 我们只好在Webpack创建上下功夫,以提高项目创建的效率。接下来我们主要介绍一些提高Webpack创建效率的方法,这也是笔试中经常会问到的一些内容。
尖端
在做这种优化工作时,建议先了解一下webpack创建的整个流程。 在哪些环节我们可以采取相应的优化措施? 如果你对这个执行过程不感兴趣,可以直接跳过,直接看前面的优化方法。
webpack执行流程
下面是我所了解的一些webpack的运行过程(笔试时经常被问到)。 如果有错误,请帮忙强调一下,Webpack的运行过程是一个串行过程。 从开始到结束,会依次执行以下流程:
初始化参数:从配置文件和shell语句中读取并合并参数,得到最终参数; 开始编译:用上一步获得的参数初始化编译器对象,加载所有配置的插件,并执行该对象的运行模式开始编译; 确定条目:根据配置中的条目查找所有条目文件; 编译模块:从入口文件开始,调用所有配置的Loader对模块进行翻译webpack分包优化,然后找出该模块所依赖的模块,然后递归这一步,直到所有入口依赖的所有文件都被这一步处理完毕; 完成模块编译:使用Loader翻译完第4步中的所有模块后,得到每个模块最终翻译的内容以及它们之间的依赖关系; 输出资源:根据条目和模块之间的依赖关系组装成包含多个模块的chunk,然后将每个chunk转换成6个独立的文件并添加到输出列表中。 这一步是改变输出内容的最后机会; 输出完成:确定输出内容后,根据配置确定输出路径和文件名,并将文件内容写入文件系统。 在上述过程中,Webpack会在特定的时间点广播特定的风暴。 当插件窃听时,它会感兴趣。 暴风雨后会执行具体逻辑,插件可以调用Webpack提供的API来改变Webpack的运行结果; webpack优化方法1.使用缓存
可以在webpack配置文件中使用cache-loader或者hard-source-webpack-plugin来缓存编译依赖。
使用缓存加载器:
module.exports = {
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: ['cache-loader', 'babel-loader'],
},
],
},
};
使用硬源 webpack-plugin:
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
module.exports = {
plugins: [
new HardSourceWebpackPlugin(),
],
};
2.减少模块热重载
模块热重载的行为可以在 webpack 配置文件中调整。
module.exports = {
devServer: {
hot: true,
hotOnly: true,
},
};
在devServer上启用hot和hotOnly,当hot热更新失败时刷新页面。 hotOnly 热更新失败时只查找模块webpack分包优化,不刷新页面。
在大多数项目中,node_modules变化的频率极低,因此在使用watch功能时,我们可以配置ignore来忽略node_modules,减少性能压力。
"watchOptions": {
"ignored": /node_modules/
}
3.使用TreeShaking和DeadCodeElimination
您可以使用 mode:'production' 和 UglifyJSPlugin 来优化代码。
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
mode: 'production',
optimization: {
minimizer: [
new UglifyJSPlugin(),
],
},
};
4.使用CodeSplitting和动态加载模块
您可以使用 import() 异步加载和 SplitChunksPlugin 进行代码拆分。
module.exports = {
optimization: {
splitChunks: {
chunks: 'async',
},
},
};
使用 chunks:'async' 实现动态加载,只加载需要的模块。
import(/* webpackChunkName: "my-chunk-name" */ './my-module')
.then(module => {
// 使用模块
})
.catch(error => {
// 处理错误
});
还可以使用React.lazy+Suspense来延迟加载React组件。
import React, { lazy, Suspense } from 'react';
const MyComponent = lazy(() => import('./MyComponent'));
function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
</div>
);
}
5. 优化加载器
Loader可以通过配置选项来优化。
module.exports = {
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
},
},
],
},
],
},
};
使用 HappyPack 可以通过多个进程并行处理加载程序。
const HappyPack = require('happypack');
const os = require('os');
module.exports = {
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: ['happypack/loader'],
},
],
},
plugins: [
new HappyPack({
loaders: ['babel-loader'],
threads: os.cpus().length,
}),
],
};
6.利用外部资源
使用外部来防止打包不必要的外部依赖项。
module.exports = {
externals: {
react: 'React',
'react-dom': 'ReactDOM',
},
};
7.指定建立环境
使用 webpack --modedevelopment 或 webpack --modeproduct 指定构建环境。
也可以在webpack配置文件的模式中指定。
module.exports = {
mode: 'development',
};
8.优化捆绑文件大小
使用 mini-css-extract-plugin 来分离 CSS 文件。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
module: {
rules: [
{
test: /.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
};
使用 terser-webpack-plugin 来压缩文件。
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true,
}),
],
},
};
9.DLL模式
Webpack 中的 DLL(DynamicLinkLibrary)优化是一种基于缓存和分离应用程序代码库的技术,可以显着提高构建性能和开发体验。 具体来说,DLL技术可以将各个模块打包成一个DLL文件,该DLL文件可以在多个构建中重复使用,从而减少打包时间和文件大小。
具体实现如下:
首先在项目中新建webpack.dll.js配置文件,用于打包DLL包。
在webpack.dll.js中设置entry,并使用第三方库和其他需要提取的代码作为entry中的值。 如下:
entry: {
vendors: ['react', 'react-dom', 'jquery']
},
接下来,将webpack.DllPlugin添加到plugins中,并配置生成的DLL文件的名称、路径和映射关系。 代码如下:
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: {
vendors: ['react', 'react-dom', 'jquery']
},
output: {
filename: '[name].dll.js',
path: path.resolve(__dirname, './dll'),
library: '[name]'
},
plugins: [
new webpack.DllPlugin({
name: '[name]',
path: path.resolve(__dirname, './dll/[name].manifest.json')
})
]
}
运行webpack.dll.js配置文件生成DLL文件和manifest文件。
在正常的项目创建中,通过webpack.DllReferencePlugin引入DLL文件以加快创建时间。 如下:
const webpack = require('webpack');
const path = require('path');
const dllPath = path.resolve(__dirname, './dll');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './build')
},
plugins: [
new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(`${dllPath}/vendors.manifest.json`)
})
]
}
最后运行npmrunbuild来打包项目
使用DLL技术可以显着减少构建时间和文件大小,特别是在重复构建时,可以防止第三方库和其他代码的重复打包。因此,在复杂的项目中,DLL技术是一种非常实用的优化方法。
10.gzip
开启Gzip压缩可以大大减小文件大小,提高网络传输速率,促进网站加载速度。 Webpack中开启Gzip压缩的方法如下:
安装compression-webpack-plugin插件:
npm install compression-webpack-plugin --save-dev
在Webpack配置文件中引入插件,代码如下:
const CompressionWebpackPlugin = require('compression-webpack-plugin');
module.exports = {
// ...
plugins: [
new CompressionWebpackPlugin({
filename: '[path][base].gz',
algorithm: 'gzip',
test: /.(js|css|html)$/,
threshold: 10240,
minRatio: 0.8
})
]
};
上述插件的配置项含义如下:
在 Webpack 配置文件中启用 Gzip 压缩。 代码如下:
module.exports = {
// ...
devServer: {
compress: true,
},
};
将 devServer 配置项的 compress 属性设置为 true 以启用 Gzip 压缩。
总结
Webpack的优化配置在不同版本中可能会有所不同。 上面提到的优化方法的目的并不是让你直接使用它们,而是让你知道有哪些可行的优化方法。 实际使用时,可以根据使用的Webpack版本进行相应的配置优化。
优化的时候,最重要的是明确优化的方向。 一旦确定了可以优化的方向,具体的实现方法就显而易见了。 虽然现在不知道如何实现,但也可以通过官网、谷歌、百度等渠道找到答案。
探索新工具和技术:您可以通过探索新工具和技术来提高自己的效率,但与您的团队分享这些知识以帮助其他人提高效率。
提供有价值的反馈:当你发现有问题或需要改进的地方时,提供有价值的反馈并提出提高效率的建议可以让你在团队中更具影响力
本文参加“金石计划”