-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(plugin-register-components): add register components plugin (close
#112)
- Loading branch information
Showing
14 changed files
with
426 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
# register-components | ||
|
||
> [@vuepress/plugin-register-components](https://www.npmjs.com/package/@vuepress/plugin-register-components) | ||
Register Vue components from component files or directory automatically. | ||
|
||
## Options | ||
|
||
### components | ||
|
||
- Type: `Record<string, string>` | ||
|
||
- Default: `{}` | ||
|
||
- Details: | ||
|
||
An object that defines name of components and their corresponding file path. | ||
|
||
The key will be used as the component name, and the value is an absolute path of the component file. | ||
|
||
If the component name from this option conflicts with [componentsDir](#componentsdir) option, this option will have a higher priority. | ||
|
||
- Example: | ||
|
||
```js | ||
module.exports = { | ||
plugins: [ | ||
[ | ||
'@vuepress/register-components', | ||
{ | ||
components: { | ||
FooBar: path.resolve(__dirname, './components/FooBar.vue'), | ||
}, | ||
}, | ||
], | ||
], | ||
} | ||
``` | ||
|
||
### componentsDir | ||
|
||
- Type: `string | null` | ||
|
||
- Default: `null` | ||
|
||
- Details: | ||
|
||
An absolute path of the components directory. | ||
|
||
Files in this directory which are matched with [componentsPatterns](#componentspatterns) will be registered as Vue components automatically. | ||
|
||
- Example: | ||
|
||
```js | ||
module.exports = { | ||
plugins: [ | ||
[ | ||
'@vuepress/register-components', | ||
{ | ||
componentsDir: path.resolve(__dirname, './components'), | ||
}, | ||
], | ||
], | ||
} | ||
``` | ||
|
||
Components directory: | ||
|
||
```bash | ||
components | ||
├─ FooBar.vue | ||
└─ Baz.vue | ||
``` | ||
|
||
Components will be registered like this: | ||
|
||
```js | ||
import { defineAsyncComponent } from 'vue' | ||
|
||
app.component( | ||
'FooBar', | ||
defineAsyncComponent(() => import('/path/to/components/FooBar.vue')) | ||
) | ||
|
||
app.component( | ||
'Baz', | ||
defineAsyncComponent(() => import('/path/to/components/Baz.vue')) | ||
) | ||
``` | ||
|
||
### componentsPatterns | ||
|
||
- Type: `string[]` | ||
|
||
- Default: `['**/*.vue']` | ||
|
||
- Details: | ||
|
||
Patterns to match component files using [globby](https://github.com/sindresorhus/globby). | ||
|
||
The patterns are relative to [componentsDir](#componentsdir). | ||
|
||
### getComponentName | ||
|
||
- Type: `(filename: string) => string` | ||
|
||
- Default: `(filename) => path.trimExt(filename.replace(/\/|\\/g, '-'))` | ||
|
||
- Details: | ||
|
||
A function to get component name from the filename. | ||
|
||
It will only take effect on the files in the [componentsDir](#componentsdir) which are matched with the [componentsPatterns](#componentspatterns). | ||
|
||
Notice that the `filename` is a filepath relative to [componentsDir](#componentsdir). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
# register-components | ||
|
||
> [@vuepress/plugin-register-components](https://www.npmjs.com/package/@vuepress/plugin-register-components) | ||
根据组件文件或目录自动注册 Vue 组件。 | ||
|
||
## 配置项 | ||
|
||
### components | ||
|
||
- 类型: `Record<string, string>` | ||
|
||
- 默认值: `{}` | ||
|
||
- 详情: | ||
|
||
一个定义了组件名称和其对应文件路径的对象。 | ||
|
||
键会被用作组件名称,值是组件文件的绝对路径。 | ||
|
||
如果该配置项中的组件名称和 [componentsDir](#componentsdir) 配置项发生冲突,那么该配置项会有更高的优先级。 | ||
|
||
- 示例: | ||
|
||
```js | ||
module.exports = { | ||
plugins: [ | ||
[ | ||
'@vuepress/register-components', | ||
{ | ||
components: { | ||
FooBar: path.resolve(__dirname, './components/FooBar.vue'), | ||
}, | ||
}, | ||
], | ||
], | ||
} | ||
``` | ||
|
||
### componentsDir | ||
|
||
- 类型: `string | null` | ||
|
||
- 默认值: `null` | ||
|
||
- 详情: | ||
|
||
组件目录的绝对路径。 | ||
|
||
该目录下匹配 [componentsPatterns](#componentspatterns) 的文件会被自动注册为 Vue 组件。 | ||
|
||
- 示例: | ||
|
||
```js | ||
module.exports = { | ||
plugins: [ | ||
[ | ||
'@vuepress/register-components', | ||
{ | ||
componentsDir: path.resolve(__dirname, './components'), | ||
}, | ||
], | ||
], | ||
} | ||
``` | ||
|
||
组件目录: | ||
|
||
```bash | ||
components | ||
├─ FooBar.vue | ||
└─ Baz.vue | ||
``` | ||
|
||
组件会像这样被注册: | ||
|
||
```js | ||
import { defineAsyncComponent } from 'vue' | ||
|
||
app.component( | ||
'FooBar', | ||
defineAsyncComponent(() => import('/path/to/components/FooBar.vue')) | ||
) | ||
|
||
app.component( | ||
'Baz', | ||
defineAsyncComponent(() => import('/path/to/components/Baz.vue')) | ||
) | ||
``` | ||
|
||
### componentsPatterns | ||
|
||
- 类型: `string[]` | ||
|
||
- 默认值: `['**/*.vue']` | ||
|
||
- 详情: | ||
|
||
使用 [globby](https://github.com/sindresorhus/globby) 来匹配组件文件的 Patterns 。 | ||
|
||
该 Patterns 是相对于 [componentsDir](#componentsdir) 目录的。 | ||
|
||
### getComponentName | ||
|
||
- 类型: `(filename: string) => string` | ||
|
||
- 默认值: `(filename) => path.trimExt(filename.replace(/\/|\\/g, '-'))` | ||
|
||
- 详情: | ||
|
||
用于从文件名获取对应组件名称的函数。 | ||
|
||
它只会对 [componentsDir](#componentsdir) 目录下匹配了 [componentsPatterns](#componentspatterns) 的文件生效。 | ||
|
||
注意,这里的 `filename` 是相对于 [componentsPatterns](#componentspatterns) 目录的文件路径。 |
39 changes: 39 additions & 0 deletions
39
packages/@vuepress/plugin-register-components/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"name": "@vuepress/plugin-register-components", | ||
"version": "2.0.0-beta.8", | ||
"description": "VuePress plugin - register-components", | ||
"keywords": [ | ||
"vuepress-plugin", | ||
"vuepress", | ||
"plugin", | ||
"component" | ||
], | ||
"homepage": "https://github.com/vuepress", | ||
"bugs": { | ||
"url": "https://github.com/vuepress/vuepress-next/issues" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/vuepress/vuepress-next.git" | ||
}, | ||
"license": "MIT", | ||
"author": "meteorlxy", | ||
"main": "lib/node/index.js", | ||
"types": "lib/node/index.d.ts", | ||
"files": [ | ||
"lib" | ||
], | ||
"scripts": { | ||
"build": "tsc -b tsconfig.build.json", | ||
"clean": "rimraf lib *.tsbuildinfo", | ||
"copy": "cpx \"src/**/*.{css,svg}\" lib" | ||
}, | ||
"dependencies": { | ||
"@vuepress/core": "2.0.0-beta.8", | ||
"@vuepress/utils": "2.0.0-beta.8", | ||
"chokidar": "^3.5.1" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
packages/@vuepress/plugin-register-components/src/node/getComponentsFromDir.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { globby, path } from '@vuepress/utils' | ||
import type { RegisterComponentsPluginOptions } from './registerComponentsPlugin' | ||
|
||
export const getComponentsFromDir = async ({ | ||
componentsDir, | ||
componentsPatterns, | ||
getComponentName, | ||
}: Omit<RegisterComponentsPluginOptions, 'components'>): Promise< | ||
Record<string, string> | ||
> => { | ||
if (!componentsDir) { | ||
return {} | ||
} | ||
|
||
// get all matched component files | ||
const componentsDirFiles = await globby(componentsPatterns, { | ||
cwd: componentsDir, | ||
}) | ||
|
||
// transform files to name => filepath map | ||
return Object.fromEntries( | ||
componentsDirFiles.map((filename) => [ | ||
getComponentName(filename), | ||
path.resolve(componentsDir, filename), | ||
]) | ||
) | ||
} |
7 changes: 7 additions & 0 deletions
7
packages/@vuepress/plugin-register-components/src/node/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { registerComponentsPlugin } from './registerComponentsPlugin' | ||
|
||
export * from './getComponentsFromDir' | ||
export * from './prepareClientAppEnhanceFile' | ||
export * from './registerComponentsPlugin' | ||
|
||
export default registerComponentsPlugin |
39 changes: 39 additions & 0 deletions
39
packages/@vuepress/plugin-register-components/src/node/prepareClientAppEnhanceFile.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import type { App } from '@vuepress/core' | ||
import { getComponentsFromDir } from './getComponentsFromDir' | ||
import type { RegisterComponentsPluginOptions } from './registerComponentsPlugin' | ||
|
||
export const prepareClientAppEnhanceFile = async ( | ||
app: App, | ||
options: RegisterComponentsPluginOptions, | ||
identifier: string | ||
): Promise<string> => { | ||
// get components from directory | ||
const componentsFromDir = await getComponentsFromDir(options) | ||
|
||
// components from options will override components from dir | ||
// if they have the same component name | ||
const componentsMap: Record<string, string> = { | ||
...componentsFromDir, | ||
...options.components, | ||
} | ||
|
||
// client app enhance file content | ||
const content = `\ | ||
import { defineAsyncComponent } from 'vue' | ||
export default ({ app }) => {\ | ||
${Object.entries(componentsMap).map( | ||
([name, filepath]) => ` | ||
app.component(${JSON.stringify( | ||
name | ||
)}, defineAsyncComponent(() => import(${JSON.stringify(filepath)})))` | ||
)} | ||
} | ||
` | ||
|
||
// write temp file and return the file path | ||
return app.writeTemp( | ||
`register-components/clientAppEnhance.${identifier}.js`, | ||
content | ||
) | ||
} |
Oops, something went wrong.