# 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)


---

# Agent Instructions: 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.2-npm-scripts.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.
