mirror of https://github.com/YunYouJun/valaxy
feat: add hookable for lifecycle
This commit is contained in:
parent
42ea60aaca
commit
c285d80795
|
@ -8,6 +8,7 @@ import { addonAlgolia } from 'valaxy-addon-algolia'
|
|||
import { addonWaline } from 'valaxy-addon-waline'
|
||||
import { addonComponents } from 'valaxy-addon-components'
|
||||
import { addonLightGallery } from 'valaxy-addon-lightgallery'
|
||||
import { addonTest } from 'valaxy-addon-test'
|
||||
|
||||
const safelist = [
|
||||
'i-ri-home-line',
|
||||
|
@ -113,5 +114,6 @@ export default defineValaxyConfig<ThemeConfig>({
|
|||
// addonTwikoo({
|
||||
// envId: 'https://twikoo.vercel.app',
|
||||
// }),
|
||||
addonTest(),
|
||||
],
|
||||
})
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
title: Hooks
|
||||
title_zh-CN: 钩子
|
||||
categories:
|
||||
- custom
|
||||
end: false
|
||||
---
|
||||
|
||||
::: tip
|
||||
|
||||
Valaxy 提供了钩子系统,以便你可以对生命周期的各个阶段进行定制。
|
||||
|
||||
:::
|
||||
|
||||
## Lifecycle {lang="en"}
|
||||
|
||||
## 生命周期 {lang="zh-CN"}
|
||||
|
||||
> 钩子的生命周期以排列顺序执行。
|
||||
|
||||
### Build Time
|
||||
|
||||
| Hook | Arguments | Description |
|
||||
| ---- | --------- | ----------- |
|
||||
| `options:resolved` | | 在 Valaxy 配置解析之后执行。|
|
||||
| `config:init` | | 在 Vite 配置初始化(根据 Valaxy Options 进行初始化)之后执行。|
|
||||
| `build:before` | | 在构建开始之前执行。|
|
||||
| `build:done` | | 在构建完成之后执行。 |
|
||||
|
||||
```ts
|
||||
// valaxy.config.ts
|
||||
import { defineValaxyConfig } from 'valaxy'
|
||||
|
||||
export default defineValaxyConfig({
|
||||
hooks: {
|
||||
'config:init': () => {
|
||||
console.log('config:init')
|
||||
},
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### App Client
|
||||
|
||||
| Hook | Arguments | Description |
|
||||
| ---- | --------- | ----------- |
|
||||
<!-- | `app:created` | | 在应用程序实例创建之后执行。| -->
|
|
@ -80,6 +80,7 @@
|
|||
"valaxy-addon-algolia": "workspace:*",
|
||||
"valaxy-addon-components": "workspace:*",
|
||||
"valaxy-addon-lightgallery": "workspace:*",
|
||||
"valaxy-addon-test": "workspace:*",
|
||||
"valaxy-addon-twikoo": "workspace:*",
|
||||
"valaxy-addon-waline": "workspace:*",
|
||||
"valaxy-theme-press": "workspace:*",
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# valaxy-addon-test
|
||||
|
||||
This is a test addon for Valaxy.
|
|
@ -0,0 +1 @@
|
|||
export * from './node'
|
|
@ -0,0 +1,15 @@
|
|||
import { defineValaxyAddon } from 'valaxy'
|
||||
import consola from 'consola'
|
||||
import pkg from '../package.json'
|
||||
|
||||
export const addonTest = defineValaxyAddon(options => ({
|
||||
name: pkg.name,
|
||||
enable: true,
|
||||
options,
|
||||
|
||||
setup(valaxy) {
|
||||
valaxy.hook('build:before', () => {
|
||||
consola.log('build:before')
|
||||
})
|
||||
},
|
||||
}))
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "valaxy-addon-test",
|
||||
"version": "0.0.0",
|
||||
"private": true
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import { createHooks } from 'hookable'
|
||||
import type { ResolvedValaxyOptions } from '..'
|
||||
|
||||
import { version } from '../../package.json'
|
||||
import type { ValaxyHooks, ValaxyNode } from '../types'
|
||||
|
||||
const buildHooks: (keyof ValaxyHooks)[] = [
|
||||
'build:before',
|
||||
'build:after',
|
||||
]
|
||||
|
||||
/**
|
||||
* Valaxy Node Instance
|
||||
* @param options
|
||||
*/
|
||||
export function createValaxyNode(options: ResolvedValaxyOptions) {
|
||||
const hooks = createHooks<ValaxyHooks>()
|
||||
|
||||
if (typeof options.config.hooks === 'object') {
|
||||
Object.keys(options.config.hooks).forEach((name) => {
|
||||
const hookName = name as keyof ValaxyHooks
|
||||
const hook = options.config.hooks![hookName]
|
||||
|
||||
if (typeof hook !== 'function')
|
||||
return
|
||||
|
||||
if (buildHooks.includes(hookName)) {
|
||||
if (options.mode === 'build')
|
||||
hooks.hook(hookName, hook)
|
||||
}
|
||||
else {
|
||||
hooks.hook(hookName, hook)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const valaxyNode: ValaxyNode = {
|
||||
version,
|
||||
hooks,
|
||||
hook: hooks.hook,
|
||||
}
|
||||
|
||||
options.addons.forEach((addon) => {
|
||||
if (typeof addon.setup === 'function')
|
||||
addon.setup(valaxyNode)
|
||||
})
|
||||
|
||||
return valaxyNode
|
||||
}
|
|
@ -28,6 +28,7 @@ import { registerNewCommand } from './cli/new'
|
|||
|
||||
import { setEnv, setEnvProd } from './utils/env'
|
||||
import { commonOptions } from './cli/options'
|
||||
import { createValaxyNode } from './app'
|
||||
|
||||
export const cli = yargs(hideBin(process.argv)).scriptName('valaxy')
|
||||
.usage('$0 [args]')
|
||||
|
@ -75,6 +76,8 @@ cli.command(
|
|||
const port = userPort || await findFreePort(4859)
|
||||
const options = await resolveOptions({ userRoot: root })
|
||||
|
||||
createValaxyNode(options)
|
||||
|
||||
const viteConfig: InlineConfig = mergeConfig({
|
||||
// avoid load userRoot/vite.config.ts repeatedly
|
||||
configFile: path.resolve(options.clientRoot, 'vite.config.ts'),
|
||||
|
@ -171,6 +174,10 @@ cli.command(
|
|||
const options = await resolveOptions({ userRoot: root }, 'build')
|
||||
printInfo(options)
|
||||
|
||||
const valaxyApp = createValaxyNode(options)
|
||||
// resolve options and create valaxy app
|
||||
valaxyApp.hooks.callHook('options:resolved')
|
||||
|
||||
const valaxyViteConfig: InlineConfig = mergeConfig(await mergeViteConfigs(options, 'build'), options.config.vite || {})
|
||||
const viteConfig: InlineConfig = mergeConfig(
|
||||
valaxyViteConfig,
|
||||
|
@ -185,6 +192,8 @@ cli.command(
|
|||
logLevel: log as LogLevel,
|
||||
},
|
||||
)
|
||||
// init config
|
||||
valaxyApp.hooks.callHook('config:init')
|
||||
|
||||
// merge index.html
|
||||
const templatePath = path.resolve(options.clientRoot, 'template.html')
|
||||
|
@ -194,6 +203,9 @@ cli.command(
|
|||
const indexHtml = await getIndexHtml(options)
|
||||
await fs.writeFile(indexPath, indexHtml, 'utf-8')
|
||||
|
||||
// before build
|
||||
valaxyApp.hooks.callHook('build:before')
|
||||
|
||||
try {
|
||||
if (ssg) {
|
||||
consola.info(`use ${yellow('vite-ssg')} to do ssg build...`)
|
||||
|
@ -220,6 +232,9 @@ cli.command(
|
|||
finally {
|
||||
// await fs.unlink(indexPath)
|
||||
await fs.copyFile(templatePath, indexPath)
|
||||
|
||||
// after build
|
||||
valaxyApp.hooks.callHook('build:after')
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import type { DefaultTheme, ValaxyAddon } from '../../types'
|
||||
import type { ResolvedValaxyOptions } from '../options'
|
||||
import type { ValaxyNodeConfig } from '../types'
|
||||
import type { ValaxyAddonResolver, ValaxyNodeConfig } from '../types'
|
||||
|
||||
export function defineValaxyAddon<AddonOptions = object>(
|
||||
addonFunc: (addonOptions?: AddonOptions, valaxyOptions?: ResolvedValaxyOptions) => ValaxyAddon,
|
||||
addonFunc: (addonOptions?: AddonOptions, valaxyOptions?: ResolvedValaxyOptions) => ValaxyAddon & {
|
||||
setup?: ValaxyAddonResolver['setup']
|
||||
},
|
||||
) {
|
||||
return addonFunc
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import type { VitePluginConfig as UnoCSSConfig } from 'unocss/vite'
|
|||
import type Pages from 'vite-plugin-pages'
|
||||
import type { UserConfig as ViteUserConfig } from 'vite'
|
||||
import type { presetAttributify, presetIcons, presetTypography, presetUno } from 'unocss'
|
||||
import type { Hookable } from 'hookable'
|
||||
import type { DefaultTheme, PartialDeep, ValaxyAddon, ValaxyConfig } from '../types'
|
||||
import type { ResolvedValaxyOptions } from './options'
|
||||
import type { MarkdownOptions } from './markdown/types'
|
||||
|
@ -16,6 +17,22 @@ export type UserValaxyNodeConfig<ThemeConfig = DefaultTheme.Config> = PartialDee
|
|||
export type ValaxyConfigFn<ThemeConfig = DefaultTheme.Config> = (options: ResolvedValaxyOptions<ThemeConfig>) => ValaxyNodeConfig | Promise<ValaxyNodeConfig>
|
||||
export type ValaxyConfigExport<ThemeConfig = DefaultTheme.Config> = ValaxyNodeConfig<ThemeConfig> | ValaxyConfigFn<ThemeConfig>
|
||||
|
||||
export type HookResult = Promise<void> | void
|
||||
|
||||
export interface ValaxyHooks {
|
||||
'options:resolved': () => HookResult
|
||||
'config:init': () => HookResult
|
||||
'build:before': () => HookResult
|
||||
'build:after': () => HookResult
|
||||
}
|
||||
|
||||
export interface ValaxyNode {
|
||||
version: string
|
||||
|
||||
hooks: Hookable<ValaxyHooks>
|
||||
hook: ValaxyNode['hooks']['hook']
|
||||
}
|
||||
|
||||
export interface ValaxyExtendConfig {
|
||||
/**
|
||||
* Markdown Feature
|
||||
|
@ -57,6 +74,8 @@ export interface ValaxyExtendConfig {
|
|||
path: string
|
||||
}) => void
|
||||
addons?: ValaxyAddons
|
||||
|
||||
hooks?: Partial<ValaxyHooks>
|
||||
}
|
||||
|
||||
export type ValaxyAddonLike = ValaxyAddon | false | null | undefined
|
||||
|
@ -74,4 +93,6 @@ export interface ValaxyAddonResolver {
|
|||
options: Record<string, any>
|
||||
configFile?: string
|
||||
pkg: Record<string, any>
|
||||
|
||||
setup?: (node: ValaxyNode) => void
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
"fuse.js": "^6.6.2",
|
||||
"global-dirs": "^3.0.1",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hookable": "^5.5.3",
|
||||
"html-to-text": "^9.0.5",
|
||||
"is-installed-globally": "^0.4.0",
|
||||
"jiti": "^1.20.0",
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// for client
|
||||
export interface ValaxyAddon<AddonOptions = Record<string, any>> {
|
||||
name: string
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// do not export node type here
|
||||
|
||||
export * from './addon'
|
||||
export * from './config'
|
||||
export * from './data'
|
||||
|
|
|
@ -104,6 +104,9 @@ importers:
|
|||
valaxy-addon-lightgallery:
|
||||
specifier: workspace:*
|
||||
version: link:packages/valaxy-addon-lightgallery
|
||||
valaxy-addon-test:
|
||||
specifier: workspace:*
|
||||
version: link:packages/valaxy-addon-test
|
||||
valaxy-addon-twikoo:
|
||||
specifier: workspace:*
|
||||
version: link:packages/valaxy-addon-twikoo
|
||||
|
@ -286,6 +289,9 @@ importers:
|
|||
gray-matter:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
hookable:
|
||||
specifier: ^5.5.3
|
||||
version: 5.5.3
|
||||
html-to-text:
|
||||
specifier: ^9.0.5
|
||||
version: 9.0.5
|
||||
|
@ -479,6 +485,8 @@ importers:
|
|||
specifier: ^2.7.2
|
||||
version: 2.7.2
|
||||
|
||||
packages/valaxy-addon-test: {}
|
||||
|
||||
packages/valaxy-addon-twikoo:
|
||||
dependencies:
|
||||
valaxy:
|
||||
|
|
Loading…
Reference in New Issue