> For the complete documentation index, see [llms.txt](https://anduril.gitbook.io/learning-element/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://anduril.gitbook.io/learning-element/chapter02_fee/2.4-da-bao-pei-zhi.md).

# 2.4  打包配置

> 原文地址： <https://juejin.cn/post/6970691644114862111/>

本文将介绍项目的打包配置功能。

> 🚨 项目中 `webpack` 版本为 `4.X`,文中涉及语法、功能与最新版本`5.X`相比存在变化。

## 📝 commonjs vs commonjs2

接下来配置 `libraryTarget`的选项中可以看到'commonjs'、'commonjs2'。两者之前的有什么区别？

`commonjs` 规范只定义了`exports`， 而 `module.exports` 是`nodejs`对`commonjs`的实现， 这种扩展实现称为`commonjs2`。

```js
// commonjs
exports.a = "a";
exports.b = "b";

// commonjs2
module.exports = {
  a: "a",
  b: "b",
};
```

> 参考<https://github.com/webpack/webpack/issues/1114>

## build/config.js

文件内容是打包配置的公用配置。

![carbon (40).png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a3bc6f626563436bbce2043a7d0fa726~tplv-k3u1fbpfcp-watermark.image)

**外部扩展(externals)** 从输出的 bundle 中排除依赖,在运行时(runtime)从外部获取这些扩展依赖(external dependencies),主要解决组件依赖导致代码冗余问题。其中 `exports.externals = externals;` 内容格式如下 👇。

![carbon (41).png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9c501fd42a6041f4a85f772119dc766b~tplv-k3u1fbpfcp-watermark.image)

## build/webpack.common.js

以 `commonjs2` 规范打包构建类库。

* 调用命令：`webpack --config build/webpack.common.js`。
* 入口文件：`src/index.js`。
* 输出文件：以`commonjs2`规范构建输出到`lib/element-ui.common.js`（类库主入口文件）。

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/612da87133b9430085bcafbe20b385b8~tplv-k3u1fbpfcp-watermark.image)

## build/webpack.component.js

以 `commonjs2` 规范对每个组件单独打包构建，支持按需引入。

* 调用命令：`webpack --config build/webpack.component.js`。
* 入口文件：`components.json`中的组件列表。
* 输出文件：把`packages`目录下的组件，以`commonjs2`规范单独构建输出到`lib/components-name.js`。

![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/602333ddab9749dba68587da0ebf70f4~tplv-k3u1fbpfcp-watermark.image)

## build/webpack.conf.js

以 `umd` 规范打包构建类库,不仅可以 NodeJs 环境使用，也可以在浏览器环境（browser）使用，需要设置`umdNamedDefine: true`。

* 调用命令：`webpack --config build/webpack.conf.js`。
* 入口文件：`src/index.js`。
* 输出文件：以`umd`规范构建输出到`lib/index.js`。

![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c6a1f63d887b47f1972302128c4b8b01~tplv-k3u1fbpfcp-watermark.image)

### externals 配置

通过这种方式引入的依赖库，不会打包到 bundle 中。以下任何一种形式在各种模块上下文使用：

* `root`：可以通过一个全局变量访问 library（例如，通过 script 标签）。
* `commonjs`：可以将 library 作为一个 CommonJS 模块访问。
* `commonjs2`：和上面的类似，但导出的是 module.exports.default。
* `amd`：类似于 commonjs，但使用 AMD 模块系统。

一个形如 `{ root, amd, commonjs, ... }` 的对象仅允许用 `libraryTarget: 'umd'` 这样的配置.

```json
  // 防止将某些 import 的包(package)打包到 bundle 中，
  // 在运行时(runtime)再去从外部获取这些扩展依赖
  externals: {
    // config.vue
    // {
    //   root: 'Vue',
    //   commonjs: 'vue',
    //   commonjs2: 'vue',
    //   amd: 'vue'
    // }
    vue: config.vue
  },
```

生成`lib\index.js`中，依赖库`vue`引入声明代码如下：

```js
(function webpackUniversalModuleDefinition(root, factory) {
  if (typeof exports === "object" && typeof module === "object")
    module.exports = factory(require("vue"));
  else if (typeof define === "function" && define.amd)
    define("ELEMENT", ["vue"], factory);
  else if (typeof exports === "object")
    exports["ELEMENT"] = factory(require("vue"));
  else root["ELEMENT"] = factory(root["Vue"]);
});
```

## build/webpack.demo.js

提供了两套打包配置，生产模式用于项目网站的构建，开发模式用于组件展示测试的构建。使用了 CSS、JS 构建的优化插件，还配置 `splitChunks`抽取公共模块解决重复引入第三方库的问题。

`npm run deploy:build` 命令打包构建项目网站。

* 调用命令：`webpack --config build/webpack.demo.js`。
* 模式：`production`。
* 入口文件：`examples/entry.js`。
* 输出文件：构建内容输出至`examples/element-ui/`目录下。

`npm run deploy:build` 命令打包运行项目网站，用于开发调试。

* 调用命令：`webpack-dev-server --config build/webpack.demo.js`。
* 模式：`development`。
* 入口文件：`examples/entry.js`。
* 输出文件：构建内容输出至`examples/element-ui/`目录下。

`npm run dev:play` 命令用于组件库开发中的功能展示。

* 调用命令：`webpack-dev-server --config build/webpack.demo.js`。
* 模式：`development`。
* 入口文件：`examples/entry.js`。
* 输出文件：构建内容输出至`examples/element-ui/`目录下。

![carbon (37).png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d7f26ca78c784c1b937eaf3d2d06f78c~tplv-k3u1fbpfcp-watermark.image)

## build/webpack.extension.js

用于构建名为`Element Theme Roller`的 chorme 插件项目，复用大部分 `webpack.demo.js` 打包配置。`npm run deploy:extension`用于项目生产发布；`npm run dev:extension`用于开发调试。

* 调用命令：`webpack --config build/webpack.extension.js`。
* 入口文件：`examples/extension/src/background.js`和`examples/extension/src/entry.js`。
* 输出文件：构建内容输出至`examples/extension/dist`目录下。生成文件 `background.js` `entry.js` ,复制文件 `icon.png` `manifest.json` 。

![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6df65cf49575421e9b00266621ae3670~tplv-k3u1fbpfcp-watermark.image)

## build/webpack.test.js

用于 `test/unit/karma.conf.js` 中打包配置。

```js
// test/unit/karma.conf.js
const webpackConfig = require('../../build/webpack.test');

module.exports = function(config) {
  const configuration = {
    ...
    webpack: webpackConfig,
    ...
  };

  config.set(configuration);
};
```

## 关联阅读

点击以下链接，可以快速查看本系列其他文章：\
[专栏/Element 2.X 源码学习](https://juejin.cn/column/6961321064110489631)

👇 项目工程化系列文章链接如下，推荐按照顺序阅读文章 👇。

1️⃣ [源码剖析之工程化：项目概览、package.json、npm script](https://juejin.cn/post/6969258163136626725)\
2️⃣ [源码剖析之工程化：项目构建、MD 解析](https://juejin.cn/post/6969933702759940133)\
3️⃣ [源码剖析之工程化：打包配置](https://juejin.cn/post/6970691644114862111/)\
4️⃣ [源码剖析之工程化：发布部署、持续集成](https://juejin.cn/post/6971054455139598366/)\
5️⃣ [源码剖析之工程化：主题构建、自动化测试、代码质量检查、类型声明](https://juejin.cn/post/6971434343516340238)\
6️⃣ [源码剖析之工程化：项目网站](https://juejin.cn/post/6972180649625157645)\
7️⃣ [源码剖析之工程化：命令之图解](https://juejin.cn/post/6991347082552573965)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://anduril.gitbook.io/learning-element/chapter02_fee/2.4-da-bao-pei-zhi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
