Skip to content

路径解析

demo的书写很简单,只涉及到一个路径path的问题,这个路径经过 Sutras 解析,最终将指向demo文件的实际地址。 考虑到使用场景,Sutras提供了一些配置项,能够让你在书写文档的时候体验更好,且便于维护。 Sutras考虑的使用场景如下:

常见的项目结构

.
├─ docs
│  ├─ components
│  │  ├─ button.md /** button的介绍文档 */
│  │  ├─ input.md /** input的介绍文档 */
│  │  └─ ...
│  └─ ...  
├─ packages
│  ├─ button
│  │  ├─ src
│  │  │  ├─ __demo__
│  │  │  │  ├─ basic.vue /** 最基础的case */
│  │  │  │  ├─ size.vue  /** 支持多种大小的case */
│  │  │  │  └─ ...
│  │  │  └─ index.ts
│  │  └─ package.json
│  ├─ input
│  └─ ...
└─ workspace.yaml

甚至是更为复杂的monorepo

.
├─ docs
│  ├─ components
│  │  ├─ button.md /** button的介绍文档 */
│  │  ├─ input.md /** input的介绍文档 */
│  │  └─ ...
│  └─ ...  
├─ packages
│  ├─ components
│  │  ├─ src
│  │  │  ├─ button
│  │  │  │  ├─ __demo__
│  │  │  │  │  ├─ basic.vue /** 最基础的case */
│  │  │  │  │  ├─ size.vue  /** 支持多种大小的case */
│  │  │  │  │  └─ ...
│  │  │  │  └─ index.ts
│  │  │  ├─ ...
│  │  │  └─ index.ts
│  │  └─ package.json
│  ├─ composables
│  │  ├─ src
│  │  │  ├─ use-style
│  │  │  │  ├─ __demo__
│  │  │  │  │  └─ ...
│  │  │  │  └─ index.ts
│  │  │  ├─ ...
│  │  │  └─ index.ts
│  │  └─ package.json
│  ├─ utils
│  └─ ...
└─ workspace.yaml

亦或是你的团队有其他的目录规范,但从概念上,Sutras做了总结:

概念介绍

  • Component

    在Sutras中,Component这一概念被广泛地应用,它不仅限于前端组件。这一概念涉及模块化复杂程序的分解以及设计重用等多个层面,是相对于整体的一个分割单元。

    • JavaScript函数:比如lodash库中的chunkeach等函数,每一个都可以视为一个组件。
    • Hook函数:如@vueuse/core中的useFetchuseTimeout等,也属于Sutras所定义的组件范畴。

    它是demo的展示对象

  • Feature

    每个Component都至少包含一个Feature

    如一个Button组件,支持设置:类型大小等等;

    如lodash函数find,有多种用法:

    js
    var users = [
      { 'user': 'barney',  'age': 36, 'active': true },
      { 'user': 'fred',    'age': 40, 'active': false },
      { 'user': 'pebbles', 'age': 1,  'active': true }
    ];
    
    _.find(users, function(o) { return o.age < 40; });
    // => object for 'barney'
    
    // The `_.matches` iteratee shorthand.
    _.find(users, { 'age': 1, 'active': true });
    // => object for 'pebbles'
    
    // The `_.matchesProperty` iteratee shorthand.
    _.find(users, ['active', false]);
    // => object for 'fred'
    
    // The `_.property` iteratee shorthand.
    _.find(users, 'active');
    // => object for 'barney'

    Sutras认为每一个Feature都可以作为一个独立的demo进行展示,当然你也可以放在一个demo中。

  • Scene

    有时一个复杂庞大的Feature,可能要进一步细化来解释、介绍。Sutras把被细化的每种情况称作Scene

  • Package

    在常规的单项目仓库(SingleRepo)中,你可能并不需要关注这个概念。在复杂的多项目仓库(Monorepo),将庞大的Component划分组织成多个Package是常见的:

    如前端组件库可以拆分为:utilscomponentsstylehooks...等等package。

    lodashjs,可以根据数据结果划分package:ArrayCollectionFunction...

    @vueuse,也有它自身设定的category分类:StateElements...

    这些package可能都需要demo展示,以便书写技术文档共享给社区或团队成员。

由此Sutras遇到了:Package-Component-Feature-Scene,这样的四级结构。Sutras也是根据围绕着四个概念设计了路径解析逻辑

路径解析逻辑

Package解析

首先,Sutras在构建时,会基于工作目录扫描你的仓库,搜集所有的package信息。

如果你的仓库是单项目仓库,那么Sutras会将你的仓库视为一个package。

如果你的仓库是多项目仓库,那么Sutras会依据你所使用的工作空间workspace设置,来获取所有的package信息。Sutras支持的workspace技术有: Yarn, Bolt, Lerna, pnpm, Rush

指定Package与Component

Sutras需要你来指定demo所属的Package、Component,指定方式有三种:

  • 通过文档的文件名与目录名

    通常你的文档可以按照/docs/package/component.md进行整理,如:/docs/components/button.md

    当你在文档button.md中书写:<demo path="basic"/>时,Sutras会认为你要将:

    Package名为:"components"、组件名为:"button"的basic文件作为你的demo文件。

    TIP

    你可以省略demo文件后缀名。

    Sutras也支持通过插件配置来为你的每个package定义各自的别名Alias,详见定义Package别名

  • 通过文档的frontmatter

    有的时候你的文档结构并非完全按照仓库结构进行组织,为此,Sutras支持你在文档的frontmatter中显示指定要展示的package与component,如在button.md中:

    md
    ---
    package: components
    component: button
    ---
    <demo path="basic"/>

    Sutras同样也会认为你要将:Package名为:"components"、组件名为:"button"的basic文件作为你的demo文件。

  • 通过demo的属性

    更特别地,你可能想要写一篇Summary文档页面,简单总结几个component下各自的demo。Sutras支持你通过demo的属性来指定,如在summary.md中:

    md
    <demo package="components" component="button" path="basic"/>
    <demo package="style" component="useStyle" path="basic"/>

你也可以讲上述三种方式组合起来,如:/docs/xxx/summary-components.md

md
---
package: components
---
<demo component="button" path="basic"/>
<demo component="input" path="basic"/>

或在/docs/components/xxx.md中,使用文档目录名:

md
<demo component="button" path="basic"/>
<demo component="input" path="basic"/>

或在/docs/components/xxx.md中,使用文档目录名,结合frontmatter

md
---
component: button
---
<demo path="basic"/>

总之:Sutras会先检查demo的属性,然后查看frontmatter,最后依据文档的文件名与目录名

扫描demo

通过你的指定信息,Sutras基本已经知道你要展示的demo是什么了。接下来,Sutras会借助glob,扫描你的仓库获取demo文件内容:

glob规则

在单项目仓库中,Sutras生成的glob规则为:

text
{root}/**/{component}/**/demos/**/{demo}.{vue|ts|js}
{root}/**/{component}/**/demos/**/{demo}./index.{vue|ts|js}
{root}/**/demos/**/{component}/**/{demo}..{vue|ts|js}
{root}/**/demos/**/{component}/**/{demo}./index.{vue|ts|js}

在多项目仓库中,Sutras生成的glob规则为:

text
{path-to-package}/**/{component}/**/demos/**/{demo}.{vue|ts|js}
{path-to-package}/**/{component}/**/demos/**/{demo}/index.{vue|ts|js}
{path-to-package}/**/demos/**/{component}/**/{demo}.{vue|ts|js}
{path-to-package}/**/demos/**/{component}/**/{demo}/index.{vue|ts|js}

定义demos目录

你可以通过插件设置,来自定义demos目录,如:__demos__,详见定义demos目录

使用本地demo

Sutras也支持你在Vitepress目录下使用demo,如,你在/docs/xxxx/目录下书写了一个demo.vuedemo.js,在/docs/目录下的任意文档中可以通过相对路径引用这个demo,如在/docs/index.md文档中:

md
<demo path="./xxxx/demo.vue"/>

继续分解

在概念介绍中,Sutras定义了一个Scene概念,如果你实际工作中确实遇到庞大的Feature需要继续分解的需求,Sutras也做了支持。

如上面介绍过的例子中,你的button组件的size特性还需要分场景进行展示:button按钮的大小,可以通过 Button 的 size属性来设置;也可以通过全局的ConfigProvder.componentSize来进行默认设置;

那么可以将size作为一个文件夹,把各种场景放置在里面:

js
.
├─ src
│  ├─ demos
│  │  ├─ button
│  │  │  ├─ basic.vue
│  │  │  ├─ size /** 支持多种大小的case */
│  │  │  │  ├─ by-props.vue /** 通过属性进行设置 */
│  │  │  │  └─ by-provider /** 通过全局config进行设置 */
│  │  │  │     └─ index.vue /** 这里作为一个例子展示 */
│  │  │  └─ ...
│  │  └─ ...
│  ├─ button
│  │  └─ index.ts
│  ├─ input
│  ├─ ...
│  └─ index.ts
├─ ...
└─ package.json

文档button.md需要添加一个属性

markdown
<demo path="size/by-props"/>
<demo path="size/by-provider"/>

如果多个场景需要并列展示,中间不插入其他markdown文本,那么Sutras提供了有更简单的等价写法:

markdown
<demo path="size" scene/>

基于 MIT 许可发布