Skip to content

Commit c7a60bf

Browse files
committed
feat(better-define): support vite hmr
closes #153
1 parent 2b42db8 commit c7a60bf

File tree

4 files changed

+54
-4
lines changed

4 files changed

+54
-4
lines changed

.changeset/few-pigs-switch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@vue-macros/better-define': minor
3+
---
4+
5+
support vite hmr

packages/better-define/src/index.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { existsSync } from 'node:fs'
22
import { createUnplugin } from 'unplugin'
33
import { createFilter } from '@rollup/pluginutils'
44
import { REGEX_SETUP_SFC, REGEX_VUE_SFC } from '@vue-macros/common'
5-
import { setResolveTSFileIdImpl } from '@vue-macros/api'
5+
import { setResolveTSFileIdImpl, tsFileCache } from '@vue-macros/api'
66
import { transformBetterDefine } from './core'
7+
import type { ModuleNode } from 'vite'
78
import type { ResolveTSFileIdImpl } from '@vue-macros/api'
89
import type { PluginContext } from 'rollup'
910
import type { FilterPattern } from '@rollup/pluginutils'
@@ -32,6 +33,20 @@ export default createUnplugin<Options | undefined>((userOptions = {}, meta) => {
3233
const options = resolveOptions(userOptions)
3334
const filter = createFilter(options.include, options.exclude)
3435

36+
const referencedFiles = new Map<
37+
string /* file */,
38+
Set<string /* importer */>
39+
>()
40+
41+
function collectReferencedFile(importer: string, file: string) {
42+
if (!importer) return
43+
if (!referencedFiles.has(file)) {
44+
referencedFiles.set(file, new Set([importer]))
45+
} else {
46+
referencedFiles.get(file)!.add(importer)
47+
}
48+
}
49+
3550
return {
3651
name,
3752
enforce: 'pre',
@@ -42,10 +57,16 @@ export default createUnplugin<Options | undefined>((userOptions = {}, meta) => {
4257
const resolveFn: ResolveTSFileIdImpl = async (id, importer) => {
4358
let resolved = (await ctx.resolve(id, importer))?.id
4459
if (!resolved) return
45-
if (existsSync(resolved)) return resolved
60+
if (existsSync(resolved)) {
61+
collectReferencedFile(importer, resolved)
62+
return resolved
63+
}
4664

4765
resolved = (await ctx.resolve(resolved))?.id
48-
if (resolved && existsSync(resolved)) return resolved
66+
if (resolved && existsSync(resolved)) {
67+
collectReferencedFile(importer, resolved)
68+
return resolved
69+
}
4970
}
5071
setResolveTSFileIdImpl(resolveFn)
5172
}
@@ -68,6 +89,25 @@ export default createUnplugin<Options | undefined>((userOptions = {}, meta) => {
6889
configResolved(config) {
6990
options.isProduction = config.isProduction
7091
},
92+
93+
handleHotUpdate({ file, server }) {
94+
function getAffectedModules(file: string): Set<ModuleNode> {
95+
if (!referencedFiles.has(file)) return new Set([])
96+
const modules = new Set<ModuleNode>([])
97+
for (const importer of referencedFiles.get(file)!) {
98+
const mods = server.moduleGraph.getModulesByFile(importer)
99+
if (mods) mods.forEach((m) => modules.add(m))
100+
101+
getAffectedModules(importer).forEach((m) => modules.add(m))
102+
}
103+
return modules
104+
}
105+
106+
if (tsFileCache[file]) delete tsFileCache[file]
107+
108+
const modules = getAffectedModules(file)
109+
return Array.from(modules)
110+
},
71111
},
72112
}
73113
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export type AnotherType = {
2+
baz: string
3+
}

playground/vue3/src/examples/better-define/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import type { AnotherType } from './another-types'
2+
13
export type Str = string
2-
export interface BaseProps {
4+
export interface BaseProps extends AnotherType {
35
name: Str
46
age: number
57
}

0 commit comments

Comments
 (0)