Skip to content

Commit

Permalink
feat: support vue tech stack (#1922)
Browse files Browse the repository at this point in the history
* feat: add vue tech stack support

* docs: techstack related

how to use vue and how to add techstack support plugin

* feat: add external api parser support

1. Add interfaces to allow dumi to integrate with an external api parser
2. Add dumi-vue-meta package, which can extract metadata from vue.
3.  Add  API tables support for dumi-plugin-vue

* docs: api table support related

* feat: add an option for changing tsconfig path

Add the `tsconfigPath` option in `parserOptions` to allow user to customize tsconfig

* refactor: give watcher creation rights to BaseAtomAssetsParser

* docs: Update README.md

* fix: type of function signature parameter needs to be string

* refactor: code structure adjustment

* fix: babel-plugin-iife type error

* chore: use umi prebundled babel dependencies

prebundle `@vue/babel-plugin-jsx`

* feat: add onBlockLoad method for IDumiTechStack

Provide a method for parsing custom files of frontend frameworks.

* refactor: replace `babel-plugin-iife` with` transformDemoCode`

* refactor: consolidate runtime related APIs into `IDumiTechStack`

remove `useTechStackRuntimeApi`

* feat: add createApiParser

* fix: createApiParser

* docs: techstack related

* refactor: add bundle-utils

* fix: support html2sketch

* fix: html comments FrontMatter

* feat: incorporate live demo into the techstack

* fix: iframe mode

* fix: issue introduced by @vue/babel-plugin-jsx

vuejs/babel-plugin-jsx#687

* refactor: new design of techstack runtime options

* fix: live demo loading

* feat: check vue version

* refactor: flatten options of preset-vue

* refactor: remove id

* docs: preset-vue and techstack

* refactor: remove id of IDemoData

* fix: demo error

* fix: shoud pass id to useRenderer
  • Loading branch information
jeffwcx committed Mar 3, 2024
1 parent fae28cb commit f2a0b9e
Show file tree
Hide file tree
Showing 135 changed files with 47,265 additions and 3,595 deletions.
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/dist
/compiled
/theme-default
/runtime
/suites/*/compiled
/suites/preset-vue/lib
12 changes: 12 additions & 0 deletions assets-types/typings/atom/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ export interface AtomComponentAsset extends AtomBaseAsset {
* props definition of component
*/
propsConfig: ObjectPropertySchema;
/**
* slots definition of component
*/
slotsConfig?: ObjectPropertySchema;
/**
* events definition of component
*/
eventsConfig?: ObjectPropertySchema;
/**
* methods definition of component
*/
methodsConfig?: ObjectPropertySchema;

/**
* available parent components of component
Expand Down
16 changes: 16 additions & 0 deletions assets-types/typings/atom/props/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,29 @@ export interface ObjectPropertySchema extends BasePropertySchema {
required?: string[];
}

export interface FunctionArgSchema {
key: string;
type: PropertySchema | string;
hasQuestionToken?: boolean;
}

export interface FunctionPropertySchema extends BasePropertySchema {
type: 'function';
signature: {
isAsync: boolean;
returnType: PropertySchema;
arguments: FunctionArgSchema[];
};
}

/**
* prop definition
*/
export type PropertySchema =
| BasePropertySchema
| ObjectPropertySchema
| ArrayPropertySchema
| FunctionPropertySchema
| StringPropertySchema
| NumberPropertySchema
| BooleanPropertySchema;
4 changes: 4 additions & 0 deletions assets-types/typings/example.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ export interface ExampleBlockAsset extends ExampleBaseAsset {
value: string;
}
>;
/**
* Entry file name, you can find the relevant entry file content from `dependencies`
*/
entry?: string;
}

/**
Expand Down
5 changes: 5 additions & 0 deletions bundler-utils.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type * as BabelCore from '@umijs/bundler-utils/compiled/@babel/core';
export { BabelCore };
export const babelCore: () => typeof import('@umijs/bundler-utils/compiled/@babel/core');
export const babelPresetTypeScript: () => BabelCore.PluginItem;
export const babelPresetEnv: () => BabelCore.PluginItem;
7 changes: 7 additions & 0 deletions bundler-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
babelCore: () => require('@umijs/bundler-utils/compiled/babel/core'),
babelPresetTypeScript: () =>
require('@umijs/bundler-utils/compiled/babel/preset-typescript'),
babelPresetEnv: () =>
require('@umijs/bundler-utils/compiled/babel/preset-env'),
};
155 changes: 155 additions & 0 deletions docs/guide/vue-api-table.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
---
title: 自动 API 表格
group:
title: 使用vue
order: 1
order: 2
---

# Vue 的自动 API 表格

dumi 支持 Vue 组件的自动 API 表格生成,用户只需配置`entryFile`即可开始 API 表格的使用:

```ts
import { defineConfig } from 'dumi';

export default defineConfig({
resolve: {
// 配置入口文件路径,API 解析将从这里开始
entryFile: './src/index.ts',
},
});
```

## tsconfig 配置

Vue 组件的元信息提取主要使用 TypeScript 的 TypeChecker, 所以配置`tsconfig.json`时请务必将`strictNullChecks`设为`false`

```json
{
"compilerOptions": {
"strictNullChecks": false
}
}
```

如果项目中一定要使用`strictNullChecks`,你也可以为 Vue 解析专门配置一个`tsconfig.vue.json`文件

```ts
// .dumirc.ts
import * as path from 'path';
export default {
plugins: ['@dumijs/preset-vue'],
vue: {
tsconfigPath: path.resolve(__dirname, './tsconfig.vue.json'),
},
};
```

## JSDoc 编写

:::warning
推荐在 props 中定义组件的事件,这样可以获得完整的 JSDoc 支持
:::

插件主要支持以下 JSDoc 标签:

### @description

属性描述,可以在`props`, `slots`, `methods`中使用,例如:

```ts
export default defineComponent({
props: {
/**
* @description 标题
*/
title: {
type: String,
default: '',
},
},
});
```

### @default

当 prop 的`default`选项为函数时,`default`值不会被解析,这时可以使用`@default`来声明它

```ts
defineComponent({
props: {
/**
* @default {}
*/
foo: {
default() {
return {};
},
},
},
});
```

### @exposed/@expose

:::warning
组件实例的方法或是属性的暴露,必须使用@exposed/@expose 标识,单文件组件也不例外
:::

```ts
defineExpose({
/**
* @exposed
*/
focus() {},
});
```

JSX/TSX 的组件方法暴露比较麻烦,需要用户另外声明

```ts
export default Button as typeof Button & {
new (): {
/**
* The signature of the expose api should be obtained from here
* @exposed
*/
focus: () => void;
};
};
```

### @ignore

`@ignore`标记的属性就会被忽略,不会被解析

## Markdown 编写

在 Markdown 文件编写时

```md
<API id="Button"></API>
```

只显示 Vue 组件的`props`部分,完整的显示应该这样编写:

```md
## Button API

### Props

<API id="Button" type="props"></API>

### Slots

<API id="Button" type="slots"></API>

### Events

<API id="Button" type="events"></API>

### Methods

<API id="Button" type="methods"></API>
```
81 changes: 81 additions & 0 deletions docs/guide/vue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
title: 安装插件
group:
title: 使用vue
order: 1
order: 1
---

# 安装 Vue 支持插件

dumi 中对 Vue 的支持主要通过`@dumijs/preset-vue`插件集实现, 目前只支持 Vue3

## 安装

```bash
pnpm i vue
pnpm i -D @dumijs/preset-vue
```

> [!NOTE]
> 如果您的 Vue 版本低于 3.3.6,请安装`@vue/compiler-sfc`
## 配置

```ts
// .dumirc.ts
export default {
presets: ['@dumijs/preset-vue'],
};
```

## 插件选项

### checkerOptions

Vue 组件元数据解析选项

例如,以下配置可以使得名称为`InternalType`的类型跳过检查

```ts
// .dumirc.ts
export default {
presets: ['@dumijs/preset-vue'],
vue: {
checkerOptions: {
schema: { ignore: ['InternalType'] },
},
},
};
```

默认情况下,从`node_modules`中引入所有类型不会被解析,这样可以有效避免元信息冗余,你也可以通过配置`exclude`来定制化类型引入

```ts
// .dumirc.ts
export default {
presets: ['@dumijs/preset-vue'],
vue: {
checkerOptions: {
schema: { exclude: [/node_modules/, /mylib/] },
},
},
};
```

### tsconfigPath

TypeChecker 使用的 tsconfig,默认值为 `<project-root>/tsconfig.json`

### compiler

Live demo 需要浏览器端的编译器,因此需要加载@babel/standalone。我们提供 `babelStandaloneCDN` 选项来更改其加载地址。默认 CDN 是
`https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.22.17/babel.min.js`

```js
vue: {
compiler: {
babelStandaloneCDN: 'https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.22.17/babel.min.js'
},
},
```
38 changes: 36 additions & 2 deletions docs/plugin/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,10 @@ api.modifyTheme((memo) => {

```ts
// CustomTechStack.ts
import type { ITechStack } from 'dumi';
import type {
IDumiTechStack,
IDumiTechStackRuntimeOpts,
} from 'dumi/tech-stack-utils';

class CustomTechStack implements IDumiTechStack {
/**
Expand All @@ -110,14 +113,45 @@ class CustomTechStack implements IDumiTechStack {
isSupported(node: hastElement, lang: string) {
return lang === 'jsx';
}

/**
* 默认情况下, dumi 只支持js/jsx/ts/tsx模块的依赖分析,
* 所以对于无法识别的文件类型需要通过此方法将文件转换为js模块
*/
onBlockLoad?(
args: IDumiTechStackOnBlockLoadArgs,
): IDumiTechStackOnBlockLoadResult {
// do something
}

/**
* 代码转换函数,返回值必须是 React 组件代码字符串
* 代码转换函数
* @note https://github.com/umijs/dumi/tree/master/src/types.ts#L57
*/
transformCode(raw: string, opts) {
// do something
return 'function Demo() { return ... }';
}

/**
* 运行时选项
*/
runtimeOpts: IDumiTechStackRuntimeOpts = {
/**
* IDemoCancelableFn函数所在的模块路径
* 操作(挂载/卸载)第三方框架组件
*/
rendererPath: '',
/**
* 运行时编译功能模块的路径
*/
compilePath: '',
/**
* 该技术堆栈的运行时插件的路径
*/
pluginPath: '',
};

/**
* 生成 demo 资产元数据(可选,通常仅在 dumi 无法分析出元数据时使用,例如非 JS 模块)
* @note https://github.com/umijs/dumi/tree/master/src/types.ts#L64
Expand Down

0 comments on commit f2a0b9e

Please sign in to comment.