> 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.7-xiang-mu-wang-zhan.md).

# 2.7 项目网站

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

本文介绍项目网站结构和文件功能。项目官网支持国际化支持四种语言，提供了指南（设计原则）、组件（文档功能展示）、主题（在线定制）、资源（Axure Sketch）等四大模块。

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

## 📁 examples 目录结构

组件库的网站项目存放在 `examples` 目录下，网站项目有两个入口，`entry.js` 和 `play.js` 。

```bash
├─entry.js              # 网站项目入口
├─app.vue               # 根组件
├─bus.js                # 事件总线（EventBus） 用于组件之间的数据通信
├─color.js              # 调整颜色的亮度
├─favicon.ico           # webpack.demo.js打包生成网站时favicon
├─icon.json             # icon名称数组 build/bin/iconInit.js生成
├─index.tpl             # webpack.demo.js打包生成网站时页面依赖文件模板
├─nav.config.json       # 网站组件页面的左侧边导航菜单配置
├─play.js               # 组件库开发中的功能展示入口文件
├─route.config.js       # 生成网站路由配置。
├─util.js               # 公共方法用于页面内容提取 examples\components\demo-block.vue 引用
├─versions.json         # 组件页面头部导航版本切换
├─play                  # 用于开发组件演示
|  └index.vue
├─pages                 # 网站模板配置以及生成多语言页面
├─i18n                  # 国际化 支持语言配置 翻译文件
├─extension             # 主题编辑器chrome 插件打包输出目录
├─element-ui            # 项目静态网站打包输出目录
├─dom                   # 定义了 dom class 操作方法
|  └class.js
├─docs                  # 组件文档目录，默认提供了四种语言的文档
├─demo-styles           # 组件页面中 组件demo的样式
├─components            # 官网项目存放一些全局组件的目录。
├─assets                # 静态资源目录
```

接下来将详细介绍各文件和目录的功能。

## 👉 entry.js

网站项目的入口,配置和导入所需资源。

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

## play.js & play/index.vue

组件库开发中的功能展示入口文件 该命令用于组件库开发中的功能展示。执行命令`npm run dev:play`，`build/webpack.demo.js` 打包入口文件`examples/play.js`, 引用 `examples/play/index.vue`, 可以引入组件库任意组件用于功能展示。

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

组件展示效果如下 👇。

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

## nav.config.json

网站组件页面的左侧导航菜单多语言配置，菜单层级最深为 3 级，对应关系查看下图 👇。

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

创建新组件时， 运行`build/bin/new.js`文件更新 `nav.config.json`，添加新组件导航信息,更新至`{"name": "组件","groups": [...]}` 。

## route.config.js

生成网站多语言路由配置。组件页面的左侧导航路由系统动态引入`nav.config.json`生成。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5a4dcbfb88bb4f858def04eef024d911~tplv-k3u1fbpfcp-watermark.image)

## index.tpl & favicon.ico

`webpack.demo.js` 打包生成网站时页面依赖文件模板以及网站 favicon。

```js
new HtmlWebpackPlugin({
  // 指定生成的文件所依赖文件模板
  template: './examples/index.tpl',
  filename: './index.html',
  favicon: './examples/favicon.ico'
}),
```

## 📁 pages

网站页面模板文件存在`examples/pages/template` 目录下，以及各语言对应的网站文件。

```bash
├─pages
|   ├─template                  # 网站页面模板
|   |    ├─changelog.tpl        # 更新日志
|   |    ├─component.tpl        # 组件模板
|   |    ├─design.tpl           # 指南/设计原则
|   |    ├─guide.tpl            # 指南
|   |    ├─index.tpl            # 首页
|   |    ├─nav.tpl              # 指南/导航
|   |    ├─resource.tpl         # 资源
|   |    ├─theme-nav.tpl        # 主题 router-view
|   |    ├─theme-preview.tpl    # 主题查看
|   |    └theme.tpl             # 主题管理
|   ├─zh-CN                     # 对应语言的网站.vue页面
|   |   ├─changelog.vue
|   |   ├─component.vue
|   |   ├─design.vue
|   |   ├─guide.vue
|   |   ├─index.vue
|   |   ├─nav.vue
|   |   ├─resource.vue
|   |   ├─theme-nav.vue
|   |   ├─theme-preview.vue
|   |   └theme.vue
|   ├─fr-FR
|   ├─es
|   ├─en-US
```

通过运行脚本`build/bin/i18n.js`,基于 `examples/i18n/page.json` 和 `examples/pages/template` 目录下模版文件，生成对应语言的.vue 文件 。

运行 `build/bin/template.js` 监听`examples/pages/template`目录下模板文件是否发生改变，若存在变化会自动执行命令`npm run i18n`，运行文件`build/bin/i18n.js`，重新生成网站文件。

## 📁 i18n

网站的国际化设置，支持语言和语言翻译文件。当使用 `make new-lang fr`指令添加新语言时，`build/bin/new-lang.js` 会将语言配置新增至 `components.json`、`page.json`、`route.json`等文件中 。

```bash
├─i18n
|  ├─component.json     # 组件页面的语言翻译文件
|  ├─page.json              # 除组件外的页面语言翻译文件
|  ├─route.json             # 路由国际化支持语言设置
|  ├─theme-editor.json      # 主题编辑器语言翻译文件
|  └title.json              # 页面title语言翻译文件
```

## 📁 docs

存放多语言组件文档，国际化默认支持四种语言,文档目录结构如下：

```bash
├─docs
|  ├─examples/docs/zh-CN/{component-name}.md
|  ├─examples/docs/en-US/{component-name}.md
|  ├─examples/docs/es/{component-name}.md
|  ├─examples/docs/fr-FR/{component-name}.md
```

`build\webpack.demo.js`打包时通过路由配置(route.config.js)加载`docs/{lang}/{component-name}.md`文件，使用自定义的 `markdown-loder`进行处理，生成 vue 文件，渲染成页面。同时页面调用组件 `components/demo-block.vue`生成具有交互体验的组件 Demo。

各组件文档无需手动创建，皆可自动创建(内容需要手动编辑)。当使用`make new component-name`指令创建新组件 package 时，`build/bin/new.js`会自动创建多语言组件文档 `examples/docs/{lang}/{component-name}.md`。

当使用 `make new-lang fr`指令添加新语言时，`build/bin/new-lang.js` 会在 `docs` 下新建对应文件夹 `examples/docs/{new-lang}`。

## 📁 assets

静态资源目录,存放网站图片资源、公共样式、字体图标样式。

```js
// entry.js 样式引用
import "./assets/styles/common.css";
import "./assets/styles/fonts/style.css";
```

## 📁 components

用于网站页面公共组件，主要包含页眉(header) 、页脚/导航(footer footer-nav) 、 侧边导航(side-nav)、 搜索(search)。

```js
├─footer-nav.vue
├─footer.vue
├─header.vue
├─search.vue
├─side-nav.vue
```

用于主题查看、管理的组件

```bash
├─theme-picker.vue
├─theme-configurator
├─theme
```

### demo-block.vue

`examples/components/demo-block.vue` 在组件文档中解析中被调用生成生成具有交互体验的组件 Demo。支持代码示例渲染、代码块语法高亮查看、codepen 在线运行等功能。

![a\_gaitubao\_662x373.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/14ea3089903c44f6bccee1d075f758d8~tplv-k3u1fbpfcp-watermark.image)

## 📁 demo-style

组件文档页面中使用 `components/demo-block.vue` 组件的 demo 样式 。 总入口文件 `examples/demo-styles/index.scss`。

```js
// entry.js 样式引用
import "./demo-styles/index.scss";
```

## color.js

提供调整颜色的亮度方法 `tintColor`。**Color 色彩** 页面 `examples\docs\{lang}\color.md` 引入方法用于生成调色板（Palette）。

```js
import { tintColor } from '../../color.js';
...

<el-row :gutter="12">
  <el-col :span="10" :xs="{span: 12}">
    <div class="demo-color-box" :style="{ background: primary }">Brand Color
      <div class="value">#409EFF</div>
      <div class="bg-color-sub" :style="{ background: tintColor(primary, 0.9) }">
        <div
          class="bg-blue-sub-item"
          v-for="(item, key) in Array(8)"
          :key="key"
          :style="{ background: tintColor(primary, (key + 1) / 10) }"
        ></div>
      </div>
    </div>
  </el-col>
</el-row>
```

根据主色生成不同亮度的色彩，效果如下 👇。

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

## versions.json

由 `build/bin/version.js` 生成。`examples\components\header.vue` 用于组件页面头部导航的版本选择。

```js
// examples\components\header.vue
<!-- 版本选择器 -->
<li class="nav-item nav-versions" v-show="isComponentPage">
    <el-dropdown
        trigger="click"
        class="nav-dropdown"
        :class="{ 'is-active': verDropdownVisible }">
        <span>
        {{ version }}
        <i class="el-icon-arrow-down el-icon--right"></i>
        </span>
        <el-dropdown-menu
        slot="dropdown"
        class="nav-dropdown-list"
        @input="handleVerDropdownToggle">
        <el-dropdown-item
            v-for="item in Object.keys(versions)"
            :key="item"
            @click.native="switchVersion(item)">
            {{ item }}
        </el-dropdown-item>
        </el-dropdown-menu>
    </el-dropdown>
</li>
<script>
created() {
    // ajax 方法请求   好古老的写法
    const xhr = new XMLHttpRequest();
    xhr.onreadystatechange = _ => {
    if (xhr.readyState === 4 && xhr.status === 200) {
        const versions = JSON.parse(xhr.responseText);
        this.versions = Object.keys(versions).reduce((prev, next) => {
        prev[next] = versions[next];
        return prev;
        }, {});
        console.log(this.versions);
    }
    };
    xhr.open('GET', '/versions.json');
    xhr.send();
}
</script>
```

## dom/class.js

定义了 dom class 操作方法 。

```js
// 指定 dom 上是否含有某个 class 类名
export const hasClass = function (obj, cls) {
  return obj.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
};
// 添加class类名
export const addClass = function (obj, cls) {
  if (!hasClass(obj, cls)) obj.className += " " + cls;
};
// 移除class类名
export const removeClass = function (obj, cls) {
  if (hasClass(obj, cls)) {
    const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
    obj.className = obj.className.replace(reg, " ");
  }
};
// 对添加和移除被选元素的一个或多个类进行切换;
export const toggleClass = function (obj, cls) {
  if (hasClass(obj, cls)) {
    removeClass(obj, cls);
  } else {
    addClass(obj, cls);
  }
};
```

## extension

用于构建名为 Element Theme Roller 的 chorme 插件项目。

* 调用命令：`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`。

## element-ui

项目静态网站打包输出目录。

## 关联阅读

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