工作原理
title: 工作原理
sort: 14
contributors:
- smelukov
- EugeneHlushko
- chenxsan
- amirsaeed671
本节描述 webpack 内部机制,对插件开发者可能会很有用。
打包(bundling)是一个函数,它接收一些文件并输出另一些文件。
但在输入和输出之间,它还有模块、入口点、chunk、chunk group 以及许多其他中间部分。
主要部分
项目中使用的每个文件都是一个模块
./index.js
js
import app from "./app.js";
./app.js
js
export default "the app";
通过相互引用,模块形成了一个图(graph)(ModuleGraph)。
在打包过程中,模块被合并成 chunk。
Chunk 再组合成 chunk group,并通过模块相互连接形成一个图(ChunkGraph)。
当你描述一个入口点时——在内部,你实际上创建了一个带有一个 chunk 的 chunk group。
./webpack.config.js
js
export default {
entry: "./index.js",
};
创建了一个名为 main 的 chunk group(main 是入口点的默认名称)。
这个 chunk group 包含 ./index.js 模块。当解析器处理 ./index.js 内部的导入时,新模块会被添加到该 chunk 中。
另一个例子:
./webpack.config.js
js
export default {
entry: {
home: "./home.js",
about: "./about.js",
},
};
创建了两个名为 home 和 about 的 chunk group。
每个 chunk group 都有一个包含模块的 chunk——home 对应 ./home.js,about 对应 ./about.js。
一个 chunk group 中可能有多个 chunk。例如 SplitChunksPlugin 会将一个 chunk 拆分成一个或多个 chunk。
Chunks
Chunk 有两种形式:
initial是入口点的主 chunk。此 chunk 包含你为入口点指定的所有模块及其依赖。non-initial是可以被懒加载的 chunk。它可能在使用动态导入或 SplitChunksPlugin 时出现。
每个 chunk 都有对应的资源(asset)。资源即输出文件——打包的结果。
webpack.config.js
js
export default {
entry: "./src/index.jsx",
};
./src/index.jsx
jsx
import { createRoot } from "react-dom/client";
import("./app.jsx").then((App) => {
const root = createRoot(document.getElementById("root"));
root.render(<App />);
});
创建了名为 main 的 initial chunk。它包含:
./src/index.jsxreactreact-dom
以及它们的所有依赖,但不包括 ./app.jsx。
因为 ./app.jsx 是动态导入的,所以会为它创建一个 non-initial chunk。
输出:
/dist/main.js- 一个initialchunk/dist/394.js-non-initialchunk
默认情况下,non-initial chunk 没有名称,因此会使用唯一 ID 代替名称。
使用动态导入时,我们可以通过“magic”注释显式指定 chunk 名称:
jsx
import(
/* webpackChunkName: "app" */
"./app.jsx"
).then((App) => {
const root = createRoot(document.getElementById("root"));
root.render(<App />);
});
输出:
/dist/main.js- 一个initialchunk/dist/app.js-non-initialchunk
输出
输出文件的名称受配置中两个字段的影响:
output.filename- 用于initialchunk 文件output.chunkFilename- 用于non-initialchunk 文件- 在某些情况下,chunk 可同时用于
initial和non-initial。此时会使用output.filename。
这些字段中可以使用一些占位符。最常用的有:
[id]- chunk id(例如[id].js->485.js)[name]- chunk 名称(例如[name].js->app.js)。如果 chunk 没有名称,则会使用其 id[contenthash]- 输出文件内容的 md4 哈希(例如[contenthash].js->4ea6ff1de66c537eb9b2.js)
帮助我们改进文档
发现翻译问题或内容错误?请告诉我们。
