Skip to content

Commit 6907535

Browse files
fix: invalidate modules after server function manifest update (#4551)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent e1daa05 commit 6907535

File tree

1 file changed

+62
-38
lines changed
  • packages/server-functions-plugin/src

1 file changed

+62
-38
lines changed

packages/server-functions-plugin/src/index.ts

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,21 @@ export function createTanStackServerFnPlugin(opts: ServerFnPluginOpts): {
4343
const directiveFnsById: Record<string, DirectiveFn> = {}
4444
let viteDevServer: ViteDevServer | undefined
4545

46-
const onDirectiveFnsById = (d: Record<string, DirectiveFn>) => {
47-
// When directives are compiled, save them to the plugin's state
48-
// This state will be used both during development to incrementally
49-
// look up server functions and during build/production to produce a
50-
// static manifest that can be read by the server build
51-
Object.assign(directiveFnsById, d)
52-
53-
if (viteDevServer) {
54-
const mod = viteDevServer.moduleGraph.getModuleById(
55-
resolveViteId(opts.manifestVirtualImportId),
56-
)
57-
if (mod) {
58-
viteDevServer.moduleGraph.invalidateModule(mod)
46+
const onDirectiveFnsById = buildOnDirectiveFnsByIdCallback({
47+
directiveFnsById,
48+
manifestVirtualImportId: opts.manifestVirtualImportId,
49+
invalidateModule: (id) => {
50+
if (viteDevServer) {
51+
const mod = viteDevServer.moduleGraph.getModuleById(id)
52+
if (mod) {
53+
if (debug) {
54+
console.info(`invalidating module ${JSON.stringify(mod.id)}`)
55+
}
56+
viteDevServer.moduleGraph.invalidateModule(mod)
57+
}
5958
}
60-
}
61-
}
59+
},
60+
})
6261

6362
const directive = 'use server'
6463
const directiveLabel = 'Server Function'
@@ -176,30 +175,23 @@ export function TanStackServerFnPluginEnv(
176175
const directiveFnsById: Record<string, DirectiveFn> = {}
177176
let serverDevEnv: DevEnvironment | undefined
178177

179-
const onDirectiveFnsById = (d: Record<string, DirectiveFn>) => {
180-
if (debug) console.info(`onDirectiveFnsById received: `, d)
181-
182-
// When directives are compiled, save them to the plugin's state
183-
// This state will be used both during development to incrementally
184-
// look up server functions and during build/production to produce a
185-
// static manifest that can be read by the server build
186-
Object.assign(directiveFnsById, d)
187-
if (debug) console.info(`directiveFnsById after update: `, directiveFnsById)
188-
189-
// during dev, invalidate the module in the server environment
190-
if (serverDevEnv) {
191-
const mod = serverDevEnv.moduleGraph.getModuleById(
192-
resolveViteId(opts.manifestVirtualImportId),
193-
)
194-
if (mod) {
195-
if (debug)
196-
console.info(
197-
`invalidating module ${JSON.stringify(mod.id)} in server environment`,
198-
)
199-
serverDevEnv.moduleGraph.invalidateModule(mod)
178+
const onDirectiveFnsById = buildOnDirectiveFnsByIdCallback({
179+
directiveFnsById,
180+
manifestVirtualImportId: opts.manifestVirtualImportId,
181+
invalidateModule: (id) => {
182+
if (serverDevEnv) {
183+
const mod = serverDevEnv.moduleGraph.getModuleById(id)
184+
if (mod) {
185+
if (debug) {
186+
console.info(
187+
`invalidating module ${JSON.stringify(mod.id)} in server environment`,
188+
)
189+
}
190+
serverDevEnv.moduleGraph.invalidateModule(mod)
191+
}
200192
}
201-
}
202-
}
193+
},
194+
})
203195

204196
const directive = 'use server'
205197
const directiveLabel = 'Server Function'
@@ -273,3 +265,35 @@ export function TanStackServerFnPluginEnv(
273265
function resolveViteId(id: string) {
274266
return `\0${id}`
275267
}
268+
269+
function buildOnDirectiveFnsByIdCallback(opts: {
270+
invalidateModule: (resolvedId: string) => void
271+
directiveFnsById: Record<string, DirectiveFn>
272+
manifestVirtualImportId: string
273+
}) {
274+
const onDirectiveFnsById = (d: Record<string, DirectiveFn>) => {
275+
if (debug) {
276+
console.info(`onDirectiveFnsById received: `, d)
277+
}
278+
279+
// When directives are compiled, save them to `directiveFnsById`
280+
// This state will be used both during development to incrementally
281+
// look up server functions and during build/production to produce a
282+
// static manifest that can be read by the server build
283+
Object.assign(opts.directiveFnsById, d)
284+
if (debug) {
285+
console.info(`directiveFnsById after update: `, opts.directiveFnsById)
286+
}
287+
288+
opts.invalidateModule(resolveViteId(opts.manifestVirtualImportId))
289+
290+
// a single module can contain multiple server functions, only invalidate the module once
291+
const uniqueFilenames = new Set(
292+
Object.values(d).map((fn) => fn.extractedFilename),
293+
)
294+
uniqueFilenames.forEach((filename) => {
295+
opts.invalidateModule(filename)
296+
})
297+
}
298+
return onDirectiveFnsById
299+
}

0 commit comments

Comments
 (0)