webpack 5 快速入门(1):素材管理

278 阅读2分钟

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',
    }
}

本地安装 webpackwebpack-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-loadercss-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-loaderfile-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-loaderxml-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 模块解析器

对于 tomlyamljson5 等数据类型文件,可以通过自定义 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 }
+    },
]

参考文献