webpack5优化的地方及搭建的一些体会
前言
在从Webpack4
到Webpack5
的升级过程中,即使以前已经搭建过Webpack4
,但是搭建Webpack5
的过程中还是有点痛苦。因为Webpack
提供的功能方法实在是太多了,很庞大的一个体系,所以搭建完感触还是很多的,发现不能一味的从网上找,还是得看文档。 看完文档才发现原来Webpack5
里面已经精简了很多插件了,不需要额外安装其他插件,很多以前概念比较模糊的东西,看了文档还是比较清晰的。大家有兴趣的话可以Fork
我的webpack5-boilerplate
学习交流,建议大家多敲敲多试试,过程虽然有点痛苦,但是一定会有收获的。 本文讲解,需要一定Webpack4
基础,还没有搭建过Webpack4
的同学,可以看看这篇Webpack4搭建
下面的讲解,都基于webpack5-boilerplate
这个项目。
Webpack
大体框架
首先我们对Webpack
得有一个大体的框架认识
// webpack.config.js
module.exports = {
// 入口
entry: {},
// 打包输出
output: {},
// 配置模块如何解析
resolve: {},
// 配置各种loader
moudle: {},
// 配置插件
plugins: [],
// 优化(可以进行代码分割)
optimization: {},
// webpack-dev-server 开发时的配置,一般用于development模式
devServer: {}
};
所需要的Loader
CSS
类的Loader
css-loader
css-minimizer-webpack-plugin
mini-css-extract-plugin
less-loader
less
style-loader
- ...
目前我暂时用到的就这些
解析ES6
类的Loader
@babel/core
@babel/plugin-transform-runtime
@babel/preset-env
babel-loader
core-js
解析Html
类的Loader
html-webpack-plugin
Webpack5
不需要用到的依赖
url-loader
file-loader
clean-webpack-plugin
@babel/polyfill
@babel/runtime
optimize-css-assets-webpack-plugin
最后依赖列表预览
"devDependencies": {
"@babel/core": "^7.16.12",
"@babel/plugin-transform-runtime": "^7.16.10",
"@babel/preset-env": "^7.16.11",
"babel-loader": "^8.2.3",
"css-loader": "^6.5.1",
"css-minimizer-webpack-plugin": "^3.4.1",
"filemanager-webpack-plugin": "^6.1.7",
"html-webpack-plugin": "^5.5.0",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"mini-css-extract-plugin": "^2.5.3",
"style-loader": "^3.3.1",
"webpack": "^5.67.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.3",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"core-js": "^3.20.3"
},
webpack5-boilerplate
这个脚手架,核心的就这些依赖,另外需要的依赖再自己装就好了。是不是觉得依赖少了很多,我是顿时觉得很舒服。接下来讲一下这些不需要用到的插件,如何在Webpack5
里面用别的方式替代。
使用Asset Module
模块,来管理资源
官方解释:资源模块(asset module
)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。
以编译图片为例,所以如果我们要编译图片:
const
maxSize = 10 * 1024,
outImageFileName = 'img/',
proResFileName = 'assets/';
/**
* @maxSize 如果图片小于10Kb,会被转为base64
* @outImageFileName 要导出到哪个文件夹,如果写在filename配置里面,则会导出到这个文件夹上
* @proResFileName outputPath指的也是把该资源存放到proResFileName文件夹下
*/
module: {
rules: [
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset',
// 设置图片导出大小,如果小于预设的值,则会被转化成base64
parser: {
dataUrlCondition: {
maxSize
}
},
// 设置导出的路径为 img
generator: {
filename: `${outImageFileName}[name]-[hash:2][ext][query]`,
outputPath: proResFileName
}
},
]
}
参考文章:
使用output
里面配置,在生成文件之前清空output
目录的内容
这样我们就可以不需要安装clean-webpack-plugin
这个插件了
output: {
clean: true
};
参考文章:
使用mini-css-extract-plugin
插件来压缩css
代码
// Webpack5压缩配置
optimization: {
minimizer: [
// 压缩css
new CssMinimizerPlugin(),
// '...' 来访问默认值。(不加的话,js不会压缩)
'...'
],
},
// Webpack4压缩配置
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
plugins: [
// 压缩css
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'), //用于优化\最小化 CSS 的 CSS 处理器,默认为 cssnano
cssProcessorOptions: { safe: true, discardComments: { removeAll: true } }, //传递给 cssProcessor 的选项,默认为{}
canPrint: true //布尔值,指示插件是否可以将消息打印到控制台,默认为 true
}),
]
Webpack5
压缩css
的配置对比起Webpack4
的更加简单。
参考文章:
Babel
依赖配置
@babel/polyfill
在Babel 7.4.0
就被弃用了。所以不用在安装@babel/polyfill
这个插件了Babel
是一个个人觉得蛮复杂的体系,大家可以好好阅读下面这几篇文章,读多几遍好好理解一下
参考文章:
关于devServer
配置的理解
我想大家最懵圈的应该就是devServer.static
(Webpack5
是static
,Webpack4
是contentBase
)这个配置了吧。是不是一直觉得,如果把里面的路径配置指向了我们打包出来的文件夹名字(dist
),然后开启了webpack-dev-server
服务器,就是访问的我们打包的那个资源(dist
),其实并不是。这里大家可以自己建一个最简单的demo
,然后配置改成下面这样:
output: {
path: path.resolve(__dirname, `build`),
},
devServer: {
static: {
directory: path.resolve(__dirname, `outDir`),
},
}
此时打包出来的文件夹是build
,但是我们开启服务器访问的时候,访问是outDir
文件夹,结果页面显示的还是我们的开发的index.html
的内容,这就说明devServer.static
的配置,根本就不是控制开启了webpack-dev-server
服务器后访问的文件目录。这是经过本人测试,分析后的个人理解。
devServer.static
,实际上指的是:一个存放,不经过Webpack
编译的静态资源目录,他是一个目录。它的功能就很像是vue-cli
里面的public
文件夹,我们开发的时候,可以通过./
或者../
访问到那个资源(具体看目录关系)。
怎么访问到devServer.static.directory
里面的文件
首先,我们先清楚这几点:
开启
webpack-dev-server
服务器时,以webpack5-boilerplate
为例,我们的代码会根据我们的配置,在内存中生成一个打包文件,保存在内存中的打包文件目录结构:(http://localhost:8080/) ├── js ├── img ├── font ├── media ├── favicon.ico ├── index.html └── share.html
- 开启
webpack-dev-server
服务器时,devServer.static.directory
里面的文件会直接被映射到根目录下 devServer.static.directory
,默认指向的是public
文件夹。
OK,我们在根目录下新建一个public
的文件夹,里面放一个test.txt
文件。开启webpack-dev-server
,打开http://localhost:8080/test.txt
,我们就可以访问到这个不经打包的静态资源了。此时保存在内存中的文件目录结构就变成了:
(http://localhost:8080/)
├── js
├── img
├── font
├── media
├── favicon.ico
├── test.txt (直接被映射到根目录下)
├── index.html
└── share.html
所以想要访问devServer.static.directory
的内容就是:http://localhost:8080/(文件名字)
。
注意:如果在public
里面新建一个index.html
,访问http://localhost:8080/index.html
或者http://localhost:8080/
时,内容是我们的开发的index.html
模板,这是因为我们的配置把编译后的index.html
输出在dist
文件夹根目录了,此时覆盖掉了public/index.html
(可以在插件HtmlWebpackPlugin
,把输的filename
,设置为filename: index2.html
,在public
下新建一个index.html
,此时访问http://localhost:8080/
就是public
里面的index.html
) 所以我们在public
文件夹里面,要避免与被编译的文件同名,否则会被覆盖掉。
关于devServer.devMiddleware.publicPath
配置说明
devServer.devMiddleware.publicPath
对应的是Webpack4
里面的devServer.publicPath
,以下简称publicPath
。 在没有配置publicPath
的时候,我们开启webpack-dev-server
,访问http://localhost:8080/
得到的是覆盖掉public/index.html
的编译后的模板index.html
。因为publicPath
默认值是:''
指向根目录,所以我们访问http://localhost:8080/
就是根目录,不用在后面加路径。 但是如果我们想类似以下访问我们的开发页面:http://localhost:8080/test/
,我们只要将配置设置成:
output: {
publicPath: '/test/',
},
devServer: {
/**
* 表示打包生成的静态文件所在的位置,意思是url访问的路径
* 改变dist访问的路径,outpath需要跟他一致,启动访问的url为http://localhost:8080/test/index.html
*/
devMiddleware: {
publicPath: '/test/',
},
}
此时我们访问的开发页面的路径就是:http://localhost:8080/test/
注意:output.publicPath
与devServer.devMiddleware.publicPath
要始终保持一致,不然会有问题
转载自:https://segmentfault.com/a/1190000041398508