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


---

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