> 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.2-npm-scripts.md).

# 2.2 npm scripts

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

`package.json`文件中`scripts`属性指定了运行脚本命令的 npm 命令行缩写，各个脚本可以互相组合使用，这些脚本覆盖整个项目的生命周期（开发、测试、打包、部署）。

## 脚本使用注意事项

### 通配符

由于 npm 脚本就是 Shell 脚本，因为可以使用 Shell 通配符。

```js
"lint": "jshint *.js"
"lint": "jshint **/*.js"
```

上面代码中，`*` 表示任意文件名，`**` 表示任意一层子目录。

### 执行顺序

如果 npm 脚本里面需要执行多个任务，需要明确它们的执行顺序。如果是 **并行执行**（即同时的平行执行），使用`&`符号。

```bash
npm run script1.js & npm run script2.js
```

如果是 **继发执行**（即只有前一个任务成功，才执行下一个任务），使用 `&&` 符号。

```bash
npm run script1.js && npm run script2.js
```

***

`element` 项目定义了很多脚本，按照用途大致分为项目基础、文件构建、项目开发 、发布部署、项目测试等。 脚本命令调用 build 目录中的众多文件,自动完成大量重复性工作,从而减少人为错误、提高效率。下面将逐一分析讲解脚本命令的功能和作用。

> 关于 `/build` 目录下文件功能，本篇幅不做讲解，详见后续文章。

## 项目基础

### npm run bootstrap

自动下载项目所需的模块，也就是配置项目所需的运行和开发环境。官方推荐使用 `yarn`。

```js
"bootstrap": "yarn || npm i"
```

### npm run clean

清除打包/测试生成的目录及文件，主要有`lib`目录、`test\unit\coverage`目录（跟测试代码覆盖率有关，详见后文）以及`package\theme-chalk\lib`目录（跟主题有关，详见后文）。

```js
"clean": "rimraf lib &&
          rimraf packages/*/lib &&
          rimraf test/**/coverage"
```

> 需要安装 `rimraf` 包,用于递归删除目录所有文件。

### npm run eslint 代码质量检查

基于 `.eslintrc` 和 `.eslintignore` 文件配置，调用 `eslint` 检测代码规范。`--quiet`参数允报告错误,禁止报告警告。

```js
"lint": "eslint src/**/* test/**/* packages/**/* build/**/* --quiet"
```

项目使用自己封装的规则配置 `eslint-config-elemefe` , 配置使用请参考前文 [代码风格检查和格式化配置（ESlint ＆ Prettier）](https://juejin.cn/post/6951808773354684447#heading-4)。

```json
{
  "extends": "elemefe"
}
```

## 文件构建

### npm run i18n

执行 `build/bin/i18n.js` 基于 `examples/i18n/page.json`页面多语言配置和 `examples/pages/template` 目录下的所有模版文件，生成 `zh-CN`、`en-US`、`es`、`fr-FR`等四种语言的网站`.vue`文件。

```js
"i18n": "node build/bin/i18n.js",
```

### npm run build:file

该命令主要用于文件的自动化生成，其多个任务是 **并行执行**。

* 执行 `build/bin/iconInit.js` 生成 `examples/icon.json` 图标集合文件。
* 执行 `build/bin/build-entry.js` 生成 `src/index.js` 组件库入口文件。
* 执行 `build/bin/i18n.js` 生成官网的多语言网站文件。
* 执行 `build/bin/version.js` 生成 `examples/version.json` 记录项目版本信息，用于网站版头部导航版本切换。

```js
"build:file": "node build/bin/iconInit.js &
               node build/bin/build-entry.js &
               node build/bin/i18n.js &
               node build/bin/version.js"
```

### npm run build:theme

该命令主要用于项目的主题和样式生成。

1. 执行 `build/bin/gen-cssfile` 生成 `packages/theme-chalk/index.scss` 样式总入口文件。全量引入组件时，引用改样式如下 `import 'packages/theme-chalk/src/index.scss'`。
2. 采用 `gulp` 进行样式构建，将`packages/theme-chalk/src`下的 `scss` 文件转换成 `css` 文件，输出至`packages/theme-chalk/src/lib`目录下;将`packages/theme-chalk/src/fonts`下的字体文件压缩处理，输出至 `packages/theme-chalk/src/lib/fonts` 目录下。
3. 将构建内容 `packages/theme-chalk/lib` 拷贝到 `lib/theme-chalk` 下。前面 `sytle` 属性配置的路径文件 `lib/theme-chalk/index.css` 就是这样生成的。

```js
"build:theme": "node build/bin/gen-cssfile &&
                gulp build --gulpfile packages/theme-chalk/gulpfile.js &&
                cp-cli packages/theme-chalk/lib lib/theme-chalk",
```

> 需要安装 `cp-cli` 包,用于文件和文件夹复制,无需担心跨平台问题。

### npm run build:utils

该命令作用把 `src` 目录下除了 `src/index.js` 入口文件外的其他文件通过 `babel` 转译后，输出至 `lib` 文件夹下。

```js
"build:utils": "cross-env BABEL_ENV=utils babel src --out-dir lib --ignore src/index.js",
```

> 需要安装 `cross-env` 包,是一款运行跨平台设置和使用环境变量的脚本，不同平台使用唯一指令，无需担心跨平台问题。

### npm run build:umd

该命令作用是执行 `build/bin/build-locale.js` 通过 `babel` 处理 `src/locale/lang` 目录下的文件，生成 `umd` 格式的文件，输出至 `lib/umd/locale` 目录下。

```js
"build:umd": "node build/bin/build-locale.js",
```

## 项目开发

### npm run dev

该命令用于运行组件库的本地开发环境。

1. 执行命令`npm run bootstrap` 配置项目所需的运行和开发环境。
2. 执行命令`npm run build:file` 详解见前文，构建项目官网相关文件。
3. `webpack-dev-server` 提供一个本地服务(serve) 并运行项目网站(打包规则配置 `build/webpack.demo.js`);同时执行`build/bin/template.js`文件启动监听`examples/pages/template`目 录下模板文件，若内容发生变化，则重新生成网站文件。 webpack-dev-server 具有 live reloading 功能,网站内容会实时重新加载。

```js
"dev": "npm run bootstrap &&
        npm run build:file &&
            cross-env NODE_ENV=development webpack-dev-server --config build/webpack.demo.js &
            node build/bin/template.js",
```

### npm run dev:play

该命令用于组件库开发中的功能展示，运行效果如下图。

1. 执行命令`npm run build:file` 详解见前文，构建项目官网相关文件。
2. 由于配置了如下环境变量`NODE_ENV=development PLAY_ENV=true`,可以在`build/webpack.demo.js`打包文件中看到入口文件`examples/play.js`, `play.js` 引用 `examples/play/index.vue`, 可以引入组件库任意组件用于功能展示。

```js
"dev:play": "npm run build:file &&
            cross-env NODE_ENV=development PLAY_ENV=true webpack-dev-server --config build/webpack.demo.js",
```

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

## 发布部署

### npm run deploy:build

该命令作用主要是打包构建项目官网内容，为网站部署做准备。

1. 执行命令`npm run build:file` 详解见前文，构建项目官网相关文件。
2. `webpack --config build/webpack.demo.js` 基于 `production` 模式，打包生成内容输出至`examples/element-ui/`目录下。
3. `echo element.eleme.io>>examples/element-ui/CNAME` 往`examples/element-ui/CNAME`文件中写入`element.eleme.io` 。[Github Docs / Managing a custom domain for your GitHub Pages site](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site)

```js
"deploy:build": "npm run build:file &&
                 cross-env NODE_ENV=production webpack --config build/webpack.demo.js &&
                 echo element.eleme.io>>examples/element-ui/CNAME"
```

### npm run deploy:extension

该命令作用主要是打包构建主题编辑器的 chorme 插件项目--`Element Theme Roller` [官方商城地址](https://chrome.google.com/webstore/detail/element-theme-roller/lifkjlojflekabbmlddfccdkphlelmim?hl=zh-CN\&utm_source=chrome-ntp-launcher) 。基于 `production` 模式打包生成内容输出至 `examples/extension` 目录下。

```js
"deploy:extension": "cross-env NODE_ENV=production webpack --config build/webpack.extension.js",
```

使用该插件可以自定义全局变量和组件的所有设计标记，并实时预览新主题并基于新主题生成完整的样式包，以供直接下载

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

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

### 👉 npm run dist ⭐

该命令作用主要是构建组件库。

1. 执行命令`npm run clean`,详见上文;
2. 执行命令`npm run build:file`,详见上文;
3. 执行命令`npm run lint`,详见上文;
4. 执行打包`webpack --config build/webpack.conf.js`,入口文件 `src/index.js` 以 `umd` 格式输出到 `lib/index.js`;
5. 执行打包`webpack --config build/webpack.common.js`,入口文件 `src/index.js` 以`commonjs2`格式输出到 `lib/element-ui.common.js`;
6. 执行打包`webpack --config build/webpack.component.js`,入口文件 `components.json`,将`packages`目录下的组件，以`commonjs2`格式分别输出到`lib`目录,用于按需引入;
7. 执行命令`npm run build:utils`,详见上文;
8. 执行命令`npm run build:umd`,详见上文;
9. 执行命令`npm run build:theme`,详见上文。

```js
"dist": "npm run clean &&
         npm run build:file &&
         npm run lint &&
         webpack --config build/webpack.conf.js &&
         webpack --config build/webpack.common.js &&
         webpack --config build/webpack.component.js &&
         npm run build:utils &&
         npm run build:umd &&
         npm run build:theme",
```

### 👉 npm run pub ⭐

```js
"pub": "npm run bootstrap &&
        sh build/git-release.sh &&
        sh build/release.sh &&
        node build/bin/gen-indices.js",
```

该命令作用主要是组件库的发布、代码管理。

1. 执行命令`npm run bootstrap`,详见上文;
2. 运行 shell 脚本`sh build/git-release.sh`，检查代码 `dev` 分支是否存在冲突(No conflicts);
3. 运行 shell 脚本`sh build/release.sh`,合并 dev 分支到 master 分支、更新版本号、发布主题、push 代码到远程仓库、发布组件库至 NPM;
4. 执行文件`node build/bin/gen-indices.js`,提供 `algoliasearch` 搜索功能，需要把 `examples/docs` 目录下 `.md` 文件内容格式化后上传 `algolia`,效果详见下图 👇。

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

> 💁‍♂️ 在 `2.15.x` 版本，`pub` 命令移除了最后一条任务指令`sh build/deploy-faas.sh`，用于站点 <https://element.eleme.io> 的 `faas deploy`。

## 测试

实现项目自动化测试。

* karma 测试执行过程管理工具(Test Runner)。
* Mocha 是运行在 Node.js 和浏览器上的功能丰富的 JavaScript 测试框架。
* Chai 是一个用于 Node.js 和浏览器的 BDD/TDD 断言库，可以与任何 JavaScript 测试框架便捷配对。
* Sinon.JS 用于对 JavaScript 隔离测试 spy, stub 和 mock。适用于任何单元测试框架。

测试脚本命名方式为 `[组件名].spec.js` , 统一放在 `test/unit/specs/` 目录下。如果测试成功，`karma-coverage` 会在 `test/unit/coverage` 文件夹中生成测试覆盖率结果的网页。

### npm run test

```js
"test": "npm run lint &&
         npm run build:theme &&
         cross-env CI_ENV=/dev/ BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
```

该命令用于启动项目测试，设置了参数 `--single-run` 执行一次测试之后，karma 会自动停掉。

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

### npm run test:watch

```js
"test:watch": "npm run build:theme &&
               cross-env BABEL_ENV=test karma start test/unit/karma.conf.js"
```

该命令用于启动项目测试，执行结束后会继续监测文件是否变更，若发生变更，会重新执行一次测试。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f07ef8b369a24fac8e91108520816bca~tplv-k3u1fbpfcp-watermark.image)

## 关联阅读

点击以下链接，可以快速查看本系列其他文章：\
[专栏/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)
