diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml
index 407d54c64..49091dab9 100644
--- a/.github/workflows/website.yml
+++ b/.github/workflows/website.yml
@@ -43,7 +43,8 @@ jobs:
# 部署到 GitHub Pages
- name: Deploy
uses: JamesIves/github-pages-deploy-action@4.1.0
- if: github.ref == 'refs/heads/master'
+ if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/release-next'
with:
BRANCH: gh-pages
FOLDER: website/build
+ repositoryName: ice-lab/site-v3
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..6c41198c2
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,100 @@
+# 参与贡献
+
+## 环境准备
+
+1. 保证 Node.js 版本是 Node.js 14 以上。推荐安装 Node.js 16+ 版本,会大大提升本地调试速度
+2. ICE 仓库是 `monorepo`,并使用 `pnpm workspace`。因此需要安装 [pnpm](https://pnpm.io/) 包管理工具
+3. 在项目根目录下执行 `pnpm setup` 后会安装依赖和编译代码
+
+> 如果在安装 puppeteer 的时候过慢,可以参考此 [issue](https://github.com/puppeteer/puppeteer/issues/6833#issuecomment-863488626) 进行配置 chromium 缓存。
+
+## 目录说明
+
+```markdown
+ice-next
+├── examples # 存档各种示例代码
+├── packages # 存放 npm 包
+| ├── bundles # 依赖预编译,锁定框架三方依赖版本,框架中的依赖需要从此包导入模块
+| ├── ice # 工程代码,包括创建 service、构建任务、Webpack 和 esbuild 的打包编译逻辑等
+| ├── plugin-auth # Auth 插件
+| ├── route-manifest # 根据约定式路由生成路由配置
+| ├── runtime # 运行时代码,包括 Client/Server 入口、Document、路由组件等
+| ├── types # 公共 TS 依赖
+| └── webpack-config # 存放 Webpack 默认的配置项
+├── scripts # 执行脚本
+├── tests # 测试用例
+| ├── integration
+| └── utils
+└── website # ICE 官方文档
+```
+
+补充说明:
+
+1. `packages` 目录下以 `plugin-xxx` 命名的都是插件包,插件的开发规范可以参考[文档]()
+2. `packages/types` 是用于存放公共的 TS 类型声明,以在其他 `package` 中进行复用
+
+## 调试
+
+### 启动 watch 命令
+
+此命令用于监听 `packages` 目录下代码变更,并增量编译代码。
+
+```bash
+pnpm watch
+```
+
+### 跑 example
+
+`examples` 目录下存放了各种用于测试的 demo,并且自动 Link 到 `packages` 目录下的代码。只需执行以下命令即可开始调试:
+
+```bash
+# 进入某个 example
+$ cd examples/basic-project
+# 调试 example
+$ pnpm start
+```
+
+`packages` 目录下的 `npm` 包在进行代码编译时会生成 `SourceMap`,结合 IDE 可以很方便进行断点调试。以 VS Code 为例:
+
+1. 选择 `JavaScript Debug Terminal` 进入 Debug 模式:
+
+
+2. 进入某个 `example` 目录并执行 `pnpm start` 开始调试
+
+3. 在某一行设置一个断点,当代码执行到此行时,将会停止执行并可查看各个变量的值
+
+
+## 测试
+
+ICE 使用 [vitest](https://vitest.dev/) 进行单元测试和集成测试。执行以下命令可快速运行项目中的测试用例:
+
+```bash
+# 执行一次测试并生成代码覆盖率
+$ pnpm test
+# 启用 Test Watch 模式
+$ pnpm test:watch
+# 只跑部分测试用例
+$ pnpm test basic-project.test.ts
+```
+
+## 文档
+
+ICE 的文档使用了 [docusaurus](https://docusaurus.io/) 进行搭建。执行以下命令即可开始文档的开发:
+
+```bash
+# 进入到 website 目录
+$ cd websites
+# 安装依赖
+$ yarn install
+# 本地预览
+$ yarn start
+```
+
+## 发布
+
+```bash
+# 发布 alpha 版本
+$ pnpm publish:alpha
+# 发布 beta 版本
+$ pnpm publish:beta
+```
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f1317005d..bf4144448 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15948,7 +15948,6 @@ packages:
- '@swc/core'
- esbuild
- uglify-js
- dev: true
/webpack/5.73.0_@swc+core@1.2.168:
resolution: {integrity: sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==}
diff --git a/website/blog/00-release-3.0.0.md b/website/blog/00-release-3.0.0.md
new file mode 100644
index 000000000..61f653074
--- /dev/null
+++ b/website/blog/00-release-3.0.0.md
@@ -0,0 +1,4 @@
+---
+title: 3.0.0 版本发布
+order: 1
+---
diff --git a/website/config/footer.js b/website/config/footer.js
index 2e02ed71e..3f9d97851 100644
--- a/website/config/footer.js
+++ b/website/config/footer.js
@@ -1,15 +1,6 @@
module.exports = {
style: 'dark',
links: [
- {
- title: '参考',
- items: [
- {
- to: 'https://iceteam.gitee.io',
- label: '国内镜像站点',
- },
- ],
- },
{
title: '社区',
items: [
@@ -21,6 +12,10 @@ module.exports = {
label: '阿里内部钉钉群',
href: 'https://iceworks.oss-cn-hangzhou.aliyuncs.com/assets/images/ice-group-inside.JPG',
},
+ {
+ to: 'https://iceteam.gitee.io',
+ label: '国内镜像站点',
+ },
{
label: 'GitHub Issue',
href: 'https://github.com/alibaba/ice/issues',
@@ -31,16 +26,12 @@ module.exports = {
title: '生态',
items: [
{
- label: '微前端 icestark',
- href: 'http://micro-frontends.ice.work',
+ label: '微前端 ICESTARK',
+ href: 'https://micro-frontends.ice.work/',
},
{
- label: 'ahooks',
- href: 'https://ahooks.js.org/',
- },
- {
- label: 'Formily',
- href: 'https://v2.formilyjs.org/',
+ label: '包开发 ICE PKG',
+ href: 'https://pkg.ice.work/',
},
],
},
@@ -51,18 +42,14 @@ module.exports = {
label: '淘系前端',
href: 'https://fed.taobao.org/',
},
- {
- label: 'Rax',
- href: 'https://rax.js.org',
- },
{
label: 'AppWorks',
href: 'https://appworks.site',
},
- {
- label: 'Kraken',
- href: 'https://openkraken.com/',
- },
+ // {
+ // label: 'Kraken',
+ // href: 'https://openkraken.com/',
+ // },
{
label: 'Midway',
href: 'https://midwayjs.org/',
diff --git a/website/config/navbar.js b/website/config/navbar.js
index d8e142a8d..f5135cba8 100644
--- a/website/config/navbar.js
+++ b/website/config/navbar.js
@@ -14,32 +14,32 @@ module.exports = {
position: 'right',
label: '指南',
},
+ // {
+ // position: 'right',
+ // label: '示例',
+ // to: '/docs/examples/tailwind',
+ // },
{
position: 'right',
- label: '插件',
- to: '/docs/plugin/develop/start',
- },
- {
- position: 'right',
- label: '示例',
- to: '/docs/examples/antd',
+ label: '博客',
+ to: '/blog',
},
{
label: '生态',
position: 'right',
items: [
{
- label: '微前端 icestark',
+ label: '微前端 ICESTARK',
to: 'http://micro-frontends.ice.work/',
},
+ {
+ label: '包开发 ICE PKG',
+ to: 'https://pkg.ice.work/',
+ },
{
label: '可视化工具 AppWorks',
to: 'https://appworks.site/',
},
- {
- label: '自定义物料开发',
- to: 'https://appworks.site/materials/about.html',
- },
{
label: '前端环境 AppToolkit',
to: 'https://github.com/appworks-lab/toolkit#readme',
@@ -52,11 +52,11 @@ module.exports = {
items: [
{
to: 'https://fusion.design/pc/doc/component/102',
- label: 'fusion 组件',
+ label: 'Fusion 组件',
},
{
to: 'https://ant.design',
- label: 'antd 组件',
+ label: 'Antd 组件',
},
{
to: 'https://iceteam.gitee.io',
@@ -66,16 +66,12 @@ module.exports = {
label: '社区钉钉群',
to: 'https://iceworks.oss-cn-hangzhou.aliyuncs.com/assets/images/ice-group.png',
},
- {
- label: '阿里内部钉钉群',
- to: 'https://iceworks.oss-cn-hangzhou.aliyuncs.com/assets/images/ice-group-inside.JPG',
- },
],
},
{
- href: 'https://github.com/alibaba/ice',
+ href: 'https://github.com/ice-lab/ice-next',
label: 'GitHub',
position: 'right',
},
],
-};
\ No newline at end of file
+};
diff --git a/website/config/sidebars.js b/website/config/sidebars.js
index 35c9d9d40..2e04c4fda 100644
--- a/website/config/sidebars.js
+++ b/website/config/sidebars.js
@@ -9,34 +9,22 @@ const getDocsFromDir = require('../scripts/getDocsFromDir');
module.exports = {
docs: [
'guide/about',
- // 'guide/start',
- // 'guide/upgrade',
+ 'guide/start',
+ // 'guide/practice',
{
type: 'category',
- label: '基础指南',
+ label: 'ICE 指南',
collapsed: false,
items: getDocsFromDir('guide/basic'),
},
{
type: 'category',
- label: '进阶指南',
+ label: '进阶',
collapsed: false,
items: getDocsFromDir('guide/advanced'),
},
- ],
- plugin: [
- {
- type: 'category',
- label: '插件开发',
- collapsed: false,
- items: getDocsFromDir('plugin/develop'),
- },
- {
- type: 'category',
- label: '官方插件',
- collapsed: false,
- items: getDocsFromDir('plugin/list'),
- },
+ 'guide/plugin',
+ 'guide/upgrade',
],
examples: getDocsFromDir('examples'),
-};
\ No newline at end of file
+};
diff --git a/website/docs/examples/antd.md b/website/docs/examples/antd.md
index 66cc194f0..8751edbe2 100644
--- a/website/docs/examples/antd.md
+++ b/website/docs/examples/antd.md
@@ -1,4 +1,4 @@
---
title: 使用 antd 组件
-order: 1
+order: 2
---
\ No newline at end of file
diff --git a/website/docs/examples/electron.md b/website/docs/examples/electron.md
new file mode 100644
index 000000000..1b777efbd
--- /dev/null
+++ b/website/docs/examples/electron.md
@@ -0,0 +1,4 @@
+---
+title: 开发 Electron 应用
+order: 5
+---
\ No newline at end of file
diff --git a/website/docs/examples/federation.md b/website/docs/examples/federation.md
new file mode 100644
index 000000000..a6aeadaef
--- /dev/null
+++ b/website/docs/examples/federation.md
@@ -0,0 +1,5 @@
+---
+title: Module Federation
+order: 4
+---
+
diff --git a/website/docs/examples/fusion.md b/website/docs/examples/fusion.md
index 5f5acb2f6..ab151a482 100644
--- a/website/docs/examples/fusion.md
+++ b/website/docs/examples/fusion.md
@@ -1,4 +1,4 @@
---
title: 使用 fusion 组件
-order: 2
+order: 3
---
\ No newline at end of file
diff --git a/website/docs/examples/lint.md b/website/docs/examples/lint.md
new file mode 100644
index 000000000..3317e5aa0
--- /dev/null
+++ b/website/docs/examples/lint.md
@@ -0,0 +1,4 @@
+---
+title: 代码质量
+order: 4
+---
\ No newline at end of file
diff --git a/website/docs/examples/tailwind.md b/website/docs/examples/tailwind.md
index dda8c80e7..149ee578e 100644
--- a/website/docs/examples/tailwind.md
+++ b/website/docs/examples/tailwind.md
@@ -1,5 +1,5 @@
---
title: 使用 Tailwind CSS
-order: 3
+order: 1
---
diff --git a/website/docs/guide/about.md b/website/docs/guide/about.md
index 803226bcf..70c0dee2a 100644
--- a/website/docs/guide/about.md
+++ b/website/docs/guide/about.md
@@ -1,6 +1,71 @@
---
-title: 关于飞冰
+title: 关于
order: 1
---
-About ICE 3.0
\ No newline at end of file
+
+
+飞冰 (ICE) 是一套基于 React 的前端解决方案,核心应用研发框架提供了基础的构建、路由、调试等基础能力以及微前端、一体化等领域能力,同时结合可视化操作、物料复用等方案降低研发门槛。
+
+## 特性 🎉
+- 🐒 开箱即用:TypeScript/Webpack5/CSS Modules/Mock/SSR,各种方案 All in One
+- 🦊 贴合业务的最佳实践:目录规范、代码规范、路由方案、状态管理、数据请求等
+- 🐯 多种应用模式:支持服务端渲染 SSR 以及静态构建 SSG
+- 🐦 强大的插件能力:官方所有能力都通过插件实现,业务可以通过插件扩展各种能力
+- 🐘 丰富的领域方案:微前端 ICESTARK、一体化方案等
+
+在应用框架之上,我们还提供了 NPM 包开发工具 [ICE PKG](https://pkg.ice.work):
+
+- 提供 React 组件开发、Node.js 模块开发、前端通用库等[多场景需求](https://pkg.ice.work/scenarios/component)
+- 组件开发提供基础研发范式,提供组件文档、示例、预览等功能,[查看文档](https://pkg.ice.work/guide/preview)
+- 更多场景可以通过插件的方式完成定制,查看[插件开发](https://pkg.ice.work/reference/plugins-development)
+
+你也可以搭配 VS Code 插件 AppWorks 享受到更多功能:
+
+- 通过大量的官方模板(fusion/antd)可视化创建项目,[查看更多](https://appworks.site/materialCenter/react.html)
+- 基于 VS Code 插件可视化的调试、管理依赖、拼装区块等,[查看文档](https://appworks.site)
+- 业务可以根据规范定制自己的物料体系(含项目模板),[查看物料开发文档](https://appworks.site/materials/about.html)
+- ……
+
+## 常见问题 📝
+
+### 与直接使用 Webpack 相比,使用 ICE 有什么优势?
+
+Webpack 只提供了基础的构建能力,ICE 在此基础上扩展了很多能力:
+
+- 默认集成好的框架能力,无需再引入繁冗的构建插件和配置
+- 不止是构建,更有面向业务领域的最佳实践,如路由、目录组织、状态管理等
+- 让很多业务接入成本高的能力可以开箱即用,如 SSR/SSG、微前端、一体化,基于原始的 Webpack 建设这些能力需要付出很高成本
+- 通过插件化让以上这些能力可以被扩展以及跨项目复用,尽可能保证不同项目的一致性
+
+### 我正在使用 icejs (ICE 2),需要升级到 ICE 吗?
+
+ICE 相比之前的版本,增加了更多对移动端能力的优化和适配。升级或不升级都是可行的,原先的 icejs 依然是可用的,而且我们会保证 Bugfix 的持续迭代。如果你的页面会同时运行在移动端和桌面端,使用 ICE 可能会是更好的选择,亦或者是你对 ICE 提供的更新的构建工具链、更优更多的解决方案感兴趣,你都可以选择升级到 ICE。
+
+### 使用飞冰(ICE)是否需要具备一定的前端基础?
+
+毫无疑问是需要的,我们在努力降低前端开发的门槛,但一些基础的前端知识还是需要具备的,比如 JavaScript 的基础语法、前后端如何通信等。为了便于快速入门前端知识,我们整理了一份 [前端基础知识](https://ice.work/docs/resource/front-basic),希望能帮助到开发者。
+
+### 资深前端同学是否适合使用飞冰?
+适合,面向前端场景飞冰团队有大量的最佳实践,无论是构建、规范、状态管理还是微前端都可以开箱即用。
+
+### 飞冰的浏览器兼容策略是怎样的?
+
+应用框架 ICE 默认使用的是 React 18,你可以查看 React 18 官方说明[对 JavaScript 环境的要求](https://zh-hans.reactjs.org/docs/javascript-environment-requirements.html)。如果你支持旧的浏览器和设备,可能需要引入对应的 Polyfill。
+
+此外,飞冰官方 React 物料默认使用 React 16+ 进行开发,所以通常情况下这些物料在 ICE 中是可以正常运行的,如果你遇到任何问题,也可以通过 [Issue](https://github.com/alibaba/ice/issues) 或其它方式反馈给我们。
+
+### 飞冰可以使用哪些 UI 组件?
+
+飞冰的应用框架和工具都不耦合 UI 组件,因此开发者可以选择任意的 React UI 组件使用,比如 Fusion/Antd 等。
+
+### 飞冰跟低代码方案有什么关系?
+
+低代码方案一般指以可视化拖拽搭建为主,少量地方使用代码辅助,此类方案往往是面向具体领域而非通用场景的,飞冰是面向通用领域的,以源码研发为主,通过框架、物料、GUI 操作等能力降低研发门槛,因此飞冰并不是通俗意义的低代码方案。
+
+## 联系我们 🧼
+
+- 反馈/建议:https://github.com/alibaba/ice/issues/new
+- 答疑钉钉群:
+
+
diff --git a/website/docs/guide/advanced/auth.md b/website/docs/guide/advanced/auth.md
new file mode 100644
index 000000000..75315ffdc
--- /dev/null
+++ b/website/docs/guide/advanced/auth.md
@@ -0,0 +1,7 @@
+---
+title: 权限
+order: 7
+hide: true
+---
+
+@TODO
diff --git a/website/docs/guide/advanced/deploy.md b/website/docs/guide/advanced/deploy.md
new file mode 100644
index 000000000..2e5cfb5e4
--- /dev/null
+++ b/website/docs/guide/advanced/deploy.md
@@ -0,0 +1,6 @@
+---
+title: 构建部署
+order: 10
+---
+
+About ICE.0
diff --git a/website/docs/guide/advanced/faas.md b/website/docs/guide/advanced/faas.md
new file mode 100644
index 000000000..c758f0e53
--- /dev/null
+++ b/website/docs/guide/advanced/faas.md
@@ -0,0 +1,7 @@
+---
+title: 一体化
+order: 8
+hide: true
+---
+
+@TODO
diff --git a/website/docs/guide/advanced/i18n.md b/website/docs/guide/advanced/i18n.md
new file mode 100644
index 000000000..ec9c0b601
--- /dev/null
+++ b/website/docs/guide/advanced/i18n.md
@@ -0,0 +1,7 @@
+---
+title: 国际化
+order: 6
+hide: true
+---
+
+@TODO
diff --git a/website/docs/guide/advanced/micro-frontends.md b/website/docs/guide/advanced/micro-frontends.md
new file mode 100644
index 000000000..74652a7c1
--- /dev/null
+++ b/website/docs/guide/advanced/micro-frontends.md
@@ -0,0 +1,7 @@
+---
+title: 微前端
+order: 9
+hide: true
+---
+
+@TODO
diff --git a/website/docs/guide/advanced/unit-test.md b/website/docs/guide/advanced/unit-test.md
new file mode 100644
index 000000000..d9918165c
--- /dev/null
+++ b/website/docs/guide/advanced/unit-test.md
@@ -0,0 +1,7 @@
+---
+title: 单元测试
+order: 8
+hide: true
+---
+
+@TODO
diff --git a/website/docs/guide/basic/app.md b/website/docs/guide/basic/app.md
new file mode 100644
index 000000000..a0bfb8a1c
--- /dev/null
+++ b/website/docs/guide/basic/app.md
@@ -0,0 +1,84 @@
+---
+title: 应用入口
+order: 4
+---
+
+ICE 通过应用配置的方式渲染整个应用,开发者可以根据提供的配置定制应用。
+
+## 应用配置文件
+
+框架以 `src/app.ts` 作为应用配置文件:
+
+```tsx
+import { defineAppConfig } from 'ice';
+
+export default defineAppConfig({
+ app: {
+ strict: true,
+ },
+});
+```
+
+> 推荐通过 `defineAppConfig()` 的方式导出应用配置,以获得良好的类型提示。
+
+## 配置项
+
+应用入口的配置项,支持应用常用的相关配置。
+
+### app
+
+#### `rootId`
+根节点 id
+
+- 类型:`string`
+- 默认值 `ice-container`
+
+#### `strict`
+是否开启 React 的严格模式 (React.StrictMode)
+
+- 类型 `boolean`
+- 默认值 `false`
+
+#### `errorBoundary`
+是否启用内置的错误边界捕获能力
+- 类型 `boolean`
+- 默认值 `false`
+
+### router
+
+#### `type`
+路由类型
+
+- 类型 `string`,可选值为 `hash` 或 `browser`
+- 默认为 `browser`
+
+#### `basename`
+路由 basename
+- 类型 `string`
+- 默认值 `/`
+
+## 运行时拓展
+
+应用入口除了支持定义应用配置之外,同时也承担运行时扩展的能力,比如权限配置:
+
+```js
+import { defineAppConfig } from 'ice';
+import { defineAuthConfig } from '@ice/plugin-auth/esm/types';
+
+// 导出 auth 相关的能力,该能力由 @ice/plugin-auth 插件提供
+export const auth = defineAuthConfig(() => {
+ return {
+ initialAuth: {
+ admin: true,
+ },
+ };
+});
+
+export default defineAppConfig({
+ app: {
+ strict: true,
+ },
+});
+```
+
+[//]: # (更多运行时插件能力,请参考[官方插件](/plugin/list/auth)。)
diff --git a/website/docs/guide/basic/assets.md b/website/docs/guide/basic/assets.md
new file mode 100644
index 000000000..a3a15ebcf
--- /dev/null
+++ b/website/docs/guide/basic/assets.md
@@ -0,0 +1,105 @@
+---
+title: 静态资源
+order: 7
+---
+
+ICE 内置了大量规则处理静态资源,一般情况下开发者无需设置资源的处理方式,而对于一些特殊的处理规则框架同样给出了便捷方式和指引
+
+# 基础规则
+
+框架内置了针对以下资源的处理:
+
+- 字体文件:`.woff`、`.woff2`、`.ttf`、`.eot`
+- sgv 文件 `.svg`
+- 图片资源 `.png`、`.jpg`、`.webp`、`.jpeg`、`.gif`
+
+上述资源默认通过资源地址加载,推荐将这些资源放在 `src/assets` 目录下:
+
+```shell
+src
+├── assets/
+│ ├── logo.png
+│ └── bg.png // Favicon
+```
+
+此时即可在代码中使用这些资源:
+
+```jsx
+import logoUrl from '@/assets/logo.png';
+
+function Home() {
+ return (
+ <>
+
+ >
+ );
+}
+```
+
+如果资源尺寸小于 8kb,则进行 base64 转码并内联到脚本或样式文件中。
+
+# 指定处理规则
+
+对于内置规则不满足特定场景的情况下,框架提供了便捷的方式对资源进行处理
+
+## URL 引入
+
+除基础规则中指定资源外,如果还希望通过资源地址的方式进行资源处理的,可以通过如下方式进行指定:
+
+```jsx
+import workletURL from 'extra-scalloped-border/worklet.js?url'
+CSS.paintWorklet.addModule(workletURL);
+```
+
+`?url` 等同于为指定资源指定 url-loader
+
+## 文件内容引入
+
+通过 `?raw` 后缀声明将资源作为字符串引入:
+
+```jsx
+import txtContent from './text.txt?raw';
+```
+
+`?raw` 等同于为指定资源指定 raw-loader
+
+## Worker 引入
+
+脚本可以通过指定后缀引入为 web worker:
+
+```jsx
+import Worker from './worker.js?worker'
+```
+
+`?worker` 等同于为指定资源指定 worker-loader
+
+```jsx
+import Worker from './worker.js?sharedworker'
+```
+
+`?sharedworker` 等同于为指定资源指定 worker-loader,并指定 worker 类型为 SharedWorker
+
+```jsx
+import Worker from './worker.js?worker&inline'
+```
+
+`?worker&inline`等同于为指定资源指定 worker-loader,并指定配置 `{ inline: 'fallback' }`
+
+# public 目录
+
+`public/` 目录作为框架默认的静态资源目录,不被构建工具进行编译的资源都可以放在该目录下。
+
+比如 `favicon.svg` 文件,我们并不希望该文件名编译(默认静态资源文件名在编译后会生成独立 hash,`favicon.svg` 希望保持原有文件名),在使用时直接在 html 模版中进行引用:
+
+```html
+
+
+