-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathauto-hmr-plugin.ts
66 lines (58 loc) · 1.89 KB
/
auto-hmr-plugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import type { Nuxt } from 'nuxt/schema'
function getStoreDeclaration(nodes?: import('estree').VariableDeclarator[]) {
return nodes?.find(
(x) =>
x.init?.type === 'CallExpression' &&
x.init.callee.type === 'Identifier' &&
x.init.callee.name === 'defineStore'
)
}
function nameFromDeclaration(node?: import('estree').VariableDeclarator) {
return node?.id.type === 'Identifier' && node.id.name
}
export function autoRegisterHMRPlugin(
nuxt: Nuxt,
{ resolve }: { resolve: (...path: string[]) => string }
) {
const projectBasePath = resolve(nuxt.options.rootDir)
return {
name: 'pinia:auto-hmr-registration',
transform(code, id) {
if (id.startsWith('\x00')) return
if (!id.startsWith(projectBasePath)) return
if (!code.includes('defineStore') || code.includes('acceptHMRUpdate')) {
return
}
const ast = this.parse(code)
// walk top-level nodes
for (const n of ast.body) {
if (
n.type === 'VariableDeclaration' ||
n.type === 'ExportNamedDeclaration'
) {
// find export or variable declaration that uses `defineStore`
const storeDeclaration = getStoreDeclaration(
n.type === 'VariableDeclaration'
? n.declarations
: n.declaration?.type === 'VariableDeclaration'
? n.declaration?.declarations
: undefined
)
// retrieve the variable name
const storeName = nameFromDeclaration(storeDeclaration)
if (storeName) {
// append HMR code
return {
code: [
code,
'if (import.meta.hot) {',
` import.meta.hot.accept(acceptHMRUpdate(${storeName}, import.meta.hot))`,
'}',
].join('\n'),
}
}
}
}
},
} satisfies import('vite').Plugin
}