webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。
当 webpack 处理应用程序时,
- 它会在内部从一个或多个入口点构建一个 依赖图 (dependency graph)
- 然后将你项目中所需的每一个模块组合成一个或多个 bundles。
- 它们均为静态资源,用于展示你的内容。
从 v4.0.0 开始,webpack 可以不用再引入一个配置文件来打包项目。
01. 工作模式 mode
mode 参数:其默认值为 production
。
development
:开发模式。- 没有进行代码优化。
- 仅能编译 JS 中的
ES Module
语法(模块化语法)- 不会编译箭头函数、剩余参数语法
- 打包更加快速。
production
:生产模式。- 不仅能编译 JS 中的
ES Module
语法。 - 还会进行
tree-shaking
和压缩代码。 - 打包比较慢。
- 不仅能编译 JS 中的
none
配置 mode:
- 在配置对象中提供
mode
选项module.exports = { mode: 'development', };
- 从 CLI 参数中传递
npx webpack --mode=development
npx
指令会将 node_modules
目录下的 .bin
添加为环境变量,因此可以访问该环境变量下的一些应用程序,包括 webpack.cmd
指令。
npx webpack [entry] --mode=[mode]
npx webpack ./src/main.js --mode=development
02. 配置文件
- 在根路径下新建一个配置文件
webpack.config.js
- 新增基本配置信息
const path = require('path') module.exports = { mode: 'development', // 模式 entry: './src/index.js', // 入口文件 output: { filename: 'bundle.js', // 入口文件输出的目标文件 path: path.join(__dirname, 'dist') // 入口文件依赖的所有文件输出的根目录 } }
03. Loader:处理 CSS
webpack 默认支持处理 JavaScript
和 JSON
文件。
其他类型都处理不了,必须借助 Loader
来对不同类型的文件进行处理。
安装 css-loader
来处理 CSS:
npm install css-loader -D
const path = require('path')
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ use: 'css-loader'
+ }
+ ]
+ }
}
module.rules
中的配置对象,可以使用use
/loader
来指定要使用的loader
:use
:可以使用多个loader
loader
:只能使用一个loader
04. 插件 plugin:处理 HTML
插件可以贯穿 Webpack 打包的生命周期,执行不同的任务。
插件 html-webpack-plugin
会为应用程序生成一个 HTML 文件,且在导出的 HTML 文件中引入入口 JavaScript 文件(通过 defer
的方式),并自动将生成的所有 bundle 注入到此文件中。
可以通过配置使用已有的 html 文件作为模板。
npm i html-webpack-plugin -D
const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: 'css-loader'
}
]
},
+ plugins: [
+ new HtmlWebpackPlugin({
+ template: './src/index.html'
+ })
+ ]
}
05. 自动清空打包目录
webpack5
webpack5 在 output
选项中设置 clean: true
即可在每次构建时自动清空上次构建的目录。
- 在打包前将
path
指定的目录整个清空。
module.exports = {
// ...
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist'),
+ clean: true
},
// ...
}
webpack4
webpack4 需要使用插件 clean-webpack-plugin
:
npm i clean-webpack-plugin -D
const {
CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
// ...
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin()
],
// ...
}
06. 引入 CSS
只靠 css-loader
只能处理 css,而无法将样式加载到页面上,需要通过 style-loader
来完成这个功能。
css-loader
:将 css 资源编译成 commonjs 的模块打包到 JavaScript 中style-loader
:将 JavaScript 中的 css 通过创建 style 标签的形式添加到 html 文件中。
-
安装
style-loader
npm i style-loader -D
-
配置 loader
- loader 的执行顺序是从后往前。
css-loader
→style-loader
module.exports = { // ... module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] }, // ... }
- loader 的执行顺序是从后往前。
-
引用样式文件
- 在入口文件
./src/index.js
引入样式文件./src/index.css
import './index.css'
style-loader 的核心逻辑:
- 通过动态添加 style 标签的方式,将样式引入页面。
const content = `${ 样式内容}` const style = document.createElement('style'); style.innerHTML = content; document.head.appendChild(style);
- 在入口文件
07. CSS 兼容性
使用 postcss-loader
,自动添加 CSS3 部分属性的浏览器前缀。
npm install postcss postcss-loader postcss-preset-env -D
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/, //匹配所有的 css 文件
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
}
]
},
//...
}
前置插件中有 autoprefixer
,能够为 css
选择器增加不同的浏览器前缀。
- 其内部会根据
browserslist
指定浏览器版本 - 然后在
caniuse
查找该浏览器版本的兼容性支持情况。
// postcss.config.js
module.exports = {
plugins: [require('postcss-preset-env')]
}
// or 在 webpack.config.js 中进行配置
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.css$/i,
exclude: /node_modules/,
use: [
'style-loader',
'css-loader',
// +
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: ["postcss-preset-env"]
}
}
}
// +
]
},
// ...
]
},
// ...
}
创建浏览器兼容的配置文件 .browserslistrc
指定兼容性处理的程度:
- 也可以通过在
package.json
中添加browserslist
字段进行配置
# 换行相当于 and
last 2 version # 回退 2 个浏览器版本
> 0.5% # 全球超过 0.5% 的人使用的浏览器
not dead
IE 10 # 兼容 IE 10
08. 引入 Less / Sass
Less 和 Sass 需要使用对应的 Loader 来处理:
- Less:
less-loader
- Sass:
sass-loader
+node-sass
或dart-sass
Sass
安装 loader:
npm install sass-loader -D
npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
在 index.js 中引入 sass 文件
import './sass.scss'
修改配置:
module.exports = {
// ...
module: {
rules: [
{
test: /\.s[ac]ss$/i, //匹配所有的 sass/scss 文件
use: [
'style-loader',
'css-loader',
'postcss-loader',
'sass-loader',
]
},
]
},
// ...
}
Less
安装 loader:
npm install less less-loader -D
在 index.js 中引入 less 文件
import './less.less'
修改配置:
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.less$/i, //匹配所有的 less 文件
use: [
'style-loader',
'css-loader',
'postcss-loader',
'less-loader',
]
},
]
},
// ...
}
09. 分离样式文件
前面都是依赖 style-loader
将样式通过 style 标签的形式添加到页面上。
网页因此会出现闪屏的现象,用户体验不好。
使用单独的 CSS 文件,并通过 link 标签引入,性能表现更好。
通过 mini-css-extract-plugin
可以以 CSS 文件的形式将样式引入到页面上。并且会默认将所有的 css 文件打包成一个。
$ npm i mini-css-extract-plugin -D
替换 style-loader
为 MiniCssExtractPlugin.loader
,并添加插件:
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.css$/i,
use: [
// 'style-loader',
MiniCssExtractPlugin.loader, // 添加 loader
'css-loader',
'postcss-loader'
]
},
// ...
]
},
plugins:[
// ...
new MiniCssExtractPlugin({
filename: '[name].[hash:8]:css'
}),
// ...
],
// ...
}
10. CSS 压缩
使用 CssMinimizerWebpackPlugin
压缩 CSS 文件。
npm i css-minimizer-webpack-p
plugins: [
...,
new CssMinimizerPlugin(),
...
]
默认生产模式已经开启了 html 压缩和 js 压缩,因此不需要进行额外的配置。
11. 处理图片资源
后续配置开发环境的时候,会使用 devServer 本地开启一个服务器,可以通过设置 contentBase
/ static
直接读取源目录中的静态文件,
但在生产环境中,引用资源的相对地址经过 webpack 打包后,会发生资源找不到的错误:
<img src="/logo.png" alt="">
<div id="imgBox"></div>
#imgBox {
background: url('../public/logo.png');
}
需要在打包的时候处理一下。
webpack4:file-loader 和 url-loader
webpack4 常用的处理图片文件的 Loader 包含:
file-loader
:将图片原封不动地输出到构建输出的目录。- 解决打包后图片引入问题,会将图片 copy 到指定目录,默认为
dist
。 - 用于缓存资源的更新。
- 可以根据文件内容计算出一个哈希值作为文件名。
- hash 值变化时,意味着文件内容变化了。此时文件名发生改变,之前缓存的资源就失效了,会自动更新资源。
- 解决打包后图片引入问题,会将图片 copy 到指定目录,默认为
url-loader
:将小于指定大小的图片转换为base64
编码,减少 HTTP 请求的数量。url-loader
包含了file-loader
。- 当图片小于
limit
值时,会将图片转换为base64
编码。 - 大于
limit
值时仍然使用file-loader
进行拷贝。
img-loader
:压缩图片。
file-loader
的配置选项:
- 图片名字
name
- 默认值为:
[contenthash].[ext]
- 默认值为:
- 图片所在的文件夹
outputPath
和publicPath
webpack5 中使用 file-loader
/ url-loader
在 webpack5 中使用 file-loader
和 url-loader
会和内置的模块处理冲突:
1.dist
文件夹中多出一个显示不了的图片,并且构建后的 css 中引用的图片 url 指向这个显示不了的图片,导致在 html 中通过 css 引入的图片无法显示。
-
错误原因:
- css-loader 会默认转换 url 为 commonjs 模块:
url(image.png) => require('./image.png')
- 之后
file-loader
和 webpack5 中的asset
模块默认都会其进行处理,发生了冲突
- css-loader 会默认转换 url 为 commonjs 模块:
-
解决方式:
- 在使用旧的
assets loader
(如file-loader
/url-loader
/raw-loader
)和asset
模块时,需要停止asset
模块对资源的默认处理以免造成 asset 的重复。 - 可以通过将 assets 模块的类型设置为
type: 'javascript/auto'
实现。
- 在使用旧的
2.上述配置后, css 引用的图片 url 变成了 [Object%20Module]
,构建后图片依然显示不了。
- 错误原因:
file-loader
新版本默认使用了esModule
语法,造成了引用图片文件时的方式和以前的版本不一样css-loader
对 url 的处理是使用commonjs
语法
- 解决方式:
- 使
file-loader
不使用默认的esModule
语法。
- 使
module:{
rules:[
{
test: /\.(jpe?g|png|gif)$/i,
use: {
loader: 'file-loader',
options: {
//不使用 esModule 的语法导出, 解决 css 引入图片 url 变成 [object%20Module]
+ esModule: false,
name:'[name][hash:8].[ext]'
},
},
// 停止 webpack5 的 asset 模块对静态资源的默认处理。
+ type: 'javascript/auto',
},
]
}
webpack5: asset 模块
webpack5 已经将两个 loader 的功能内置到 webpack 里面了,只需要进行简单的配置即可。
module: {
rules: [
{
test: /\.(png|jpe?g|gif|webp|svg)$/i,
type: 'asset'
}
]
}
将小图片转换为 base64 :
- 减少 http 请求次数,减轻服务器的压力。
- 转换后资源大小会增大。
- 如果将大图片转换为 base64 会导致页面加载速度变慢
{
test: /\.(png|jpe?g|gif|webp|svg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
// 小于 10 kb 的图片转 base64
maxSize: 10 * 1024,
}
}
},
12. 修改输出文件目录
所有 bundles 的输出根目录可以通过 output
选项配置:
path
: 修改所有文件的输出路径filename
:入口文件打包输出时使用的文件名
指定资源的输出目录 / 文件名可以通过 loader
中的 generator
选项配置:
[name]
:原先的文件名[fullhash]
:根据文件计算出的一个哈希值- 也可以使用
[chunkhash]
/[contenthash]
- 也可以使用
[ext]
:文件原先的扩展名[query]
:请求携带的查询参数?a=b
{
test: /\.(png|jpe?g|gif|webp|svg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
// 小于 10 kb 的图片转 base64
maxSize: 10 * 1024,
}
},
generator: {
filename: "images/[name][contenthash:10][ext][query]"
}
},
13. 处理字体资源
type
使用 asset/resource
,相当于是之前的 file-loader
,直接将文件原封不动的输出,不需要转换为 Base64。
module: {
rules: [
{
test: /\.(ttf|woff2?)$/i,
type: "asset/resource",
generator:{
filename: "asset/fonts/[name].[contenthash:10][ext][query]"
}
}
],
}
14. 处理其他资源
只需要使用 type: "asset/resource"
原封不动的输出即可。
module: {
rules: [
{
test: /\.(mp3|mp4|avi)$/i,
type: "asset/resource",
generator:{
filename: "asset/resource/[name].[contenthash:10][ext][query]"
}
}
],
}
15. 处理 JavaScript 资源
webpack 对 JavaScript 的处理是有限的,只能编译 ES Module 模块化语法。
- 通常我们会通过
Babel
再做一些兼容性处理。 - 并通过
Eslint
来检查代码的格式。
Eslint
Eslint 是可组装的 JavaScript 和 JSX 检查工具。通过配置文件来定义代码规则。
① 配置文件
.eslintrc.*
需要位于项目根目录.eslintrc
.eslintrc.js
.eslintrc.json
package.json
中的eslintConfig
字段也可以进行配置。
以 .eslintrc.js
配置文件为例:
module.exports = {
// 解析选项
parserOptions: {
},
// 具体检查规则
rules: {
},
// 继承其他规则
extends: [],
// ...
}
-
parserOptions
解析选项:parserOptions: { // ES 语法版本 ecmaVersion: 6, // ES 模块化 sourceType: "module", // ES 其他特性 ecmaFeatures: { // react 项目需要开启 jsx: true } }
-
rules
具体规则:"off"
/0
:关闭规则。"warn"
/1
:开启规则。使用警告级别的错误warn
不会导致程序退出。"error"
/2
:开启规则。使用错误级别的错误error
会导致程序退出。
rules: { semi: "error", // 禁止使用分号 'array-callback-return': 'warn', // 强制数组方法的回调函数中有 return 语句,否则警告 'default-case': [ 'warn', // 要求 switch 语句中有 default 分支,否则警告 { commentPattern: 'no default$' } // 允许通过在最后注释 no default 消除警告 ], eqeqeq: [ 'warn', // 强制使用 === 和 !==,否则警告 'smart' // 少数情况下不会有警告 ] }
-
extends
继承:- 可以继承现有规则。
- 较为有名的规则:
eslint:recommended
Eslint 官方的规则plugin:vue/essential
Vue Cli 官方的规则react-app
React Cli 官方的规则
// .eslintrc.js
module.exports = {
// 继承 Eslint 规则
extends: ["eslint:recommended"],
env: {
node: true, // 启用 node 中的全局变量
browser: true, // 启用浏览器中的全局变量
},
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
},
rules: {
"no-var": 2, // 不能使用 var 定义变量
},
};
② webpack 配置 eslint 插件
eslint
以插件 ESLintWebpackPlugin
的形式配置,需要传入 options
选项:
context
:配置哪个根目录下的文件需要进行检查。
plugins: [
new ESLintWebpackPlugin({
context: path.resolve(__dirname, 'src'),
}),
]
配置 .eslintrcignore
文件,使 VSCode 的 Eslint 插件对 dist
目录下打包后的文件不进行代码格式检查。
Babel
JavaScript 编译器。用于将 ES6 语法编写的代码转换为向后兼容的 JavaScript 代码,以便能够运行在当前和旧版本的浏览器或其他环境中。
① 配置文件
babel.config.*
:位于项目根目录的一个文件babel.config.js
babel.config.json
.babelrc.*
:位于项目根目录的一个文件.babelrc
.babelrc.js
.babelrc.json
package.json
中的babel
:不需要创建文件,在原有文件的基础上写。
② 具体配置
以 babel.config.js
配置文件为例:
module.exports= {
// 预设
presets: []
}
presets
预设:一组 Babel 插件,扩展 Babel 的功能。@babel/preset-env
:一个智能预设,允许您使用最新的 JavaScript- 将 ES6+ 的语法编译为 ES5 的语法。
@babel/preset-react
:用来编译 React jsx 语法的预设。@babel/preset-typescript
:用来编译 TypeScript 语法的预设。- 预设可以加载一个或多个。
③ webpack 配置 babel-loader
npm i -D babel-loader @babel/core @babel/preset-env
配置 loader:
module: {
rules: [
// ...
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
// 在此处配置 or 通过新建一个文件 babel.config.js 进行配置。
// options: {
// presets: ["@babel/preset-env"]
// }
}
// ...
]
}
16. 启动 devServer
安装 webpack-dev-server
npm i webpack-dev-server -D
config 对象中的配置:
module.exports = {
// ...
module: {
...},
plugins: [...],
devServer: {
host: 'localhost',
// contentBase: webpack-dev-server version < 4.0.0 时使用 contentBase 替代 static 进行配置。
static: path.resolve(__dirname, 'public'), // 静态文件目录
compress: true, // 启动 gzip
port: 8080, // 端口号
open: true // 自动打开浏览器
},
// ...
}
启动本地服务:
npx webpack serve --mode=development
通过 devServer 启动,不会输出构建后的资源,是在内存中编译打包的。
配置 contentBase
/ static
使用 webpack 打包时,对静态文件(如图片)的处理都是直接复制到 dist
目录下面。对于本地开发来说,这个过程没有必要,太费时。
在设置 contentBase / static
之后,就可以直接到对应的静态资源目录下去读取文件,而无需对文件做任何移动,节省了时间和性能开销。
17. 区分环境
本地开发与部署上线有不同的需求:
- 本地环境
- 需要更快的构建速度
- 需要打印 debug 信息
- 需要
live reload
/HRM
的功能(热重载) - 需要
sourcemap
方便定位问题
- 生产环境
- 需要通过 代码压缩 +
tree-shaking
获得更小的包体积 - 需要进行代码分割
- 需要压缩图片体积
- 需要通过 代码压缩 +
针对不同的需求,需要进行环境的区分。可以通过两种方式进行区分:
① cross-env
-
本地安装
cross-env
npm i cross-env -D
-
配置启动命令
在
package.json
中配置scripts
:{ "scripts": { "dev": "cross-env NODE_ENV=dev webpack serve --mode development", "test": "cross-env NODE_ENV=test webpack --mode production", "build": "cross-env NODE_ENV=prod webpack --mode production" }, }
-
在 webpack 配置文件中获取环境变量
const HtmlWebpackPlugin = require('html-webpack-plugin') const path = require('path') + console.log('process.env.NODE_ENV=', process.env.NODE_ENV) // 打印环境变量 const devConfig = { + // mode: 'development', entry: './src/index.js', output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, module: { /* ... */ }, plugins: [ /* ... */ ], // ... } + module.exports = (env, argv) => { + console.log('argv.mode=', argv.mode) // 打印 mode 值 + switch(argv.mode) { + case 'development': return devConfig + case 'production': ... + } + }
-
测试
npm run build
npm run test
npm run dev
可以根据不同的环境动态修改 webpack 的配置。
② 两个配置文件
另一种区分环境的方式是通过创建两个文件: webpack.dev.js
和 webpack.prod.js
。
其中 webpack.dev.js
用于配置开发环境,webpack.prod.js
用于配置生产环境。
# 以开发环境执行
# 开发环境需要开启 devServer,因此需要有 serve
npx webpack serve --config webpack.dev.js
# 以生产环境执行
# 生产环境无需 devServer
npx webpack --config webpack.prod.js
两个环境的配置文件见下文。
18. 开发模式的配置
// webpack.dev.js
const ESLintWebpackPlugin = require('eslint-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const path = require('path')
const styleLoader = [
MiniCssExtractPlugin.loader, // 将 css 输出为一个单独的文件
'css-loader',
'postcss-loader' // 解决 css 兼容性问题,添加浏览器前缀
]
module.exports = {
// 运行代码是在根目录运行的,因此 entry 的相对路径不需要进行修改
// 绝对路径需要回退一个目录
entry: './src/index.js',
output: {
filename: 'bundle.js',
// 开发模式没有输出,因此 path 可以为 undefined
path: path.join(__dirname, '../dist'),
// clean: true
},
module: {
rules: [
// 样式资源
{
test: /\.css$/i,
exclude: /node_modules/,
use: [...styleLoader]
},
{
test: /\.s[ac]ss$/i,
exclude: /node_modules/,
use: [
...styleLoader,
'sass-loader'
]
},
{
test: /\.less$/i,
exclude: /node_modules/,
use: [
...styleLoader,
'less-loader'
]
},
// 图片资源
{
test: /\.(png|jpe?g|gif|webp|svg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
// 小于 10 kb 的图片转 base64
maxSize: 10 * 1024,
}
},
generator: {
filename: "images/[name].[contenthash:10][ext][query]"
}
},
// 字体资源
{
test: /\.(ttf|woff2?)$/i,
type: "asset/resource",
generator: {
filename: "asset/fonts/[name].[contenthash:10][ext][query]"
}
},
// 其他资源
{
test: /\.(mp3|mp4|avi)$/i,
type: 'asset/resource',
generator: {
filename: "asset/resource/[name].[contenthash:10][ext][query]"
}
},
// js 资源: babel 配置
{
test: /.js$/i,
exclude: /node_modules/,
loader: "babel-loader",
// 也可以通过 babel.config.js 进行配置
// options: {
// presets: ["@babel/preset-env"]
// }
}
]
},
plugins: [
new ESLintWebpackPlugin({
// context: 检测哪些文件
context: path.resolve(__dirname, '../src')
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../public/index.html')
}),
// require('postcss-preset-env'),
new MiniCssExtractPlugin({
filename: '[name].[hash:8].css'
}),
],
devServer: {
host: 'localhost',
port: 8080,
open: true, // 自动打开浏览器
compress: true, // 启用 gzip 压缩
// 静态文件目录,webpack < 4.0.0 使用 contentBase 代替
static: path.resolve(__dirname, "../public")
},
mode: 'development'
}
重命名为 webpack.dev.js
表示开发模式的配置
- 由于没有输出打包的文件,因此
output.path
可以是undefined
,并关闭output.clean
。 - 更改文件的目录之后,需要改写所有的绝对路径,而不需要改写
entry
的相对路径,因为代码是在根目录进行运行的。
以开发模式的配置运行:
npx webpack serve --config ./config/webpack.dev.js
19. 生产模式的配置
webpack.prod.js
表示生产模式的配置
- 开启
output.clean
。 - 不需要
devServer
。
// webpack.prod.js
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const ESLintWebpackPlugin = require('eslint-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const path = require('path')
const styleLoader = [
MiniCssExtractPlugin.loader, // 将 css 输出为一个单独的文件
'css-loader',
'postcss-loader' // 解决 css 兼容性问题,添加浏览器前缀
]
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, '../dist'),
clean: true
},
module: {
rules: [
// 样式资源
{
test: /\.css$/i,
exclude: /node_modules/,
use: [
...styleLoader
]
},
{
test: /\.s[ac]ss$/i,
exclude: /node_modules/,
use: [
...styleLoader,
'sass-loader'
]
},
{
test: /\.less$/i,
exclude: /node_modules/,
use: [
...styleLoader,
'less-loader'
]
},
// 图片资源
{
test: /\.(png|jpe?g|gif|webp|svg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
// 小于 10 kb 的图片转 base64
maxSize: 10 * 1024,
}
},
generator: {
filename: "images/[name].[contenthash:10][ext][query]"
}
},
// 字体资源
{
test: /\.(ttf|woff2?)$/i,
type: "asset/resource",
generator: {
filename: "asset/fonts/[name].[contenthash:10][ext][query]"
}
},
// 其他资源
{
test: /\.(mp3|mp4|avi)$/i,
type: 'asset/resource',
generator: {
filename: "asset/resource/[name].[contenthash:10][ext][query]"
}
},
// js 资源: babel 配置
{
test: /.js$/i,
exclude: /node_modules/,
loader: "babel-loader",
// 也可以通过 babel.config.js 进行配置
// options: {
// presets: ["@babel/preset-env"]
// }
}
]
},
plugins: [
new ESLintWebpackPlugin({
// context: 检测哪些文件
context: path.resolve(__dirname, '../src')
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../public/index.html')
}),
// require('postcss-preset-env'),
new MiniCssExtractPlugin({
filename: '[name].[hash:8].css'
}),
new CssMinimizerPlugin(),
],
// 生产模式不需要 devServer
mode: 'production'
}
以生产模式的配置运行:
npx webpack serve --config ./config/webpack.prod.js
20. 设置运行指令
设置 package.json
的 script
。
因为使用运行指令的方式时,.bin
默认也会添加到环境变量中,因此无需添加开头的 npx
。
"scripts": {
"start": "npm run dev",
"dev": "webpack serve --config ./config/webpack.dev.js",
"build": "webpack --config ./config/webpack.prod.js"
},