1375 字
7 分钟
webpack记录

前置包#

webpack-cli#

https://github.com/webpack/webpack-cli/issues

webpack-dev-server#

将 webpack 与提供实时重新加载的开发服务器一起使用。这应该仅用于开发。它在底层使用 webpack-dev-middleware,它提供对 webpack 资产的快速内存访问。

source map 配置详情#

img

优化手段#

output#

浏览器缓存,就是进入某个网站后,加载的静态资源被浏览器缓存,再次进入该网站后,将直接拉取缓存资源,加快加载速度。

webpack 支持根据资源内容,创建 hash id,当资源内容发生变化时,将会创建新的 hash id。

配置 JS bundle hash,webpack.js 配置方式如下:

module.exports = {
// 输出
output: {
// 仅在生产环境添加 hash
filename: ctx.isEnvProduction ? '[name].[contenthash].bundle.js' : '[name].bundle.js',
},
}

tree shaking#

  • js的shaking看这个 原理

loader优化#

  1. 使用babel-loader可以开启缓存,在第2次编译时,直接使用缓存,不用重新编译,缓存一般只适用于开发环境
  2. 使用includeexclude适当缩小loader的适用范围,让其更快找到要解析的文件,开发和生产环境皆适用
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/i,
use: ['babel-loader?cacheDirectory'],
exclude: /node_modules/,
include: /src/,
},
]
}

压缩 css 文件#

使用css-minimizer-webpack-plugin

const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
new CssMinimizerPlugin({
parallel: 4,
}),
],
}
}

输出结果不携带路径信息#

默认 webpack 会在输出的 bundle 中生成路径信息,将路径信息删除可小幅提升构建速度。

module.exports = {
output: {
pathinfo: false,
},
};
}

React的优化#

优化 resolve 配置#

1. alias#

alias 可以创建 importrequire 的别名,用来简化模块引入。

2. extensions#

根据项目中的文件类型,定义 extensions,以覆盖 webpack 默认的 extensions,加快解析速度。

由于 webpack 的解析顺序是从左到右,因此要将使用频率高的文件类型放在左侧,如下我将 tsx 放在最左侧。

webpack.common.js 配置方式如下:

module.exports = {
resolve: {
extensions: ['.tsx', '.js'], // 因为我的项目只有这两种类型的文件,如果有其他类型,需要添加进去。
}
}

3. modules#

modules 表示 webpack 解析模块时需要解析的目录。

指定目录可缩小 webpack 解析范围,加快构建速度。

webpack.common.js 配置方式如下:

module.exports = {
modules: [
'node_modules',
paths.appSrc,
]
}

如果项目不使用 symlinks(例如 npm link 或者 yarn link),可以设置 resolve.symlinks: false,减少解析工作量。

webpack.common.js 配置方式如下:

module.exports = {
resolve: {
symlinks: false,
},
}

缓存#

webpack5之前

利用 cache-loader 将结果缓存中磁盘中;利用 hard-source-webpack-plugin 将结果缓存在 node_modules/.cache 下提升二次打包速度;利用 DllReferencePlugin 将变化不频繁的第三方库提前单独打包成动态链接库,提升真正业务代码的打包速度

然而。。webpack5自带了配置项

开发环境 webpack.dev.js

cache: {
type: 'memory'
},
复制代码

生产环境 webpack.pro.js

cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename]
}
},

打包时清除上次构建产物#

打包目录下面可能会存在大量上次打包留下来的产物,时间长了就会有很多无用的代码

webpack5.20之前这里推荐使用CleanWebpackPlugin

之后就可以用output.clean为true清除

js代码压缩#

webpack5之前我们是需要terser-webpack-plugin这个包的并且需要以下配置

const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
// ...other config
optimization: {
minimize: !isDev,
minimizer: [
new TerserPlugin({
extractComments: false,
terserOptions: {
compress: {
pure_funcs: ['console.log']
}
}
}) ]
}

但是webpack5自带了代码压缩

// webpack.config.js中
module.exports = {
optimization: {
usedExports: true, //只导出被使用的模块
minimize : true // 启动压缩
}
}

当然你如果需要自定义的话也可以安装这个插件,然后自定义配置

const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
parallel: 4,
terserOptions: {
parse: {
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
comparisons: false,
inline: 2,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
},
}),
]
}
}

合并模块#

普通打包只是将一个模块最终放到一个单独的立即执行函数中,如果你有很多模块,那么就有很多立即执行函数。concatenateModules 可以要所有的模块都合并到一个函数里面去。

热更新#

  • 自动刷新 是指在修改模块内存时,浏览器会自动刷新页面来更新视图内容,是整个页面刷新,速度较慢;刷新页面还会导致临时状态丢失(比如表单内容)

  • 热更新 是在不刷新页面的情况下,使新代码生效,整个网面不会刷新,状态也不会丢失

target: 'web',
plugins: [
new webpack.HotModuleReplacementPlugin({})
]

noParse#

noParse是用来过滤不需要解析的模块,比如jquery,lodash之类的,这些库一般不会再引入其它库,所以不需要webpack去解析其依赖,也不用打包,只是直接引用即可

module: {
noParse: /jquery|lodash/,
}

多线程打包#

thread-loader

将耗时的 loader 放在一个独立的 worker 池中运行,加快 loader 构建速度。

webpack 官网 提到 node-sass 中有个来自 Node.js 线程池的阻塞线程的 bug。 当使用 thread-loader 时,需要设置 workerParallelJobs: 2

由于 thread-loader 引入后,需要 0.6s 左右的时间开启新的 node 进程,如果项目代码量小,引入 thread-loader就没什么必要了

我们应该仅在非常耗时的 loader 前引入 thread-loader。

优化图片#

使用打包大小分析工具#

how to use webpack-bundle-analyzer

webpack-bundle-analyzer

升级webpack5遇到的问题#

node的一些模块webpack不自带了#

webpack记录
https://nollieleo.github.io/posts/webpack记录/
作者
翁先森
发布于
2021-08-05
许可协议
CC BY-NC-SA 4.0