一、webpack4使用
1. webpack安装
- 全局安装
npm i webpack webpack-cli -g
- 项目本地安装
npm i webpack webpack-cli -D
- 指定版本安装
npm i webpack@4 webpack-cli -D
通常,全局安装是为了可以在任意位置直接执行webpack命令。实际开发项目中还是推荐在本地安装,因为针对每个项目需要使用的webpack版本可能不同,每个开发者电脑上全局安装的webpack也不相同,使用全局的webpack可能会带来一些不必要的问题。
2. 默认配置
webpack默认不需要配置文件,其内部已经制定了一些常用的默认配置。webpack默认读取的入口文件为webpack当前执行文件下的src/index.js文件,如果没有这个文件,webpack会报错找不到入口文件。如果没有webpack.config.js配置文件,直接执行webpack命令,还会提示警告The 'mode' option has not been set,可以在执行webpack带上参数webpack --mode=production。
在wenpack构建代码或启动服务的时候,当制定了mode的时候,webpack会自动带上一些默认的配置。mode分为development/production,默认为production。每个选项的默认配置如下(common指两个配置项都存在的属性):
- 开发/生产环境公共的默认配置:
//parent chunk中解决了的chunk会被删除
optimization.removeAvailableModules:true
//删除空的chunks
optimization.removeEmptyChunks:true
//合并重复的chunk
optimization.mergeDuplicateChunks:true
- 开发环境的默认配置:
//调试
devtool:eval
//缓存模块, 避免在未更改时重建它们。
cache:true
//缓存已解决的依赖项, 避免重新解析它们。
module.unsafeCache:true
//在 bundle 中引入「所包含模块信息」的相关注释
output.pathinfo:true
//在可能的情况下确定每个模块的导出,被用于其他优化或代码生成。
optimization.providedExports:true
//找到chunk中共享的模块,取出来生成单独的chunk
optimization.splitChunks:true
//为 webpack 运行时代码创建单独的chunk
optimization.runtimeChunk:true
//编译错误时不写入到输出
optimization.noEmitOnErrors:true
//给模块有意义的名称代替ids
optimization.namedModules:true
//给模chunk有意义的名称代替ids
optimization.namedChunks:true
- 生产环境的默认配置:
//性能相关配置
performance:{hints:"error"....}
//某些chunk的子chunk已一种方式被确定和标记,这些子chunks在加载更大的块时不必加载
optimization.flagIncludedChunks:true
//给经常使用的ids更短的值
optimization.occurrenceOrder:true
//确定每个模块下被使用的导出
optimization.usedExports:true
//识别package.json or rules sideEffects 标志
optimization.sideEffects:true
//尝试查找模块图中可以安全连接到单个模块中的段。- -
optimization.concatenateModules:true
//使用uglify-js压缩代码
optimization.minimize:true
webpack运行时还会根据mode设置一个全局变量process.env.NODE_ENV,这里的process.env.NODE_ENV不是node中的环境变量,而是webpack.DefinePlugin中定义的全局变量,允许你根据不同的环境执行不同的代码。
下的代码:
if(process.env.NODE_ENV === 'development'){
//开发环境 do something
}else{
//生产环境 do something
}
最终将编译成:
if(true){
//开发环境 do something
}else{
//生产环境 do something
}
在境下,uglify打包代码时会自动删除不可达代码,也就是说生产环境压缩后最终的代码为:
//生产环境 do something
3. webpack的五个核心参数:
- Entry
入口(entry)指示webpack以那个入口起点开始打包,分析构建内部依赖图 - Output
输出(output)指示webpack打包后的资源bundles输出到哪里去,以及如何命名 - Loader
加载器(loader)能够处理那些非Javascript/Json的文件(webpack自身职能理解识别Javascript和Json数据代码) - Plugin
插件(plugin)可以用于执行范围更广的任务,插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等 - Mode
模式(mode)指示webpack使用相应模式的默认配置,有生产模式(production)和开发模式(development)两种,如果不配置webpack会报警告,并以生产模式(production)打包。
4. webpack4常用的loader和plugin配置
5. webpack-dev-server开发配置
二、webpack打包优化
三、webpack4升级到webpack5的差异记录
webpack从4升级到5之后,很多的插件可能不兼容,或者是对应功能的插件换了新的插件名称,webpack5本身也有一些不一样的地方,比如本身就内置了file-loader和url-loader的加载器,通过type来制定文件资源的处理方式。使用webpack4老版本的配置,容易出现各种问题,在这做一下记录,后续遇到的话持续更新。
1.eslint-loader改为eslint-webpack-plugin
plugins: [
new ESLintPlugin({
fix: true, // 启用ESLint自动修复功能
extensions: ['js', 'jsx'],
context: resolve('src'), // 文件根目录
exclude: '/node_modules/',// 指定要排除的文件/目录
cache: true //缓存
})
]
2.内置file-loader和url-loader
{
test: /.(eot|svg|ttf|woff|woff2?)$/,
type: 'asset/resource',
generator: {
filename: 'static/fonts/[hash][ext][query]'
}
},
{
test: /.(png|jpe?g|gif|svg)(?.*)?$/,
type: 'asset/resource',
generator: {
filename: 'static/images/[hash][ext][query]'
}
}
3.本地启用devserver命令更改,webpack-dev-server改为webpack serve
"start": "webpack serve --config build/webpack.dev.js --progress",
4. 不支持babel-polyfill,改用@babel/runtime-corejs3和@babel/plugin-transform-runtime
5.图片路径问题
webpack5生产环境需要使用mini-css-extract-plugin的loader,升级后发现背景图片不显示(img标签正常),排查发现是打包后相对路径出现问题,修改publicPath解决
- 修改前
{
test: /.(sa|sc|c)ss$/,
use: [
isEnvProduction ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
'postcss-loader',
'sass-loader'
]
}
- 修改后
const cssLoader = () => {
const loader = devModel ? 'style-loader' : {
loader: devModel ? 'style-loader' : MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
}
return [
loader,
'css-loader',
'postcss-loader',
'sass-loader'
]
}
// rule
{
test: /.(sa|sc|c)ss$/,
use: cssLoader()
},
6. 部分页面报错,文件引用出现问题(大坑)
排查后发现是用了旧的插件出现问题
new webpack.optimize.ModuleConcatenationPlugin()
删掉OK
7.optimize-css-assets-webpack-plugin替换为css-minimizer-webpack-plugin
optimization: {
moduleIds: 'deterministic',
minimizer: [
new CssMinimizerPlugin({
parallel: true // 开启多线程压缩
}),
]
}