知海

工作原理

webpackjsorg-main核心概念

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",
  },
};

创建了两个名为 homeabout 的 chunk group。
每个 chunk group 都有一个包含模块的 chunk——home 对应 ./home.jsabout 对应 ./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.jsx
  • react
  • react-dom

以及它们的所有依赖,但不包括 ./app.jsx

因为 ./app.jsx 是动态导入的,所以会为它创建一个 non-initial chunk。

输出:

  • /dist/main.js - 一个 initial chunk
  • /dist/394.js - non-initial chunk

默认情况下,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 - 一个 initial chunk
  • /dist/app.js - non-initial chunk

输出

输出文件的名称受配置中两个字段的影响:

  • output.filename - 用于 initial chunk 文件
  • output.chunkFilename - 用于 non-initial chunk 文件
  • 在某些情况下,chunk 可同时用于 initialnon-initial。此时会使用 output.filename

这些字段中可以使用一些占位符。最常用的有:

  • [id] - chunk id(例如 [id].js -> 485.js
  • [name] - chunk 名称(例如 [name].js -> app.js)。如果 chunk 没有名称,则会使用其 id
  • [contenthash] - 输出文件内容的 md4 哈希(例如 [contenthash].js -> 4ea6ff1de66c537eb9b2.js

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。