基本配置
5大核心概念
-
entry(入口)—使用相对路径
指示Webpack从哪个文件开始打包
-
output(输出)—使用绝对路径
指示webpack打包完的文件输出到哪里,怎么命名
-
loader(加载器)
webpack本身只能处理js、json等资源,其他资源需要借助loader,webpack才能解析
-
plugins(插件)
扩展webpack的功能
-
mode(模式)
主要有两种模式
-
开发模式:development
-
生产模式:production
-
开发模式介绍
在这个模式下我们主要做两件事:
-
编译代码,使浏览器能识别运行
开发时我们有样式资源、字体图标、图片资源等,webpack默认都不能处理这些资源,所以我们要加载配置来编译这些资源
-
代码质量检查,树立代码规范
提前检查代码的一些隐患,让代码运行时更加健壮
输出
output:{
// 所有文件的输出路径
path:path.resolve(__dirname,"dist"), // __dirname代表当前文件的文件夹目录
// 入口文件打包输出文件名
filename:"static/js/main.js",
// 自动清空上次打包的内容
clean:true, // 原理:在打包之前,将path整个目录内容清空,再进行打包
}
处理样式资源
webpack本身是不能识别样式资源的,所以我们需要借助loader来帮助webpack解析资源
我们找loader都应该去官方文档找对应的loader,然后使用
官方文档找不到的话,可以从Github中寻找
解析CSS资源
安装
npm install --save-dev css-loader
npm install --save-dev style-loader
配置
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
test
的值是一个正则表达式,用于匹配文件
use
的值是一个数组,用于配置所用loader
信息,loader
的执行顺序为从右到左
css-loader
将css资源编译成common.js
的模块到js中
style-loader
将js中css通过创建style
标签添加html
文件中生效
处理图片资源
过去在webpack4时,我们处理图片资源通过file-loader
和url-loader
进行处理
现在webpack5已经将两个loader功能内置到webpack里,我们只需要简答配置即可处理资源
base64的优缺点
优点:
网页中使用base64格式的图片时,不用再请求服务器调用图片资源,减少了服务器访问次数
base64编码的字符串,更适合不同平台、不同语言的传输
缺点:
base64格式的文本内容较多,存储在数据库中增大了数据库服务器的压力
网页加载图片虽然不用访问服务器了,但因为base64格式的内容太多,所以加载网页的速度会降低,可能会影响用户的体验。
base64无法缓存,要缓存只能缓存包含base64的文件,比如js或者css,这比直接缓存图片要差很多,而且一般HTML改动比较频繁,所以等同于得不到缓存效益。
算法是编码, 不是压缩, 编码后只会增加字节数,但是算法简单, 几乎不会影响效率,算法可逆, 解码很方便, 不用于私密信息通信;
{
test:/\.(png|jpe?g|gif|webp|svg)$/
type:"asset",
parser:{
dataUrlCondition:{
// 小于10kb的图片转为bas64
// 优点:减少请求数量,缺点:体积会变大
maxSize:10 *1024 // 10kb
}
}
}
修改输出目录
如果不对输出目录进行设置,我们会发现打包之后的图片和代码文件处于一个文件夹内,这样子会显得很乱
所以,我们需要修改图片的输出目录,将所有图片
{
test:/\.(png|jpe?g|gif|webp|svg)$/
type:"asset",
parser:{
dataUrlCondition:{
// 小于10kb的图片转为bas64
// 优点:减少请求数量,缺点:体积会变大
maxSize:10 *1024 // 10kb
}
},
generator:{
// 输出图片的名称
filename:"static/images/[hash][ext][query]"
}
}
【举例】
一张打包好的图片,文件名:074das1d6546131as6d.png
-
hash
即为074das1d6546131as6d
-
ext
即为文件后缀,png
-
query
是携带的参数,url地址?后的查询参数
现在有一种感觉,打包之后的图片名字很长,我们可以修改hash
值的长度进行修改
generator:{
// 输出图片的名称
filename:"static/images/[hash:10][ext][query]"
}
[hash:10]
就能将hash值取前10位
处理字体图标资源或音频等资源
{
test:/\.(ttf|woff2?|mp3|mp4)$/,
// 这样就不会转为base64形式
type:"asset/resource",
generator:{
// 输出名称
filename:"static/media/[hash][ext][query]"
}
}
处理js资源
webpack对js处理是有限的,只能编译js中ES模块,不能编译其他语法,导致js不能在IE等浏览器中运行,所以我们希望做一些兼容处理
-
针对js兼容性处理,我们使用babel来完成
-
针对代码格式,我们使用Eslint来实现
我们先完成Eslint,检测代码格式无误后,在babel做代码兼容性处理
Eslint
可组装的JavaScript和JSX检查工具
我们使用Eslint,关键是写Eslint配置文件,里面写上rules规则,将来运行Eslint时就会以写的规则对代码进行检查
使用
npm install eslint-webpack-plugin eslint --save-dev
然后把插件添加到你的 webpack 配置
注意:插件是需要引入的
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
// ...
plugins: [new ESLintPlugin({...})],
// ...
};
new ESLintPlugin
参数配置:
详细配置:https://webpack.docschina.org/plugins/eslint-webpack-plugin
context
类型:
string
默认值:
compiler.context
指定文件根目录,类型为字符串。需要检测的文件
一般的写法:
path.resolve(__dirname,'src)
,检测根目录下,src
文件夹下的文件
…
配置
-
配置文件
配置文件有很多的写法:
-
.eslintrc
-
.eslintrc.js
-
.eslintrc.json
-
package.json
中eslintConfig
,无需创建文件,在原有文件基础上写
区别在于配置格式不一样
Eslint会查找和自动读取它们,所以以上配置文件只需一个存在即可
-
-
具体配置
以
.eslint.js
配置文件为例:module.export = { // 解析选项 parserOptions:{}, // 具体检查规则 rules:[]. // 继承其他规则 extends:[], // ... }
-
parserOptions解析选项
parserOptions:{ ecmaVersion:6 // ES语法版本 sourceType:"module" // ES模块化 ecmaFeatures:{ jsx:true // 如果是react项目,就需要开启jsx语法 } }
-
rules 具体规则
-
"off"
或者0
—— 关闭规则 -
"warn"
或者1
—— 开启规则,使用警告级别的错误:warn
(不会导致程序退出) -
"error"
或者2
—— 开启规则,使用错误级别的错误:error
(当被触发的时候,程序会退出)
rules:{ semi:"error", // 禁止使用分号 "default-case":[ "warn", // 要求switch语法中有default,否则警告 {commentPattern:'^no default$'} // 允许在最后注释no default,就不会警告了 ] // .... }
-
-
extends 继承
开发中有一点点写rules规则太费劲,所以有更好的办法,继承现有的规则
{ // 例如在react项目中 extends:['react-app'] }
-
Babal
主要将ES6语法编写的代码转化为向后兼容的javascript语法,以便能够运行在当前和就版本的浏览器或者其他环境
使用
npm install -D babel-loader @babel/core @babel/preset-env webpack
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
exclude
:排除哪些文件不进行处理
预设可以直接写在webpack的配置中,也可以新建文件进行配置
配置
-
配置文件
-
babel.config.js
-
babel.config.json
-
.babelrc
-
.babelrc.js
-
.babelrc.json
Babel会查找和自动读取它们,所以以上配置文件只需要存在一个即可
-
-
具体配置
我们以
babel.config.js
为例module.exports = { // 预设 presets:[] }
presets预设,简单理解:就是一组Babel插件,扩展Babel功能
-
@babel/preset-env
:一个智能预设,允许使用最新的javascript -
@babel/preset-react
:一个用来编译React.jsx语法的预设 -
@babel/preset-typescript
:一个用来编译Typescript语法的预设
处理html文件
在之前的代码中,我们都是在public/index.html
中引入打包后的js
文件,但是对于那些文件名中包含哈希值,并且哈希值会随着每次编译而改变的 webpack 包,通过手写的路径就出现问题,我们需要自动导包
npm install --save-dev html-webpack-plugin
该插件将为你生成一个 HTML5 文件, 在 body 中使用 script
标签引入你所有 webpack 生成的 bundle。 只需添加该插件到你的 webpack 配置中
// 配置
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: 'index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'index_bundle.js',
},
plugins: [new HtmlWebpackPlugin({
// 模板:以public/index.html文件创建新的html文件
// 新的html文件特点:1.结构和原来一致 2. 自动引入打包输出的资源
template:path.resolev(___dirname,"public.index.html")
})],
};
开发服务器&自动化—修改后自动打包
每次写完代码都需要手动输入指令才能编译代码,太麻烦,我们希望一切自动化
开发服务,不会输出资源,在内存中编译打包的,因此在目录中不会出现打包后的文件
npm i webpack-dev-server -D
devServer:{
host:'localhost', // 启动服务器域名
port:'3000', // 启动服务器端口号
open:true // 是否自动打开浏览器
}
启动服务器
-
之前打包使用的命令行为
npx webpack
-
开启服务器,需要使用
npx webpack serve
生产模式
生产模式是开发完成代码之后,我们需要得到代码将来部署上线
这个模式下我们主要对代码进行优化,让其运行性能更好
优化主要从两个角度:
-
优化代码运行性能
-
优化代码打包速度
CSS处理
css文件目前被打包到js文件中,当js文件加载时,会创建一个style标签生成样式
这样对于网站来说,会出现闪屏现象,用户体验不好
我们应该是单独的css文件,通过link标签加载
MiniCssExtractPlugin
本插件会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。
本插件基于 webpack v5 的新特性构建,并且需要 webpack 5 才能正常工作。
npm install --save-dev mini-css-extract-plugin
建议 mini-css-extract-plugin
与 css-loader
一起使用。
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()], // 第一步
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"], // 第二步
},
],
},
};
如果需要规范css文件的位置,可以再plugins
中添加参数进行修改
plugins:[
new MiniCssExtractPlugin({
filename:'static/css/main.css'
})
]
CSS兼容性处理
npm install --save-dev postcss-loader postcss
然后添加本 loader 的相关配置到你的 webpack
的配置文件
此处需要注意loader
的位置顺序:
css-loader
> postcss-loader
> less|sass等预处理loader
module: {
rules: [
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
'postcss-preset-env',
{
// 其他选项
},
],
],
},
},
},
],
},
],
},
}
我们还需要进行兼容的配置(设置最低兼容的程度),在package.json
中设置
{
...
"browserslist":[
"ie >= 9"
]
}
以上配置是兼容到ie9及以上
但是我们实际上会这么写(取数组中所有约束的交集):
{
...
"browserslist":[
"last 2 version", 所有浏览器近两个版本
"> 1%", 覆盖99%的浏览器
"not dead" 未停止维护的
]
}
封装样式loader
在配置样式的loader
的时候,我们发现有多行代码是重复的,为了代码的简洁和提高其复用性,我们将其进行封装
function getStyleLoader() {
return [
...loader重复的配置
]
}
CSS压缩
CssMinimizerWebpackPlugin
使用 cssnano 优化和压缩 CSS,在 source maps 和 assets 中使用查询字符串会更加准确,支持缓存和并发模式下运行。
npm install css-minimizer-webpack-plugin --save-dev
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /.s?css$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
],
},
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
// `...`,
new CssMinimizerPlugin(),
],
},
plugins: [new MiniCssExtractPlugin()],
};
这将仅在生产环境开启 CSS 优化。
如果还想在开发环境下启用 CSS 优化,请将 optimization.minimize
设置为 true
:
module.exports = {
optimization: {
// [...]
minimize: true,
},
};
更简单的方法就是在plugns
中直接配置
plugins:[new CssMinimizerPlugin()]