> 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.6-zhu-ti-ce-shi-ge-shi-hua.md).

# 2.6 主题、测试、格式化

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

本文介主题构建、自动化测试、代码质量检查、类型声明。

## 项目主题

### 📁 packages/theme-chalk

项目主题 `theme-chalk` 是一个独立的项目,通过 `gulp` 打包构建生成，支持单独发布。 [ElementUI/theme-chalk 仓库地址](https://github.com/ElementUI/theme-chalk)

`packages/theme-chalk` 下放有字体文件，scss 相关变量、mixin 及公共样式设置，各 UI 组件对应的 scss 文件。项目目录结构如下 👇：

```bash
├─gulpfile.js               # 帮助gulp实现自动化管理项目功能
├─package.json
├─src
|  ├─reset.scss             # 重置浏览器的默认属性
|  ├─index.scss             # 样式入口文件
|  ├─base.scss              # 基础 引入动画 、图标样式
|  ├─icon.scss              # 图标样式
...
|  ├─button.scss            # 组件对应单独的scss文件
|  ├─upload.scss            # 组件对应单独的scss文件
...
|  ├─mixins                 # 混入(mixin)定义
|  |   ├─config.scss        # 变量
|  |   ├─function.scss      # 自定义函数 @fuction
|  |   ├─mixins.scss        # 支持接收参数
|  |   ├─utils.scss         # 公共样式
|  |   └button.scss         # 按钮公共样式
|  ├─fonts  # 字体图标
|  ├─date-picker            # 日期时间选择器样式
|  ├─common
|  |   ├─transition.scss    # 动画
|  |   └var.scss            # 主题sass变量
├─lib                       # 打包输出目录
```

### @mixin 与 @include

`@mixin` 指令允许我们定义一个可以在整个样式表中重复使用的样式。

`@include` 指令可以将混入（mixin）引入到文档中。

混入(mixin)通过 @mixin 指令来定义。创建一个名为 "important-text" 的混入：

```css
@mixin important-text {
  color: red;
  font-size: 25px;
  font-weight: bold;
  border: 1px solid blue;
}
```

@include 指令可用于包含一混入,包含 important-text 混入代码如下：

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

```css
/* @include实例 */
.danger {
  @include important-text;
  background-color: green;
}
将以上代码转换为 CSS 代码，如下所示：

/* 转换为 CSS 代码 */
.danger {
  color: red;
  font-size: 25px;
  font-weight: bold;
  border: 1px solid blue;
  background-color: green;
}
```

### 主题构建

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

#### 1️⃣ 生成入口文件

`build/bin/gen-cssfile` 找到 `components.json`， 获取组件列表，找到`packages/theme-chalk/src`目录下对应的各组件的 `component-name.scss` 文件，以`@import "./component-name.scss"`的形式，写入`packages/theme-chalk/index.scss`文件-样式总入口文件。若是组件对应的样式不存在，会自动创建遗漏的样式文件。

#### 2️⃣ 构建主题

`gulp`是一种基于流(stream)的自动化构建工具，`gulpfile.js` 定义两个任务(task):

* 将`packages/theme-chalk/src`目录下的 scss 文件转换成 css 文件，输出至`packages/theme-chalk/src/lib`目录下;
* 将`packages/theme-chalk/src/fonts`目录下的字体图标文件压缩处理，输出至 `packages/theme-chalk/src/lib/fonts` 目录下。

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

#### 3️⃣ 拷贝至 lib/theme-chalk 下

通过`cp-cli`，将`packages/theme-chalk/src/lib`目录下文件拷贝至`lib/theme-chalk`目录下。

## 项目测试

### test\ssr\require.test.js

SSR 引入类库(require)测试, `build\release.sh`文件执行 `node test/ssr/require.test.js` 命令。

```js
const path = require("path");

try {
  process.env.VUE_ENV = "server";
  require(path.join(process.env.PWD, "./lib/index"));
  console.log("SSR require test PASS");
} catch (e) {
  console.error("SSR require test error");
  throw Error(e);
}
```

### 📁 test/unit 单元测试

项目通过执行 `npm run test` `npm run test:watch` 运行单元测试，使用如下技术：

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

目录结构如下 👇：

```js
├─index.js			    # 入口文件
├─karma.conf.js			    # karma配置
├─util.js                           # 公共方法
├─specs                             # 测试用例
|   ├─alert.spec.js                 # 测试用例脚本 [组件名].spec.js
|   ├─button.spec.js
...
...
|   ├─upload.spec.js
|   ├─util.clickoutside.spec.js
|   └util.vue-popper.spec.js
├─mocks                             # 模拟数据
|   └uri.js
├─coverage                          # 测试覆盖率报告
|    ├─lcov.info                    # 报告信息
|    ├─lcov-report                  # 报告网站
```

`karma.conf.js` 测试配置信息。

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

`index.js` 测试入口文件，单元测试默认测试 `src` 目录下除了 main.js 之外的所有文件，根据实际情况调整测试范围。

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

测试脚本命名方式为 `[组件名].spec.js` , 统一放在 `test/unit/specs/` 目录下，语法结构如下 👇。

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

如果测试成功，终端输出测试覆盖率概览 👇。

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

同时`karma-coverage` 会在 `test/unit/coverage` 文件夹中生成测试覆盖率结果的概览信息`lcov.info`和网页 `lcov-report/**`。

生成测试覆盖率结果的网站,在浏览其中打开，内容如下 👇：

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

## 代码质量检查

element 使用了 `eslint` 进行代码风格检测，辅助编码规范执行，有效控制代码质量，实现项目代码风格统一。 编写发布了 eslint 的扩展规则配置-- [eslint-config-elemefe](https://www.npmjs.com/package/eslint-config-elemefe) 。

`eslint` 所能提供的格式化功能很有限；而 `prettier` 在格式化代码方面具有更大优势。可以集成 `prettier` 负责格式限制、自动格式化，详细配置参考[代码风格检查和格式化配置（ESlint ＆ Prettier）](https://juejin.cn/post/6951808773354684447)。

## 类型声明

`types` 目录存放组件的 `TypeScript` 声明文件，以 `.d.ts` 后缀结尾。提升`typescript` 项目中引入组件库的开发体验，需要在 `package.json` 中指定 `typing` 属性的值， 声明的入口文件才能生效。

```json
{
  "typings": "types/index.d.ts"
}
```

## 关联阅读

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