Skip to content

Commit 4fb6553

Browse files
committed
feat: support load config asynchronously
1 parent c5508bf commit 4fb6553

File tree

8 files changed

+151
-136
lines changed

8 files changed

+151
-136
lines changed

.changeset/few-lions-return.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@vue-macros/config": minor
3+
"unplugin-vue-macros": minor
4+
"@vue-macros/astro": minor
5+
"@vue-macros/nuxt": minor
6+
---
7+
8+
support load config asynchronously
9+

packages/astro/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ export default function (options?: Options): AstroIntegration {
2020
return {
2121
name: '@vue-macros/astro',
2222
hooks: {
23-
'astro:config:setup': ({ config }) => {
23+
'astro:config:setup': async ({ config }) => {
2424
const resolvedOptions = resolveOptions(options || {})
2525
const vue = findPluginAndRemove('vite:vue', config.vite.plugins)
2626
const vueJsx = findPluginAndRemove('vite:vue-jsx', config.vite.plugins)
2727

28-
const vueMacrosPlugins = VueMacros({
28+
const vueMacrosPlugins = await VueMacros({
2929
...resolvedOptions,
3030
plugins: {
3131
vue,

packages/config/src/options.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import process from 'node:process'
1515
import { loadConfig } from './config'
16+
import { loadConfigAsync } from './config-worker'
1617

1718
import type { Options as OptionsBetterDefine } from '@vue-macros/better-define'
1819
import type { Options as OptionsBooleanProp } from '@vue-macros/boolean-prop'
@@ -227,8 +228,9 @@ export type OptionsResolved = Required<OptionsCommon> & {
227228
export function resolveOptions(
228229
options?: Options,
229230
cwd: string = process.cwd(),
231+
config?: Omit<Options, 'plugins'>,
230232
): OptionsResolved {
231-
const config = loadConfig(cwd)
233+
config ||= loadConfig(cwd)
232234

233235
let { isProduction, nuxtContext, plugins, root, version, ...subOptions } = {
234236
...config,
@@ -294,3 +296,11 @@ export function resolveOptions(
294296
}
295297
}
296298
}
299+
300+
export async function resolveOptionsAsync(
301+
options?: Options,
302+
cwd: string = process.cwd(),
303+
): Promise<OptionsResolved> {
304+
const config = await loadConfigAsync(cwd)
305+
return resolveOptions(options, cwd, config)
306+
}

packages/macros/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@
174174
"@vue-macros/short-vmodel": "workspace:*",
175175
"@vue-macros/volar": "workspace:*",
176176
"unplugin": "catalog:",
177-
"unplugin-combine": "^1.1.1",
177+
"unplugin-combine": "^1.2.0",
178178
"unplugin-vue-define-options": "workspace:*"
179179
},
180180
"devDependencies": {

packages/macros/src/index.ts

Lines changed: 91 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { resolvePlugin } from './core/plugin'
2121
import VueBetterDefine from '@vue-macros/better-define'
2222
import VueBooleanProp from '@vue-macros/boolean-prop'
2323
import VueChainCall from '@vue-macros/chain-call'
24-
import { resolveOptions, type Options } from '@vue-macros/config'
24+
import { resolveOptionsAsync, type Options } from '@vue-macros/config'
2525
import VueDefineEmit from '@vue-macros/define-emit'
2626
import VueDefineModels from '@vue-macros/define-models'
2727
import VueDefineProp from '@vue-macros/define-prop'
@@ -47,104 +47,111 @@ import VueShortEmits from '@vue-macros/short-emits'
4747
import VueShortVmodel from '@vue-macros/short-vmodel'
4848
import VueDefineOptions from 'unplugin-vue-define-options'
4949

50-
export { defineConfig, resolveOptions, type Options } from '@vue-macros/config'
50+
export {
51+
defineConfig,
52+
resolveOptions,
53+
resolveOptionsAsync,
54+
type Options,
55+
} from '@vue-macros/config'
5156

5257
const name = generatePluginName()
5358
const plugin: UnpluginCombineInstance<Options | undefined> =
5459
createCombinePlugin<Options | undefined>((userOptions = {}, meta) => {
55-
const options = resolveOptions(userOptions)
60+
return {
61+
name,
62+
plugins: (async () => {
63+
const options = await resolveOptionsAsync(userOptions)
5664

57-
const framework = meta.framework!
58-
const setupComponentPlugins = resolvePlugin(
59-
VueSetupComponent,
60-
framework,
61-
options.setupComponent,
62-
)
63-
const namedTemplatePlugins = resolvePlugin(
64-
VueNamedTemplate,
65-
framework,
66-
options.namedTemplate,
67-
)
65+
const framework = meta.framework!
66+
const setupComponentPlugins = resolvePlugin(
67+
VueSetupComponent,
68+
framework,
69+
options.setupComponent,
70+
)
71+
const namedTemplatePlugins = resolvePlugin(
72+
VueNamedTemplate,
73+
framework,
74+
options.namedTemplate,
75+
)
6876

69-
const plugins: OptionsPlugin[] = [
70-
resolvePlugin(VueSetupSFC, framework, options.setupSFC),
71-
setupComponentPlugins?.[0],
72-
resolvePlugin(VueSetupBlock, framework, options.setupBlock),
73-
resolvePlugin(VueScriptLang, framework, options.scriptLang),
74-
options.plugins.vueRouter,
75-
namedTemplatePlugins?.[0],
77+
const plugins: OptionsPlugin[] = [
78+
resolvePlugin(VueSetupSFC, framework, options.setupSFC),
79+
setupComponentPlugins?.[0],
80+
resolvePlugin(VueSetupBlock, framework, options.setupBlock),
81+
resolvePlugin(VueScriptLang, framework, options.scriptLang),
82+
options.plugins.vueRouter,
83+
namedTemplatePlugins?.[0],
7684

77-
// props
78-
resolvePlugin(VueChainCall, framework, options.chainCall),
79-
resolvePlugin(VueDefineProps, framework, options.defineProps),
80-
resolvePlugin(VueDefinePropsRefs, framework, options.definePropsRefs),
81-
resolvePlugin(VueExportProps, framework, options.exportProps),
85+
// props
86+
resolvePlugin(VueChainCall, framework, options.chainCall),
87+
resolvePlugin(VueDefineProps, framework, options.defineProps),
88+
resolvePlugin(VueDefinePropsRefs, framework, options.definePropsRefs),
89+
resolvePlugin(VueExportProps, framework, options.exportProps),
8290

83-
// emits
84-
resolvePlugin(VueDefineEmit, framework, options.defineEmit),
85-
resolvePlugin(VueShortEmits, framework, options.shortEmits),
91+
// emits
92+
resolvePlugin(VueDefineEmit, framework, options.defineEmit),
93+
resolvePlugin(VueShortEmits, framework, options.shortEmits),
8694

87-
// both props & emits
88-
resolvePlugin(VueDefineModels, framework, options.defineModels),
95+
// both props & emits
96+
resolvePlugin(VueDefineModels, framework, options.defineModels),
8997

90-
// convert to runtime props & emits
91-
resolvePlugin(VueBetterDefine, framework, options.betterDefine),
98+
// convert to runtime props & emits
99+
resolvePlugin(VueBetterDefine, framework, options.betterDefine),
92100

93-
// runtime props
94-
resolvePlugin(VueDefineProp, framework, options.defineProp),
101+
// runtime props
102+
resolvePlugin(VueDefineProp, framework, options.defineProp),
95103

96-
resolvePlugin(VueDefineSlots, framework, options.defineSlots),
97-
resolvePlugin(VueDefineStyleX, framework, options.defineStyleX),
98-
resolvePlugin(VueExportRender, framework, options.exportRender),
99-
resolvePlugin(VueExportExpose, framework, options.exportExpose),
100-
resolvePlugin(VueJsxDirective, framework, options.jsxDirective),
101-
resolvePlugin(
102-
VueReactivityTransform,
103-
framework,
104-
options.reactivityTransform,
105-
),
106-
resolvePlugin(VueHoistStatic, framework, options.hoistStatic),
107-
resolvePlugin(VueDefineOptions, framework, options.defineOptions),
104+
resolvePlugin(VueDefineSlots, framework, options.defineSlots),
105+
resolvePlugin(VueDefineStyleX, framework, options.defineStyleX),
106+
resolvePlugin(VueExportRender, framework, options.exportRender),
107+
resolvePlugin(VueExportExpose, framework, options.exportExpose),
108+
resolvePlugin(VueJsxDirective, framework, options.jsxDirective),
109+
resolvePlugin(
110+
VueReactivityTransform,
111+
framework,
112+
options.reactivityTransform,
113+
),
114+
resolvePlugin(VueHoistStatic, framework, options.hoistStatic),
115+
resolvePlugin(VueDefineOptions, framework, options.defineOptions),
108116

109-
...(framework === 'vite' ||
110-
framework === 'rollup' ||
111-
framework === 'rolldown'
112-
? [
113-
resolvePlugin(
114-
// VueBooleanProp is not an unplugin, by now
115-
VueBooleanProp as any,
116-
framework,
117-
options.booleanProp,
118-
),
119-
resolvePlugin(
120-
// VueShortBind is not an unplugin, by now
121-
VueShortBind as any,
122-
framework,
123-
options.shortBind,
124-
),
125-
resolvePlugin(
126-
// VueShortVmodel is not an unplugin, by now
127-
VueShortVmodel as any,
128-
framework,
129-
options.shortVmodel,
130-
),
131-
]
132-
: []),
117+
...(framework === 'vite' ||
118+
framework === 'rollup' ||
119+
framework === 'rolldown'
120+
? [
121+
resolvePlugin(
122+
// VueBooleanProp is not an unplugin, by now
123+
VueBooleanProp as any,
124+
framework,
125+
options.booleanProp,
126+
),
127+
resolvePlugin(
128+
// VueShortBind is not an unplugin, by now
129+
VueShortBind as any,
130+
framework,
131+
options.shortBind,
132+
),
133+
resolvePlugin(
134+
// VueShortVmodel is not an unplugin, by now
135+
VueShortVmodel as any,
136+
framework,
137+
options.shortVmodel,
138+
),
139+
]
140+
: []),
133141

134-
options.plugins.vue,
135-
options.plugins.vueJsx,
136-
resolvePlugin(VueDefineRender, framework, options.defineRender),
137-
setupComponentPlugins?.[1],
138-
namedTemplatePlugins?.[1],
139-
framework === 'vite'
140-
? Devtools({ nuxtContext: options.nuxtContext })
141-
: undefined,
142-
framework === 'vite' ? excludeDepOptimize() : undefined,
143-
].filter(Boolean)
142+
options.plugins.vue,
143+
options.plugins.vueJsx,
144+
resolvePlugin(VueDefineRender, framework, options.defineRender),
145+
setupComponentPlugins?.[1],
146+
namedTemplatePlugins?.[1],
147+
framework === 'vite'
148+
? Devtools({ nuxtContext: options.nuxtContext })
149+
: undefined,
150+
framework === 'vite' ? excludeDepOptimize() : undefined,
151+
].filter(Boolean)
144152

145-
return {
146-
name,
147-
plugins,
153+
return plugins
154+
})(),
148155
}
149156
})
150157
export default plugin

packages/nuxt/src/index.ts

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { defineNuxtModule, useNuxt } from '@nuxt/kit'
22
import { REGEX_SETUP_SFC } from '@vue-macros/common'
3-
import { resolveOptions, type Options } from 'unplugin-vue-macros'
3+
import { resolveOptionsAsync, type Options } from 'unplugin-vue-macros'
44
import VueMacros from 'unplugin-vue-macros/vite'
55
import { githubRepo } from '../../../macros' with { type: 'macro' }
66
import type {} from '@nuxt/devtools'
@@ -14,9 +14,9 @@ const module: NuxtModule<Options> = defineNuxtModule<Options>({
1414
configKey: 'macros',
1515
},
1616
defaults: {},
17-
setup(options) {
17+
async setup(options) {
1818
const nuxt = useNuxt()
19-
const resolvedOptions = resolveOptions(options)
19+
const resolvedOptions = await resolveOptionsAsync(options)
2020

2121
nuxt.options.typescript.tsConfig ||= {}
2222
// @ts-expect-error
@@ -27,34 +27,36 @@ const module: NuxtModule<Options> = defineNuxtModule<Options>({
2727
vueCompilerOptions.plugins ||= []
2828
vueCompilerOptions.plugins.push('unplugin-vue-macros/volar')
2929

30-
nuxt.hook('vite:configResolved', (config: ViteConfig, { isClient }) => {
31-
function findPluginAndRemove(
32-
name: string,
33-
): [plugin: Plugin | null, index: number] {
34-
const idx = config.plugins!.findIndex(
35-
(plugin) => plugin && 'name' in plugin && plugin.name === name,
36-
)
37-
if (idx === -1) return [null, idx]
38-
const plugin = config.plugins![idx]
39-
config.plugins!.splice(idx, 1)
40-
return [plugin as any, idx]
41-
}
42-
config.plugins ||= []
43-
const [vue, idx] = findPluginAndRemove('vite:vue')
44-
const [vueJsx] = findPluginAndRemove('vite:vue-jsx')
30+
nuxt.hook(
31+
'vite:configResolved',
32+
async (config: ViteConfig, { isClient }) => {
33+
function findPluginAndRemove(
34+
name: string,
35+
): [plugin: Plugin | null, index: number] {
36+
const idx = config.plugins!.findIndex(
37+
(plugin) => plugin && 'name' in plugin && plugin.name === name,
38+
)
39+
if (idx === -1) return [null, idx]
40+
const plugin = config.plugins![idx]
41+
config.plugins!.splice(idx, 1)
42+
return [plugin as any, idx]
43+
}
44+
config.plugins ||= []
45+
const [vue, idx] = findPluginAndRemove('vite:vue')
46+
const [vueJsx] = findPluginAndRemove('vite:vue-jsx')
4547

46-
const vueMacrosPlugins = VueMacros({
47-
...resolvedOptions,
48-
plugins: { vue, vueJsx },
49-
nuxtContext: { isClient },
50-
// TODO: no config file
51-
})
52-
if (idx !== -1) {
53-
config.plugins.splice(idx, 0, ...vueMacrosPlugins)
54-
} else {
55-
config.plugins.push(...vueMacrosPlugins)
56-
}
57-
})
48+
const vueMacrosPlugins = await VueMacros({
49+
...resolvedOptions,
50+
plugins: { vue, vueJsx },
51+
nuxtContext: { isClient },
52+
})
53+
if (idx !== -1) {
54+
config.plugins.splice(idx, 0, ...vueMacrosPlugins)
55+
} else {
56+
config.plugins.push(...vueMacrosPlugins)
57+
}
58+
},
59+
)
5860

5961
nuxt.hook('prepare:types', (opts) => {
6062
opts.references.push({ types: 'unplugin-vue-macros/macros-global' })

pnpm-lock.yaml

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)