webpack入门到实战(中)
介绍
webpack入门到实战(上)中主要包含内容
- 从零开始打包第一个应用
webpack.config.js
配置文件- loader 和 plugins 打包不同资源文件
webpack-dev-server
下面我们继续 webpack 的生产环境下的配置… …
当我们的代码打包上线时我们可能会考虑到:
css
是被打包在js
中的所以打包后是没有.css
的,这样会导致js
文件很大,而项目运行是需要先加载js
,然后再通过创建style
标签插入到页面中。有没有什么办法可以将css
从js
中提取出来呢?- 这么多代码可以进行压缩处理使其体积更小吗?
- 我们的
js
代码在不同浏览器中运行的兼容性有没有什么办法可以处理? - …
解决这些问题,可以让我们的代码在生产环境下运行更快更优更平稳(开发环境不需要做这些处理,这些打包优化项会拖慢我们开发环境的编译构建过程)。
提取css为单独文件
npm i mini-css-extract-plugin -D
将style-loader
替换成MiniCssExtractPlugin.loader
// webpack.config.js
...
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
// 这个loader取代style-loader,因为style-loader会将js中的css内容通过js方法插入到页面中,我们需要的是提取js中的css为单独的css文件
MiniCssExtractPlugin.loader,
// 将css文件变成commonjs模块整合到js文件中,里面内容是样式字符串
'css-loader'
]
},
{
test: /\.less$/,
use: [
// 取代style-loader
MiniCssExtractPlugin.loader,
'css-loader',
// 将less文件编译成css文件(需要安装less和less-loader)
'less-loader'
]
},
]
},
plugins: [
new HtmlWebpackPlugin({...}),
new MiniCssExtractPlugin({
// 对打包后的css重命名文件为 build/css/style.css,不重命名默认打包文件为 build/main.css
filename: 'css/style.css'
})
],
}
npm run build
所有的css
和less
文件打包成了一个单独的build/css/style.css
文件,且自动插入到了build/index.html
页面link
中。
注意:如果 less
使用style-loader
而 css
使用MiniCssExtractPlugin.loader
,最终的build/css/style.css
中就只会打包 css
文件,less
还是会通过style-loader
的方式通过style
标签插入到页面的head
中,所以对样式进行处理时,别忘了css
和less
的loader都要处理。
css兼容性处理
npm i postcss-loader autoprefixer -D
// webpack.config.js
{
test: /\.css$/,
use: [
...
'postcss-loader'
]
},
{
test: /\.less$/,
use: [
...
'postcss-loader'
]
},
// 新建 postcss.config.js
module.exports = {
plugins: [
// 通过查看package.json中的 browserslist 配置,使用 Can I Use的数据来决定哪些前缀需要加上
require('autoprefixer')
]
}
// package.json
{
...
"devDependencies": {...},
"browserslist": [
"last 3 version",
">1%" // 使用超过1%的浏览器
]
}
npm run build
关于更多 browserslist
目标浏览器参数可以参考browserslist 参数。
压缩css
注:这里为了方便查看打包后的成果物内容,打包模式都是设置的开发模式,真正上线打包时记得改成开发模式。两种模式下的结果都是有效的,只是体积大小不同,因为:
- 开发模块(即:
mode="development"
)打包结果中build/js/bundle.js
、build/css/style.css
和build/index.html
都是未压缩且保留注释的。- 生产模式(即:
mode="production"
)打包结果中build/js/bundle.js
和build/index.html
文件是压缩且清除注释的,但build/css/style.css
仅仅清除了注释并没有被压缩。
如何对打包生成的css
文件进行压缩来减小体积呢?
npm i optimize-css-assets-webpack-plugin -D
// webpack.config.js
...
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
plugins: [
...
new OptimizeCssAssetsWebpackPlugin()
],
npm run build
注意:压缩优化后打包结果注释还是保留的,只有设置为生产环境时才会清除注释。
eslint 语法检查
npm i eslint eslint-webpack-plugin -D
// webpack.config.js
...
const ESlintWebpackPlugin = require('eslint-webpack-plugin')
plugins: [
...
// 会默认去找.eslintrc配置文件
new ESlintWebpackPlugin()
]
npx eslint --init
或者手动创建.eslintrc
文件
// .eslintrc
{
"parserOptions": {
// script / module,es6+语法和使用export/import语法的需要指定module
"sourceType": "module",
"ecmaVersion": 2015
},
"rules": {
"no-console": "warn" // 不允许使用 console 语句
}
}
此时项目中如果使用了 console.log
语句,看到报警告就说明配置成功了。
关于更多eslint配置规则以及其他项的配置可以自行去查看。
babel 处理js兼容性问题
我们知道不同的浏览器中的代码兼容性是不同的,上面我们处理过 css
的兼容性问题,同样的 js
代码也存在兼容性问题,尤其是 IE 浏览器(没有拉踩哈,我就是单纯的…不喜欢它而已),那如何处理使得我们的 js
代码可以兼容不同的浏览器呢?
js 基本语法转化
npm i babel-loader @babel/core @babel/preset-env -D
// webpack.config.js
module: {
rules: [
...
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
}
// 新建 babel.config.js
module.exports = {
// 预设:指示babel做怎样的兼容性处理
presets: [[
// @babel/preset-env:基本语法的转换(更高级的api比如promise等没法转化)
'@babel/preset-env'
]]
}
npm run build
js 高级api转化
@babel/preset-env
只能对基本语法进行转换,而无法对更高级的 api (比如 promise
等 IE 浏览器无法识别)进行转化
IE 浏览器打开 build/index.html
如何将更高级的 api 进行转化呢?
npm i core-js regenerator-runtime -D
// babel.config.js
module.exports = {
// 预设:指示babel做怎样的兼容性处理
presets: [[
// @babel/preset-env:基本语法的转换(更高级的api比如promise等没法转化)
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3
}
]]
}
js和html的压缩
当我们设置 mode='production'
时,webpack 内部会默认压缩 js
(使用 UglifyJsPlugin
) 和 index.html
代码。
如果希望在 mode='development'
环境下对打包后的 index.html
代码进行压缩
// webpack.config.js
plugins: [
...
new HtmlWebpackPlugin({
...
minify: {
removeComments: true,
collapseWhitespace: true
}
}),
]
版本
文章中涉及到的包版本号
"@babel/core": "^7.18.2",
"@babel/preset-env": "^7.18.2",
"autoprefixer": "^10.4.7",
"babel-loader": "^8.2.5",
"core-js": "^3.22.8",
"css-loader": "^6.7.1",
"eslint": "^8.17.0",
"eslint-webpack-plugin": "^3.1.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"html-withimg-loader": "^0.1.16",
"less": "^4.1.2",
"less-loader": "^11.0.0",
"mini-css-extract-plugin": "^2.6.0",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"postcss-loader": "^7.0.0",
"regenerator-runtime": "^0.13.9",
"style-loader": "^3.3.1",
"url-loader": "^4.1.1",
"webpack": "^5.73.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.9.1"
注意:不同的webpack版本配置内容会有所不同
资源
项目代码获取
git clone https://gitee.com/potatocoder/webpack_learn.git