Skip to content

Commit a11b51f

Browse files
committed
feat: add auto hmr registration plugin to nuxt module
1 parent d8ea789 commit a11b51f

File tree

2 files changed

+73
-0
lines changed

2 files changed

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

packages/nuxt/src/module.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ import {
77
addImports,
88
createResolver,
99
addImportsDir,
10+
addVitePlugin,
1011
} from '@nuxt/kit'
1112
import type { NuxtModule } from '@nuxt/schema'
1213
import { fileURLToPath } from 'node:url'
14+
import { autoRegisterHMRPlugin } from './auto-hmr-plugin'
1315

1416
export interface ModuleOptions {
1517
/**
@@ -76,6 +78,11 @@ const module: NuxtModule<ModuleOptions> = defineNuxtModule<ModuleOptions>({
7678
addImportsDir(resolve(nuxt.options.rootDir, storeDir))
7779
}
7880
}
81+
82+
// Register automatic hmr code plugin - dev mode only
83+
if (nuxt.options.dev) {
84+
addVitePlugin(autoRegisterHMRPlugin(nuxt, { resolve }))
85+
}
7986
},
8087
})
8188

0 commit comments

Comments
 (0)