常用配置
module.exports = {
mode: 'none/development/production',
devtool: 'eval-cheap-module-source-map/none',
entry: './src/index.js/',
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].bundle.js',
chunkFilename: '[name].chunk.js',
// publicPath: '/build/'
},
devServer: {
hot: true, // 开启热更新
port: 'port number/auto',
// proxy: {}
static: {
directory: path.resolve(__dirname, 'build'),
}
},
module: {
noParse: /jquery|lodash/,
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"],
},
{
test: /\.(jpg|png|jpeg|gif|svg)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 8 * 1024,
},
},
generator: {
filename: "assets/imgs/[hash:6][ext][query]",
},
},
],
},
plugins: [...],
resolve: {
alias: {
$imgs: path.resolve(__dirname, "./src/assets/imgs/"),
},
extensions: [".js", "jsx", ".ts", ".tsx"],
modules: [path.resolve(__dirname, "node_modules")],
},
cache: {
type: "memory/filesystem", // 临时/持久化
buildDependencies: {
config: [__filename]
},
// version: process.env.NODE_ENV,
// name: process.env.NODE_ENV,
}
// snapshot: { // 大部分情况使用默认
// managedPaths: [path.resolve(__dirname, '../node_modules')],
// immutablePaths: [],
// buildDependencies: {
// hash: true,
// timestamp: true,
// },
// module: {
// timestamp: true,
// },
// resolve: {
// timestamp: true,
// },
// resolveBuildDependencies: {
// hash: true,
// timestamp: true,
// },
// },
optimization: {
splitChunks: {
chunks: 'all',
minSize: 20000,
minRemainingSize: 0,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
enforceSizeThreshold: 50000,
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
lodash: {
name: 'lodash-vendor',
test: /[\\/]lodash[\\/]/,
priority: 0,
reuseExistingChunk: true,
},
},
},
minimize: true,
minimizer: [new TerserWebpackPlugin()],
sideEffects: 'true',
}
}
entry
- 单页面只有一个入口文件
output
- path: 打包后输出文件位置
- filename:打包生成 bundle 文件名称
- chunkFilename: chunk 包名称
- publicPath:打包后 html 加载资源文件前缀;未找到时,报 404
module
loader
- 图片、字体 —— 采用 assetModuleFilename
- asset/resource:将资源分割为单独的文件,并导出 url,类似之前的 file-loader 的功能.
- asset/inline:将资源导出为 dataUrl 的形式,类似之前的 url-loader 的小于 limit 参数时功能
- asset:会根据文件大小来选择使用哪种类型,当文件小于 8 KB(默认) 的时候会使用 asset/inline,否则会使用 asset/resource
- test、include、exclude 对匹配到的文件进行 loader
- 优先级:exclude > include > test
- options:提供 loader 特有的属性值(参考对应的 loader)
其他
- noParse:不解析正则表达式匹配到的文件
resolve:如何正确的找到对应的文件
- alias:对常用模板进行别名,有利于代码简洁
- extensions:支持文件后缀匹配的缩写;支持多种类型,命名不可相同
- modules
- 相对路径:对 module 的 resolve 过程中,会依次查找 ./node_modules、../node_modules、../../node_modules 等,即沿着路径一层一层往上找,直到找到 node_modules
- 绝对路径:只找给定路径下
- unsafeCache:针对常用模板进行缓存处理;再次解析时,直接用缓存
plugins
- 熟悉常用的 plugin
- 打包分析:webpack-bundle-analyzer
optimization
split chunk
-
目的:减少请求资源的大小和请求次数
-
源码
splitChunks: { chunks: 'all', minSize: 20000, // 打包前文件大小 maxSize: 0, // 打包后文件大小 minRemainingSize: 0, minChunks: 1, // 引用次数 maxAsyncRequests: 30, // 最大的按需(异步)加载次数 maxInitialRequests: 30, // 打包后的入口文件加载时,还能同时加载js文件的数量(包括入口文件) enforceSizeThreshold: 50000, cacheGroups: { defaultVendors: { name: 'vendors', // 自定义打包的文件名 test: /[\\/]node_modules[\\/]/, priority: -10, // 优先级 reuseExistingChunk: true, }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true, }, ... 自定义多个groups,减小首屏的文件的加载资源文件的大小 }, } // 优先级: minSize > maxSize > maxInitialRequests / maxAsyncRequests // 满足上面一个条件都会进行模版拆分 // cacheGroups里面没有定义,使用外面的配置 // 拆分chunk包,防止某个包过大;使减少请求资源的大小和请求次数达到平衡 -
懒加载:通过 import 动态引入,实现懒加载(webpackPrefetch、webpackPreload)
tree shaking
- 目的:移除 JavaScript 上下文中的未引用代码
- sideEffects
- 需要再 package.js 配置 sideEffects: [], 不需要 tree shaking 的正则表达式
- 模式:生产模式生效 —— mode: "production"
minimize、minimizer
- terser-webpack-plugin:js 压缩
- css-minimizer-webpack-plugin:css 压缩
cache
- 作用:持久化缓存主要解决的就是优化编译流程(resolve,build),减少编译耗时的问题
- 缓存失效策略 —— 当模块代码没有发生变化,但是构建处理过程本身发生变化时(例如升级了 Webpack 版本、修改了配置文件、改变了环境变量等),也可能对构建后的产物代码产生影响
- buildDependencies:业务中依赖模块改变时
- version
- name:利用 name 保留多套缓存
- 资料:缓存讲解
snapshot
- 作用:配置决定了缓存内存生成 snapshot 时所采用的策略,策略最终会影响到缓存是否失效,即 webpack 是否决定来使用缓存
- 策略:timestamps(时间戳) | content hash(hash 值) | timestamps + content hash(时间戳+hash 值)
- 源码
snapshot: { managedPaths: [path.resolve(__dirname, '../node_modules')], // 被信任的路径, immutablePaths: [], buildDependencies: { // 依赖项 hash: true, timestamp: true, }, module: { // 构建的module timestamp: true, }, // 在 resolve request 的时候创建 snapshot 的方式 resolve: { timestamp: true, }, // 在 resolve buildDependencies 的时候创建 snapshot 的方式 resolveBuildDependencies: { hash: true, timestamp: true, }, },
devServer
- 作用:开发环境使用
- hot: 开启热更新
- port:端口;自定义/auto:自动
- static
- directory:devServer 启动后,文件路径;类似 output.publicPath
- TODO publicPath
other config
- mode:环境
- devtool:利用 SourceMap 反向定位到源码位置
- eval-cheap-module-source-map:dev
- none —— prod;理由:就是不想别人看到我的源代码
优化
- 步骤:resolve - build - generator
- 优化主要针对前面两个步骤
- loader
- 减少不必要的解析文件;noParse
- exclude、include、test 减小范围
- webpack4:cache-loader
- thread-loader:多线程
- resolve
- 减少不必要的查找;避免了层层寻找 node_modules 的开销
- 针对常用的进行缓存处理:unsafeCache
- 简化整个 resolve 过程
- cache
- webpack5:持久化缓存
- plugin
- webpack4:DllPlugin
- 压缩:css、js 代码压缩
- optimization
- split chunks: 拆分 chunk 包,减小首屏加载无用资源
- 懒加载