webpack 是一个 JavaScript 模块打包器📦。它历经多次大版本升级,当前大版本 v5.0.0 的上线时间是 2020 年 10 月 10 日。
当前最新版本是 5.68.0。最低 Node.js 版本是 v10.13.0。
$ pnpm view webpack version
5.68.0
$ pnpm view webpack engines
{ node: '>=10.13.0' }
简单例子
// src/index.js
import answer from './bar.js';
answer();
// src/bar.js
export default function answer() {
console.log(42);
}
编写配置文件 webpack.config.js:
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
}
}
本地安装 webpack 和 webpack-cli:
$ pnpm init -y
$ pnpm add webpack webpack-cli --save-dev
编译打包:
$ pnpm webpack
asset bundle.js 4.09 KiB [emitted] (name: main)
runtime modules 670 bytes 3 modules
cacheable modules 100 bytes
./src/index.js 42 bytes [built] [code generated]
./src/bar.js 58 bytes [built] [code generated]
webpack 5.68.0 compiled successfully in 101 ms
$ node dist/bundle.js
42
核心概念
- 输入(Entry),设定入口文件,可以有多个
- 输出(Output),设定输出目录和文件名
- 加载器(Loaders),用于将任意类型文件转换为 JS 代码
- 插件(Plugins),自定义 webpack 各种行为
- 模式(Mode),针对不同环境设定不同的优化特性
- 浏览器兼容性(Browser Compatibility),支持 IE8+
素材管理
加载 CSS
安装 style-loader 和 css-loader 后,就可以从 JS 模块中使用 import 加载 CSS 文件。
$ pnpm add style-loader css-loader --save-dev
webpack.config.js
module.exports = {
...
+ module: {
+ rules: [
+ {
+ test: /\.css$/i,
+ use: ['style-loader', 'css-loader'],
+ },
+ ],
+ }
}
模块加载器可以串联。模块加载器从右向左依次执行(即逆序执行 ⬅️)。上面的例子中,先执行 css-loader,再执行 style-loader。它俩的先后顺序不能乱,否则会报错。
配置好 CSS 加载器,就可以在 JS 代码中导入 CSS 文件。最终页面会生成 <style> 样式标签。
// src/index.js
import './style.css';
加载图像
对于背景图像或图标等文件,在 webpack 5 中可以使用内置的素材模块(Asset Modules)轻松搞定。
素材模块是一种处理素材文件(字体、图表等)的模块,无需配置加载器。在 webpack 5 之前,通常会使用
raw-loader,url-loader或file-loader完成同样的功能。
webpack.config.js
module: {
rules: [
+ {
+ test: /\.(png|svg|jpg|jpeg|gif)$/i,
+ type: 'asset/resource',
+ },
]
}
此时执行 import MyImage from './my-image.png',这个图像被处理后会进入 output 目录,并且 MyImage 变量包含处理后的最终 url 地址。
加载字体
素材模块可以处理任意文件类型,因此字体文件也可以使用同样的处理方法。
// webpack.config.js
rules: [
+ {
+ test: /\.(woff|woff2|eot|ttf|otf)$/i,
+ type: 'asset/resource',
+ },
]
然后,就可以使用 @font-face 声明字体。
@font-face {
font-family: 'MyFont';
src: url('./my-font.woff2') format('woff2'),
url('./my-font.woff') format('woff');
font-weight: 600;
font-style: normal;
}
.hello {
color: red;
font-family: 'MyFont';
background: url('./icon.png');
}
加载数据
另一个常用的素材是数据文件,比如 JSON、CSV、TSV 和 XML。JSON 开箱即用,即可以直接使用 import Data from './data.json'。如果要导入 CSV、TSV 和 XML 文件,需要安装 csv-loader 和 xml-loader:
$ pnpm add csv-loader xml-loader --save-dev
webpack.config.js
rules: [
+ {
+ test: /\.(csv|tsv)$/i,
+ use: ['csv-loader'],
+ },
+ {
+ test: /\.xml$/i,
+ use: ['xml-loader'],
+ }
]
此时,就可以在 js 中加载数据文件:
// src/index.js
import Data from './data.xml';
import Notes from './data.csv';
console.log(Data);
console.log(Notes);
自定义 JSON 模块解析器
对于 toml、yaml 或 json5 等数据类型文件,可以通过自定义 JSON 模块解析器加载,无需特定的 webpack 加载器。
首先,安装各自解析器:
$ pnpm add toml yamljs json5 --save-dev
修改配置文件 webpack.config.js:
+ const toml = require('toml');
+ const yaml = require('yamljs');
+ const json5 = require('json5');
// ...
rules: [
+ {
+ test: /\.toml$/i,
+ type: 'json',
+ parser: { parse: toml.parse }
+ },
+ {
+ test: /\.yaml$/i,
+ type: 'json',
+ parser: { parse: yaml.parse }
+ },
+ {
+ test: /\.json5$/i,
+ type: 'json',
+ parser: { parse: json5.parse }
+ },
]
参考文献
- webpack 官方文档
- Webpack 5 release (2020-10-10) | webpack