Webpack学习笔记九 webpack优化总结
webpack 优化笔记
webpack4 自带的优化包括 swingtree(摇摆树)和作用域提升
-
swingtree
比如入口文件 index.js引入通用方法 util, 里面有 10个方法, 通过 import只用到了两个。
那么剩余的 8个, 会在打包的时候摇摆(删除)掉。util.js
function a() {} function b() {} function c() {} function d() {} export default { a, b, c, d }
index.js
import utils from './util' utils.a() utils.b()
webpack在构建的时候, 会把 c、d没用到的函数摇摆掉。
webpack 配置的优化
noparse
type: regexp|[regexp]|function
防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中不应该含有 import、require等调用。
忽略大型的 library 可以提高构建性能。
比如你引入一个 jquery库, 只想用 jquery的功能,不需要jquery通过import或require引入的其它库。提升构建性能。
module.exports = { module: { // noparse: /jquery|lodash/, // webpack.3.0.0支持函数 nopaese: content => /jquery|lodash/.test(content) } }
exclude|include
exclude: 表示哪些目录中的文件需要进行 loader转换
include: 表示哪些目录中的文件不需要进行 loader转换
比如使用 loader处理scss的时候, 我可以忽略的 node_modules中的, 只转换 src目录下的 scss文件。
module.exports = { module: { rules: [ { test: /\.scss$/, exclude: /node_modules/, // node_modules中的scss文件不需要 loader转换 include: path.resolve(__dirname, 'src'), // src目录下的文件需要 loader转换 use: [ 'style-loader', 'css-loader', 'sass-loader' ] } ] } }
设置好exclude和include可以优化打包时间。
ignoreplugin
ignoreplugin 是 webpack自带的一个插件。 创建实例时可以传递两个参数
const webpack = require('webpack') module.exports = { plugins: [ new webpack.ignoreplugin(requestregexp, contextregexp) ] }
requestregexp
: 匹配资源请求路径的正则表达式contentregexp
: (可选的) 匹配资源上下文(目录)的正则表达式
根据 webpack官网给出的一个例子:
假如, 现在我项目中需要用到一个处理时间的库, 我选中了 时间库。
我通过 npm 安装 这个时间库, 它有一个语言包也一同下载到了 node_modules
目录下的moment/locale
文件夹中。 而这个时间库内部直接通过 require()引入了本地的这个时间库,而且超级大。100多个国家的语言,而我的项目中只需要zh-cn语言包就可以了。怎么办?
可以使用 ignoreplugin这个插件,如下配置new webpack.ignoreplugin(/^\.\/locale$/, /moment$/)
第一个参数是构建的时候, 忽略通过 ./locale
引入的文件, 第二个参数是:引入的这个文件是在哪个目录下引入的。 而 ./locale
是再 moment
目录下的文件。
你可以通过手动按需引入你需要的语言包。 比如:
入口文件:
import zhcn from 'moment/locale/zh-cn.js'
dllplugin_拆分bundles
splitchunks拆分块插件
注意:
被splitchunks的代码必须使用才可以,如果一个辅助函数,你只导入不调用不计入到minchunks
。
webpack4.x中使用 splitchunks取代了 commonschunkplugin插件。
通俗一点讲就是 splitchunks 拆分代码块,提取公用的代码。防止重复打包。
提取被重复引入的文件,单独生成一个或多个文件,这样避免在多入口重复打包文件。
问题: splitchunks 可以和 dllplugins 并存吗?
将多入口共用的代码提取为一个块。需要mode设为production
webpack配置
module.exports = { mode: 'production', entry: { index: './src/index.js', main: './src/main.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, // 配置splitchunks // webpack 自带优化项 optimization: { splitchunks: { // 抽离 checkgroups: { vendors: { maxsize: 0, chunks: 'all', minchunks: 2, automaticnamedelimiter: '_', } } } } }
运行 npx webpack, 除了生成 index.js
、main.js
,还会生成一份共用的代码块vendors_index_main.js
文件。
配置项:
cachegroups: 自定义配置,主要使用它来决定生成的文件。
cachegroups.test: 限制范围,主要是正则,匹配文件夹或文件。
name: 拆分块的名称,默认将根据块和缓存组键自动生成名称,上面是根据 vendors和入口文件的名称组和的。
priority: 优先级。
minsize: 要生成块的最小大小字节。 默认为 30000。可以设置为0。
minchunks: 指的是被不同的entry 引入的次数。如果为1时,适合分离第三方库node_modules。
automaticnamedelimiter: 拆分块名称的链接符,这里时_
,所以生成的块名称为 vendors_index_main.js
。
chunks: 这表示将选择哪些块进行优化。共有三个值 all
、initial
、async
。
-
initial
: 对于异步导入的文件不处理
-
async
: 只对异步导入的文件处理
-
all
: 全部chunk, 只要导入的文件都做处理
splitchunks 可以和 dllplugins 可以并存, 但是需要在生产环境中。 开发环境的话,通过dllplugin提前打包的外部库。
会被引用到入口文件中。