babel优化 useBuiltIns: 'usage', module: false,走runtime包 只打包使用的文件而且才有esm规范
修改 babel.config.js 配置 , 详见 我掌握的Babel配置(带视频)
module.exports = {
presets: [
[
"@babel/preset-env",
{
modules: false,
useBuiltIns: "usage",
corejs: 2
},
],
],
plugins: ["@babel/plugin-transform-runtime"],
};
webpack优化:打包缓存,多进程,oneOf,代码压缩
-
缓存两部分 eslint 和 babel, 因为js经常进行eslint检查和babel编译,所以要缓存结果
-
因为rules匹配是匹配到一个后,会继续往下匹配,oneOf作用就是只做唯一匹配就退出
-
多进程是利用电脑多核加快打包,如果代码简单就没必要,会有开启进额外开销600ms,多进程优化babel,eslint,terser包(压缩js和html)
-
压缩css使用css-minimizer-webpack-plugin
-
检查tree-shaking,optimization下默认sideEffects:true,usedExports:true,生产环境默认都是true
-
图片压缩 image-minimizer-webpack-plugin (exe文件可能下载不下来,很烦人,可跳过,用下面webp)
以及无损压缩
npm install image-minimizer-webpack-plugin imagemin --save-dev
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev
-
图片转webp
-
拆包 optimazation 中 splitChunks 详见 webpack的摇树、拆包、热更新、按需加载等难点
-
预加载,preload和prefetch,都是先加载不执行,当前页面要用的用preload,下一个页面要用的用prefetch,插件 @vue/preload-webpack-plugin,webpack5内置
-
runtimeChunk 配置,把模块依赖关系存起来,某个文件修改后只改某个文件的hash
webpackPrefetch: true
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
const ESLintPlugin = require('eslint-webpack-plugin')
const TerserPlugin = require("terser-webpack-plugin")
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin")
const threadLoader = require('thread-loader')
const os = require('os') // 核心包,直接调用
const threads = os.cups().length // cpu核数
{
module: {
rules:[
{
oneOf:[
{
test: /\.css/,
use: ['style-loader','css-loader']
},
{
test: /\.js$/,
exclude: /node_modules/,
use:[
{
loader: 'thread-loader', // 开启多进程和进程数量
options:{
workers: threads
}
},{
loader: 'babel-loader',
options: {
cacheDirectory: true, // 开启babel缓存,会在node_modules下生产.cache文件夹
cacheCompression: false // 关闭缓存文件压缩
}
}]
}
]
}
]
},
plugins:[
new ESLintPlugin({
context: path.resolve(__dirname,'./src'),
exclude: 'node_modules',
cache: true, // 开启缓存
cacheLocation: path.resolve(__dirname,'./node_modules/.cache/eslintcache'),
threads // 开启多进程和进程数量
}),
],
optimization:{
minimize: true,
minimizer: [
new CssMinimizerPlugin(), // 压缩css
new TerserPlugin({
parallel: threads // 开启多进程和进程数量
}),
new ImageMinimizerPlugin({ // 图片无损压缩
minimizerOptions: {
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
[
"svgo",
{
plugins: extendDefaultPlugins([
{
name: "removeViewBox",
active: false,
},
{
name: "addAttributesToSVGElement",
params: {
attributes: [{ xmlns: "http://www.w3.org/2000/svg" }],
},
},
]),
},
],
],
},
}),
]
}
}
三方包的按需加载
有了tree-shaking,为什么还要做按需加载呢?
-
引入的样式文件通常只有一个是所有样式的合并,按需加载减少样式文件大小
-
三方库可能没有做esm导出统一入口,具体要看包的package.json的module字段是否有,否则就是commonjs导出的
-
具体像我们用到的组件库,elment,antd
-
用到的工具库 loadsh
-
比如 moment.js 较大,可以换成 dayjs