@tanstack/start-plugin-core 1.169.12 → 1.169.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/rsbuild/index.d.ts +1 -0
- package/dist/esm/rsbuild/plugin.js +2 -0
- package/dist/esm/rsbuild/plugin.js.map +1 -1
- package/dist/esm/rsbuild/schema.d.ts +27 -27
- package/dist/esm/rsbuild/start-compiler-host.d.ts +3 -1
- package/dist/esm/rsbuild/start-compiler-host.js +6 -2
- package/dist/esm/rsbuild/start-compiler-host.js.map +1 -1
- package/dist/esm/rsbuild/start-router-plugin.d.ts +0 -2
- package/dist/esm/rsbuild/start-router-plugin.js +21 -24
- package/dist/esm/rsbuild/start-router-plugin.js.map +1 -1
- package/dist/esm/schema.d.ts +51 -51
- package/dist/esm/start-compiler/compiler.d.ts +21 -5
- package/dist/esm/start-compiler/compiler.js +197 -48
- package/dist/esm/start-compiler/compiler.js.map +1 -1
- package/dist/esm/start-compiler/config.d.ts +7 -3
- package/dist/esm/start-compiler/config.js +19 -7
- package/dist/esm/start-compiler/config.js.map +1 -1
- package/dist/esm/start-compiler/handleCreateServerFn.js +12 -0
- package/dist/esm/start-compiler/handleCreateServerFn.js.map +1 -1
- package/dist/esm/start-compiler/host.d.ts +3 -1
- package/dist/esm/start-compiler/host.js +5 -3
- package/dist/esm/start-compiler/host.js.map +1 -1
- package/dist/esm/start-compiler/types.d.ts +4 -13
- package/dist/esm/types.d.ts +33 -0
- package/dist/esm/vite/index.d.ts +1 -0
- package/dist/esm/vite/plugin.js +2 -0
- package/dist/esm/vite/plugin.js.map +1 -1
- package/dist/esm/vite/schema.d.ts +27 -27
- package/dist/esm/vite/start-compiler-plugin/plugin.d.ts +3 -1
- package/dist/esm/vite/start-compiler-plugin/plugin.js +6 -2
- package/dist/esm/vite/start-compiler-plugin/plugin.js.map +1 -1
- package/dist/esm/vite/start-router-plugin/plugin.js +5 -3
- package/dist/esm/vite/start-router-plugin/plugin.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +6 -1
- package/src/rsbuild/index.ts +5 -0
- package/src/rsbuild/plugin.ts +3 -0
- package/src/rsbuild/start-compiler-host.ts +22 -3
- package/src/rsbuild/start-router-plugin.ts +20 -21
- package/src/start-compiler/compiler.ts +389 -70
- package/src/start-compiler/config.ts +43 -6
- package/src/start-compiler/handleCreateServerFn.ts +29 -0
- package/src/start-compiler/host.ts +13 -3
- package/src/start-compiler/types.ts +5 -14
- package/src/types.ts +44 -0
- package/src/vite/index.ts +5 -0
- package/src/vite/plugin.ts +3 -0
- package/src/vite/start-compiler-plugin/plugin.ts +22 -3
- package/src/vite/start-router-plugin/plugin.ts +6 -3
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export type { TanStackStartInputConfig } from './schema.js';
|
|
2
|
-
export type { TanStackStartCoreOptions } from './types.js';
|
|
2
|
+
export type { StartCompilerImportTransform, StartCompilerTransformCandidate, StartCompilerTransformContext, TanStackStartCoreOptions, } from './types.js';
|
|
3
3
|
export { START_ENVIRONMENT_NAMES } from './constants.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { RSBUILD_ENVIRONMENT_NAMES } from './planning.js';
|
|
2
2
|
export type { TanStackStartRsbuildPluginCoreOptions } from './types.js';
|
|
3
3
|
export type { TanStackStartRsbuildInputConfig } from './schema.js';
|
|
4
|
+
export type { StartCompilerImportTransform, StartCompilerTransformCandidate, StartCompilerTransformContext, } from '../types.js';
|
|
4
5
|
export { tanStackStartRsbuild } from './plugin.js';
|
|
@@ -120,6 +120,8 @@ function tanStackStartRsbuild(corePluginOpts, startPluginOpts = {}) {
|
|
|
120
120
|
root: () => resolvedStartConfig.root || process.cwd(),
|
|
121
121
|
providerEnvName: serverFnProviderEnv,
|
|
122
122
|
generateFunctionId: startPluginOpts.serverFns?.generateFunctionId,
|
|
123
|
+
compilerTransforms: corePluginOpts.compilerTransforms,
|
|
124
|
+
serverFnProviderModuleDirectives: corePluginOpts.serverFnProviderModuleDirectives,
|
|
123
125
|
serverFnsById,
|
|
124
126
|
onServerFnsByIdChange: () => {
|
|
125
127
|
updateServerFnResolver?.();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[],"sources":["../../../src/rsbuild/plugin.ts"],"sourcesContent":["import { existsSync, readdirSync, realpathSync, statSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { hasKeys } from '@tanstack/router-core'\nimport { joinURL } from 'ufo'\nimport {\n applyResolvedBaseAndOutput,\n applyResolvedRouterBasepath,\n createStartConfigContext,\n} from '../config-context'\nimport { normalizePath } from '../utils'\nimport { createServerFnBasePath, normalizePublicBase } from '../planning'\nimport { parseStartConfig } from './schema'\nimport {\n RSBUILD_ENVIRONMENT_NAMES,\n RSBUILD_RSC_LAYERS,\n createRsbuildEnvironmentPlan,\n createRsbuildResolvedEntryAliases,\n resolveRsbuildOutputDirectory,\n} from './planning'\nimport { registerStartCompilerTransforms } from './start-compiler-host'\nimport { registerImportProtection } from './import-protection'\nimport {\n START_MANIFEST_PLACEHOLDER,\n registerVirtualModules,\n} from './virtual-modules'\nimport { createServerSetup } from './dev-server'\nimport { registerClientBuildCapture } from './normalized-client-build'\nimport { registerRouterPlugins } from './start-router-plugin'\nimport { postBuildWithRsbuild } from './post-build'\nimport { enableSwcReactServerComponents } from './swc-rsc'\nimport type { ServerFn } from '../start-compiler/types'\nimport type { TanStackStartRsbuildPluginCoreOptions } from './types'\nimport type {\n ModifyRspackConfigFn,\n RsbuildDevServer,\n RsbuildPlugin,\n RsbuildPluginAPI,\n Rspack,\n rspack as rspackNamespaceType,\n} from '@rsbuild/core'\nimport type { TanStackStartRsbuildInputConfig } from './schema'\n\n// Detect whether this plugin source is running from inside the TanStack\n// Router monorepo (packages/start-plugin-core/src/rsbuild/plugin.ts). When\n// installed from npm in a user app, the path structure is different and\n// this evaluates to false. Used to gate dev-only workarounds that only\n// matter when workspace package dists are symlinked into node_modules.\nconst currentDir = dirname(fileURLToPath(import.meta.url))\nconst isInsideRouterMonoRepo = (() => {\n // src layout: <repo>/packages/start-plugin-core/src/rsbuild → 4 levels up\n // dist layout (CJS/ESM): <repo>/packages/start-plugin-core/dist/<fmt>/rsbuild\n // → also 4 levels up\n const candidate = resolve(currentDir, '../../../../')\n return candidate.endsWith('/packages') || candidate.endsWith('\\\\packages')\n})()\n\ntype RspackNamespace = typeof rspackNamespaceType\ntype RscPluginPair = ReturnType<\n NonNullable<RspackNamespace['experiments']['rsc']>['createPlugins']\n>\ntype RspackConfig = Parameters<ModifyRspackConfigFn>[0]\ntype RspackCompiler = Rspack.Compiler\ntype RspackCompilationExtended = Rspack.Compilation\n\nexport function tanStackStartRsbuild(\n corePluginOpts: TanStackStartRsbuildPluginCoreOptions,\n startPluginOpts: TanStackStartRsbuildInputConfig = {},\n): RsbuildPlugin {\n const rscOpts = corePluginOpts.rsc\n const rscEnabled = Boolean(rscOpts)\n\n const configContext = createStartConfigContext({\n corePluginOpts,\n startPluginOpts,\n parseConfig: parseStartConfig,\n })\n const { getConfig, resolvedStartConfig } = configContext\n const serverFnProviderEnv = corePluginOpts.providerEnvironmentName\n const ssrIsProvider = corePluginOpts.ssrIsProvider\n\n // RSC plugin instances — created lazily when rspack namespace is available\n let rscPlugins: RscPluginPair | undefined\n\n // Reference to the dev server for RSC HMR socket writes\n let devServerRef: Pick<RsbuildDevServer, 'sockWrite'> | null = null\n const serverFnsById: Record<string, ServerFn> = {}\n let updateServerFnResolver: (() => void) | undefined\n\n return {\n name: 'tanstack-start-rsbuild',\n setup(api: RsbuildPluginAPI) {\n // ---------------------------------------------------------------\n // 1. modifyRsbuildConfig — resolve config, set up environments\n // ---------------------------------------------------------------\n api.modifyRsbuildConfig((rsbuildConfig, { mergeRsbuildConfig }) => {\n const root =\n typeof rsbuildConfig.root === 'string'\n ? rsbuildConfig.root\n : process.cwd()\n\n const serverBase = rsbuildConfig.server?.base\n const assetPrefix = rsbuildConfig.output?.assetPrefix\n const publicBase = normalizePublicBase(\n typeof serverBase === 'string'\n ? serverBase\n : typeof assetPrefix === 'string' && assetPrefix !== 'auto'\n ? assetPrefix\n : undefined,\n )\n const rootDistPath = rsbuildConfig.output?.distPath\n const clientDistPath =\n rsbuildConfig.environments?.[RSBUILD_ENVIRONMENT_NAMES.client]?.output\n ?.distPath\n const serverDistPath =\n rsbuildConfig.environments?.[RSBUILD_ENVIRONMENT_NAMES.server]?.output\n ?.distPath\n\n applyResolvedBaseAndOutput({\n resolvedStartConfig,\n root,\n publicBase,\n clientOutputDirectory: resolveRsbuildOutputDirectory({\n distPath: clientDistPath,\n rootDistPath,\n fallback: 'dist/client',\n subdirectory: 'client',\n }),\n serverOutputDirectory: resolveRsbuildOutputDirectory({\n distPath: serverDistPath,\n rootDistPath,\n fallback: 'dist/server',\n subdirectory: 'server',\n }),\n })\n\n const { startConfig } = getConfig()\n const routerBasepath = applyResolvedRouterBasepath({\n resolvedStartConfig,\n startConfig,\n })\n\n const resolvedEntryPlan = configContext.resolveEntries()\n const isDev = api.context.action === 'dev'\n\n const entryAliases = createRsbuildResolvedEntryAliases({\n entryPaths: resolvedEntryPlan.entryPaths,\n })\n\n const environmentPlan = createRsbuildEnvironmentPlan({\n root,\n entryAliases,\n clientOutputDirectory: resolvedStartConfig.outputDirectories.client,\n serverOutputDirectory: resolvedStartConfig.outputDirectories.server,\n publicBase: resolvedStartConfig.basePaths.publicBase,\n serverFnProviderEnv,\n environmentOverrides: corePluginOpts.rsbuild?.environments,\n rsc: rscOpts,\n dev: isDev,\n })\n const serverFnBase = createServerFnBasePath({\n routerBasepath,\n serverFnBase: startConfig.serverFns.base,\n })\n const inlineCssEnabled = !isDev && startConfig.server.build.inlineCss\n\n return mergeRsbuildConfig(rsbuildConfig, {\n source: {\n define: {\n 'process.env.TSS_SERVER_FN_BASE': JSON.stringify(serverFnBase),\n 'import.meta.env.TSS_SERVER_FN_BASE':\n JSON.stringify(serverFnBase),\n 'process.env.TSS_ROUTER_BASEPATH': JSON.stringify(routerBasepath),\n 'import.meta.env.TSS_ROUTER_BASEPATH':\n JSON.stringify(routerBasepath),\n 'process.env.TSS_DEV_SERVER': JSON.stringify(\n isDev ? 'true' : 'false',\n ),\n 'import.meta.env.TSS_DEV_SERVER': JSON.stringify(\n isDev ? 'true' : 'false',\n ),\n // Rsbuild dev already injects emitted CSS asset hrefs, so keep\n // Start's synthetic `/@tanstack-start/styles.css` path disabled.\n 'process.env.TSS_DEV_SSR_STYLES_ENABLED': JSON.stringify('false'),\n 'import.meta.env.TSS_DEV_SSR_STYLES_ENABLED':\n JSON.stringify('false'),\n 'process.env.TSS_DEV_SSR_STYLES_BASEPATH': JSON.stringify(\n resolvedStartConfig.basePaths.publicBase,\n ),\n 'import.meta.env.TSS_DEV_SSR_STYLES_BASEPATH': JSON.stringify(\n resolvedStartConfig.basePaths.publicBase,\n ),\n 'process.env.TSS_INLINE_CSS_ENABLED': JSON.stringify(\n inlineCssEnabled ? 'true' : 'false',\n ),\n 'import.meta.env.TSS_INLINE_CSS_ENABLED': JSON.stringify(\n inlineCssEnabled ? 'true' : 'false',\n ),\n },\n },\n server: {\n // SSR apps render every route on the server — disable HTML\n // fallback so rsbuild doesn't intercept /_serverFn/ URLs.\n htmlFallback: false,\n // server.setup returned callback runs after built-in middleware\n // but BEFORE fallback middleware — the ideal slot for SSR.\n ...(isDev &&\n startPluginOpts.rsbuild?.installDevServerMiddleware !== false\n ? {\n setup: createServerSetup({\n serverFnBasePath: serverFnBase,\n }),\n }\n : {}),\n },\n ...(isDev\n ? {\n dev: {\n lazyCompilation: false,\n ...(rscEnabled ? { liveReload: false } : {}),\n },\n }\n : {}),\n environments: environmentPlan.environments,\n resolve: {\n alias: environmentPlan.alias,\n },\n })\n })\n\n // ---------------------------------------------------------------\n // 2. StartCompiler transforms — server fns, isomorphic fns, etc.\n // ---------------------------------------------------------------\n registerStartCompilerTransforms(api, {\n framework: corePluginOpts.framework,\n // modifyRsbuildConfig copies rsbuildConfig.root into resolvedStartConfig.root,\n // so defer this read until transform time instead of falling back to\n // process.cwd() during plugin setup.\n root: () => resolvedStartConfig.root || process.cwd(),\n providerEnvName: serverFnProviderEnv,\n generateFunctionId: startPluginOpts.serverFns?.generateFunctionId,\n serverFnsById,\n onServerFnsByIdChange: () => {\n updateServerFnResolver?.()\n },\n })\n\n registerImportProtection(api, {\n getConfig,\n framework: corePluginOpts.framework,\n environments: [\n { name: RSBUILD_ENVIRONMENT_NAMES.client, type: 'client' },\n { name: RSBUILD_ENVIRONMENT_NAMES.server, type: 'server' },\n ...(serverFnProviderEnv !== RSBUILD_ENVIRONMENT_NAMES.server &&\n !rscEnabled\n ? [{ name: serverFnProviderEnv, type: 'server' as const }]\n : []),\n ],\n })\n\n // ---------------------------------------------------------------\n // 3. Virtual modules — manifest, server fn resolver, adapters,\n // RSC runtime, RSC HMR\n // ---------------------------------------------------------------\n const virtualModuleState = registerVirtualModules(api, {\n root: resolvedStartConfig.root || process.cwd(),\n getConfig,\n serverFnsById,\n providerEnvName: serverFnProviderEnv,\n ssrIsProvider,\n serializationAdapters: corePluginOpts.serializationAdapters,\n getDevClientEntryUrl: (publicBase: string) =>\n joinURL(publicBase, 'static/js/index.js'),\n rscEnabled,\n })\n updateServerFnResolver = virtualModuleState.updateServerFnResolver\n\n // ---------------------------------------------------------------\n // 4. Client build stats capture via processAssets\n // ---------------------------------------------------------------\n const { getClientBuild } = registerClientBuildCapture(api)\n\n // ---------------------------------------------------------------\n // 4b. Server manifest module generation (build only)\n // For ordinary multi-environment builds, Rsbuild can compile the\n // server environment after the client environment finishes. Generate\n // the final manifest as module source in that phase instead of\n // patching emitted server assets afterwards.\n // ---------------------------------------------------------------\n if (api.context.action !== 'dev') {\n const normalizedManifestPath = normalizePath(\n virtualModuleState.manifestPath,\n )\n const matchesManifestPath = (id: string) =>\n normalizePath(id) === normalizedManifestPath\n\n api.transform(\n {\n test: (id: string) => matchesManifestPath(id),\n environments: [RSBUILD_ENVIRONMENT_NAMES.server],\n },\n ({ code }) => {\n const clientBuild = getClientBuild()\n\n if (clientBuild) {\n return virtualModuleState.generateManifestContent(clientBuild)\n }\n\n if (!rscEnabled) {\n throw new Error(\n 'TanStack Start could not generate the rsbuild server manifest before the client build completed',\n )\n }\n\n // RSC builds cannot express the required client -> server ordering\n // through MultiCompiler dependencies, so keep the placeholder for\n // the RSC-only asset-patching fallback below.\n return code\n },\n )\n }\n\n // ---------------------------------------------------------------\n // 5. Router plugin wiring (generator + code splitter)\n // ---------------------------------------------------------------\n registerRouterPlugins(api, {\n getConfig,\n corePluginOpts,\n startPluginOpts,\n })\n\n // ---------------------------------------------------------------\n // 6. Dev SSR middleware — registered via server.setup in\n // modifyRsbuildConfig above (returned callback runs after\n // built-ins but before fallback middleware)\n // ---------------------------------------------------------------\n\n // ---------------------------------------------------------------\n // 6b. Dev watcher: ignore workspace package `dist/**` directories.\n //\n // In a real user app, `@tanstack/react-router` and friends live\n // inside `node_modules/` and are ignored by Rspack's default\n // watcher. In this monorepo, pnpm symlinks them to\n // `packages/*/dist` (realpath outside node_modules), so the\n // watcher follows them and treats their dist files as live\n // sources. If anything rewrites those files during dev, Rspack\n // sees transient half-written modules and fails to resolve\n // relative imports between them.\n //\n // Only apply this in monorepo development. In user apps this\n // is a no-op — their `node_modules/@tanstack/*/dist/**` is\n // already ignored by Rspack's default watchOptions.\n // ---------------------------------------------------------------\n if (isInsideRouterMonoRepo && api.context.action === 'dev') {\n api.modifyRspackConfig((config) => {\n const workspaceDistRealpaths = resolveWorkspacePackageDistRealpaths()\n if (workspaceDistRealpaths.length === 0) return\n\n const workspaceDistIgnored = new RegExp(\n workspaceDistRealpaths\n .map((path) => `^${escapeRegExp(path)}(?:[\\\\\\\\/]|$)`)\n .join('|'),\n )\n const ignored = config.watchOptions?.ignored\n\n config.watchOptions = {\n ...(config.watchOptions ?? {}),\n ignored:\n ignored == null\n ? new RegExp(\n `${defaultRspackWatchIgnored.source}|${workspaceDistIgnored.source}`,\n )\n : typeof ignored === 'string'\n ? [ignored, ...workspaceDistRealpaths]\n : Array.isArray(ignored)\n ? [...ignored, ...workspaceDistRealpaths]\n : new RegExp(\n `${ignored.source}|${workspaceDistIgnored.source}`,\n ),\n }\n })\n }\n\n // ---------------------------------------------------------------\n // 7. RSC: rspack layer rules + native RSC plugins\n // When RSC is enabled, we add:\n // - issuerLayer rule for react-server condition propagation\n // - SWC reactServerComponents: true\n // - rspack ServerPlugin (server env) / ClientPlugin (client env)\n // The Coordinator inside createPlugins() handles compilation\n // ordering (server→client→server-actions) automatically.\n // ---------------------------------------------------------------\n if (rscEnabled) {\n api.modifyRspackConfig((config, utils) => {\n const envName = utils.environment.name\n const isServerEnv = envName === RSBUILD_ENVIRONMENT_NAMES.server\n const isClientEnv = envName === RSBUILD_ENVIRONMENT_NAMES.client\n\n // Create RSC plugin pair lazily (once per build)\n if (!rscPlugins) {\n rscPlugins = utils.rspack.experiments.rsc.createPlugins()\n }\n\n if (isServerEnv) {\n // --- issuerLayer rule: modules imported from RSC layer\n // get react-server resolve condition ---\n const moduleRules = (config.module.rules ??= [])\n const root = resolvedStartConfig.root || process.cwd()\n\n // Split server-fn provider modules are the actual RSC execution\n // boundary in Start's layered model. They must compile in the\n // RSC layer so React and react-server-dom-rspack resolve their\n // react-server exports without forcing the whole SSR graph into\n // react-server conditions.\n moduleRules.push({\n resourceQuery: /(?:^|[?&])tss-serverfn-split(?:&|$)/,\n layer: RSBUILD_RSC_LAYERS.rsc,\n resolve: {\n conditionNames: ['react-server', '...'],\n },\n })\n\n // All modules imported from the RSC layer inherit\n // the react-server condition (transitive propagation), except\n // route split virtual modules. Those remain ordinary SSR/client\n // route code; only `?tsr-shared=1` modules may be shared with the\n // provider subtree.\n moduleRules.push({\n issuerLayer: RSBUILD_RSC_LAYERS.rsc,\n resourceQuery: {\n not: [/(?:^|[?&])tsr-split(?:=|&|$)/],\n },\n resolve: {\n conditionNames: ['react-server', '...'],\n },\n })\n\n // The RSC ServerPlugin injects imports like\n // `react-server-dom-rspack/server` into transformed modules.\n // Some modules in the server graph resolve from real package paths\n // outside the app root, so relying on the default relative\n // `node_modules` lookup is not enough. Seed resolve.modules with the\n // app root explicitly, without package-manager-specific heuristics.\n seedResolveModules(config, [`${root}/node_modules`, 'node_modules'])\n\n // Add ServerPlugin with HMR callback\n config.plugins.push(\n new rscPlugins.ServerPlugin({\n clientEntryName: 'index',\n runtimeEntryName: 'index',\n injectSsrModulesToEntries: ['index'],\n onServerComponentChanges: () => {\n // Send rsc:update to connected clients for HMR\n devServerRef?.sockWrite('custom', {\n event: 'rsc:update',\n })\n },\n }),\n )\n\n config.plugins.push({\n apply(compiler: RspackCompiler) {\n compiler.hooks.finishMake.tapPromise(\n {\n name: 'TanStackStartRscServerFnResolverRebuild',\n stage: -10,\n },\n async (compilation: RspackCompilationExtended) => {\n if (!hasKeys(serverFnsById)) {\n return\n }\n\n const resolverContent =\n virtualModuleState.generateCurrentResolverContent(true)\n virtualModuleState.tryUpdateServerFnResolver(\n resolverContent,\n )\n\n await rebuildModulesContaining(\n compilation,\n virtualModuleState.serverFnResolverPath,\n )\n },\n )\n },\n })\n\n if (api.context.action !== 'dev') {\n config.plugins.push({\n apply(compiler: RspackCompiler) {\n compiler.hooks.finishMake.tapPromise(\n {\n name: 'TanStackStartRscManifestRebuild',\n // The native RSC ServerPlugin completes the client-entry\n // handoff during its finishMake hook. Rebuild the manifest\n // after that point so the transform hook can emit the final\n // manifest source instead of the placeholder.\n stage: 10,\n },\n async (compilation: RspackCompilationExtended) => {\n const clientBuild = getClientBuild()\n\n if (!clientBuild) {\n return\n }\n\n virtualModuleState.updateManifest(clientBuild)\n\n await rebuildModulesContaining(\n compilation,\n virtualModuleState.manifestPath,\n )\n },\n )\n },\n })\n }\n }\n\n if (isClientEnv) {\n // Add ClientPlugin — the Coordinator links it to the\n // ServerPlugin's compilation state\n config.plugins.push(new rscPlugins.ClientPlugin())\n }\n\n // --- SWC reactServerComponents ---\n // Enable RSC directive detection where the native RSC plugins need it.\n // In the server build, scope it to the actual RSC provider subtree so\n // ordinary route-split modules (e.g. ?tsr-split=component) stay out of\n // RSC validation unless they are really imported by a provider module.\n if (isServerEnv) {\n enableSwcReactServerComponents(config, 'rsc-subtree')\n } else if (isClientEnv) {\n enableSwcReactServerComponents(config, 'all')\n }\n })\n\n // Capture dev server reference for RSC HMR socket writes\n if (api.context.action === 'dev') {\n api.onBeforeStartDevServer(({ server }) => {\n devServerRef = server\n })\n }\n }\n\n // ---------------------------------------------------------------\n // 8. Build ordering — client must complete before server starts\n // so that the manifest virtual module has real client build stats.\n // Uses rspack MultiCompiler.setDependencies() under the hood.\n //\n // IMPORTANT: When RSC is enabled we must NOT set dependencies.\n // The RSC Coordinator already orchestrates server↔client\n // compilation ordering by interleaving phases within compiler\n // hooks. Adding setDependencies(server, [client]) on top of\n // the Coordinator creates a deadlock: MultiCompiler blocks\n // the server compiler until client is `done`, but the\n // Coordinator blocks the client's `make` hook until the\n // server's entries phase completes — neither can start.\n // ---------------------------------------------------------------\n if (!rscEnabled) {\n api.onAfterCreateCompiler(({ compiler }) => {\n // MultiCompiler has a `compilers` array; single compiler does not\n if ('compilers' in compiler) {\n const serverCompiler = compiler.compilers.find(\n (c) => c.name === RSBUILD_ENVIRONMENT_NAMES.server,\n )\n if (serverCompiler) {\n compiler.setDependencies(serverCompiler, [\n RSBUILD_ENVIRONMENT_NAMES.client,\n ])\n }\n }\n })\n }\n\n // ---------------------------------------------------------------\n // 8b. Manifest asset replacement fallback (RSC build only)\n // Rsbuild's native RSC coordinator interleaves server and client\n // compilers, so the server manifest module can compile before Start's\n // normalized client build stats exist. Keep final replacement in the\n // server asset pipeline, after the client processAssets capture has a\n // chance to run.\n // ---------------------------------------------------------------\n if (api.context.action !== 'dev' && rscEnabled) {\n const manifestPlaceholderLiteral = JSON.stringify(\n START_MANIFEST_PLACEHOLDER,\n )\n api.modifyRspackConfig((config, utils) => {\n if (utils.environment.name !== RSBUILD_ENVIRONMENT_NAMES.server)\n return\n\n config.plugins.push({\n apply(compiler: RspackCompiler) {\n compiler.hooks.compilation.tap(\n 'TanStackStartManifestReplace',\n (compilation: RspackCompilationExtended) => {\n compilation.hooks.processAssets.tap(\n {\n name: 'TanStackStartManifestReplace',\n stage:\n utils.rspack.Compilation\n .PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,\n },\n () => {\n const assetsWithPlaceholder = compilation\n .getAssets()\n .flatMap((asset) => {\n if (!asset.name.endsWith('.js')) return []\n\n const sourceStr = String(asset.source.source())\n return sourceStr.includes(manifestPlaceholderLiteral)\n ? [{ asset, sourceStr }]\n : []\n })\n\n if (assetsWithPlaceholder.length === 0) return\n\n const clientBuild = getClientBuild()\n if (!clientBuild) {\n throw new Error(\n 'TanStack Start could not replace the rsbuild RSC server manifest placeholder because the client build was unavailable',\n )\n }\n\n const manifestValueLiteral =\n virtualModuleState.generateManifestValueLiteral(\n clientBuild,\n )\n\n for (const {\n asset,\n sourceStr,\n } of assetsWithPlaceholder) {\n compilation.updateAsset(\n asset.name,\n new utils.rspack.sources.RawSource(\n sourceStr.replace(\n manifestPlaceholderLiteral,\n manifestValueLiteral,\n ),\n ),\n )\n }\n },\n )\n },\n )\n },\n })\n })\n }\n\n // ---------------------------------------------------------------\n // 9. After client env compiles — refresh resolver + manifest\n // ---------------------------------------------------------------\n api.onAfterEnvironmentCompile(({ environment }) => {\n if (environment.name !== RSBUILD_ENVIRONMENT_NAMES.client) return\n\n virtualModuleState.updateServerFnResolver()\n\n const clientBuild = getClientBuild()\n if (clientBuild) {\n virtualModuleState.updateManifest(clientBuild)\n }\n })\n\n if (api.context.action === 'build') {\n api.onAfterBuild(async () => {\n const { startConfig } = getConfig()\n\n await postBuildWithRsbuild({\n startConfig,\n clientOutputDirectory: resolvedStartConfig.outputDirectories.client,\n serverOutputDirectory: resolvedStartConfig.outputDirectories.server,\n })\n })\n }\n },\n }\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nconst defaultRspackWatchIgnored = /[\\\\/](?:\\.git|node_modules)[\\\\/]/\n\nfunction seedResolveModules(\n config: RspackConfig,\n entries: Array<string>,\n): void {\n const resolveModules = (config.resolve.modules ??= [])\n\n for (const entry of entries) {\n if (!resolveModules.includes(entry)) {\n resolveModules.push(entry)\n }\n }\n}\n\nfunction rebuildModulesContaining(\n compilation: RspackCompilationExtended,\n identifierFragment: string,\n): Promise<void> {\n const modulesToRebuild = Array.from(compilation.modules).filter((mod) =>\n mod.identifier().includes(identifierFragment),\n )\n\n if (modulesToRebuild.length === 0) {\n return Promise.resolve()\n }\n\n return Promise.all(\n modulesToRebuild.map(\n (mod) =>\n new Promise<void>((resolve, reject) => {\n compilation.rebuildModule(mod, (err: Error | null) => {\n if (err) reject(err)\n else resolve()\n })\n }),\n ),\n ).then(() => undefined)\n}\n\n/**\n * Return the realpath of every packages/<name>/dist directory in the\n * TanStack Router monorepo. Only meaningful when called from inside the\n * monorepo — in user apps, callers should guard with\n * `isInsideRouterMonoRepo` before invoking this.\n */\nfunction resolveWorkspacePackageDistRealpaths(): Array<string> {\n // currentDir points at either <repo>/packages/start-plugin-core/src/rsbuild\n // or <repo>/packages/start-plugin-core/dist/<fmt>/rsbuild. Four levels up\n // lands on <repo>/packages in both layouts.\n const packagesDir = resolve(currentDir, '../../../../')\n if (!existsSync(packagesDir)) return []\n\n let entries: Array<string>\n try {\n entries = readdirSync(packagesDir)\n } catch {\n return []\n }\n\n const dists: Array<string> = []\n for (const entry of entries) {\n const distPath = join(packagesDir, entry, 'dist')\n try {\n if (!statSync(distPath).isDirectory()) continue\n } catch {\n continue\n }\n try {\n dists.push(realpathSync(distPath))\n } catch {\n dists.push(distPath)\n }\n }\n\n return dists\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","names":[],"sources":["../../../src/rsbuild/plugin.ts"],"sourcesContent":["import { existsSync, readdirSync, realpathSync, statSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { hasKeys } from '@tanstack/router-core'\nimport { joinURL } from 'ufo'\nimport {\n applyResolvedBaseAndOutput,\n applyResolvedRouterBasepath,\n createStartConfigContext,\n} from '../config-context'\nimport { normalizePath } from '../utils'\nimport { createServerFnBasePath, normalizePublicBase } from '../planning'\nimport { parseStartConfig } from './schema'\nimport {\n RSBUILD_ENVIRONMENT_NAMES,\n RSBUILD_RSC_LAYERS,\n createRsbuildEnvironmentPlan,\n createRsbuildResolvedEntryAliases,\n resolveRsbuildOutputDirectory,\n} from './planning'\nimport { registerStartCompilerTransforms } from './start-compiler-host'\nimport { registerImportProtection } from './import-protection'\nimport {\n START_MANIFEST_PLACEHOLDER,\n registerVirtualModules,\n} from './virtual-modules'\nimport { createServerSetup } from './dev-server'\nimport { registerClientBuildCapture } from './normalized-client-build'\nimport { registerRouterPlugins } from './start-router-plugin'\nimport { postBuildWithRsbuild } from './post-build'\nimport { enableSwcReactServerComponents } from './swc-rsc'\nimport type { ServerFn } from '../start-compiler/types'\nimport type { TanStackStartRsbuildPluginCoreOptions } from './types'\nimport type {\n ModifyRspackConfigFn,\n RsbuildDevServer,\n RsbuildPlugin,\n RsbuildPluginAPI,\n Rspack,\n rspack as rspackNamespaceType,\n} from '@rsbuild/core'\nimport type { TanStackStartRsbuildInputConfig } from './schema'\n\n// Detect whether this plugin source is running from inside the TanStack\n// Router monorepo (packages/start-plugin-core/src/rsbuild/plugin.ts). When\n// installed from npm in a user app, the path structure is different and\n// this evaluates to false. Used to gate dev-only workarounds that only\n// matter when workspace package dists are symlinked into node_modules.\nconst currentDir = dirname(fileURLToPath(import.meta.url))\nconst isInsideRouterMonoRepo = (() => {\n // src layout: <repo>/packages/start-plugin-core/src/rsbuild → 4 levels up\n // dist layout (CJS/ESM): <repo>/packages/start-plugin-core/dist/<fmt>/rsbuild\n // → also 4 levels up\n const candidate = resolve(currentDir, '../../../../')\n return candidate.endsWith('/packages') || candidate.endsWith('\\\\packages')\n})()\n\ntype RspackNamespace = typeof rspackNamespaceType\ntype RscPluginPair = ReturnType<\n NonNullable<RspackNamespace['experiments']['rsc']>['createPlugins']\n>\ntype RspackConfig = Parameters<ModifyRspackConfigFn>[0]\ntype RspackCompiler = Rspack.Compiler\ntype RspackCompilationExtended = Rspack.Compilation\n\nexport function tanStackStartRsbuild(\n corePluginOpts: TanStackStartRsbuildPluginCoreOptions,\n startPluginOpts: TanStackStartRsbuildInputConfig = {},\n): RsbuildPlugin {\n const rscOpts = corePluginOpts.rsc\n const rscEnabled = Boolean(rscOpts)\n\n const configContext = createStartConfigContext({\n corePluginOpts,\n startPluginOpts,\n parseConfig: parseStartConfig,\n })\n const { getConfig, resolvedStartConfig } = configContext\n const serverFnProviderEnv = corePluginOpts.providerEnvironmentName\n const ssrIsProvider = corePluginOpts.ssrIsProvider\n\n // RSC plugin instances — created lazily when rspack namespace is available\n let rscPlugins: RscPluginPair | undefined\n\n // Reference to the dev server for RSC HMR socket writes\n let devServerRef: Pick<RsbuildDevServer, 'sockWrite'> | null = null\n const serverFnsById: Record<string, ServerFn> = {}\n let updateServerFnResolver: (() => void) | undefined\n\n return {\n name: 'tanstack-start-rsbuild',\n setup(api: RsbuildPluginAPI) {\n // ---------------------------------------------------------------\n // 1. modifyRsbuildConfig — resolve config, set up environments\n // ---------------------------------------------------------------\n api.modifyRsbuildConfig((rsbuildConfig, { mergeRsbuildConfig }) => {\n const root =\n typeof rsbuildConfig.root === 'string'\n ? rsbuildConfig.root\n : process.cwd()\n\n const serverBase = rsbuildConfig.server?.base\n const assetPrefix = rsbuildConfig.output?.assetPrefix\n const publicBase = normalizePublicBase(\n typeof serverBase === 'string'\n ? serverBase\n : typeof assetPrefix === 'string' && assetPrefix !== 'auto'\n ? assetPrefix\n : undefined,\n )\n const rootDistPath = rsbuildConfig.output?.distPath\n const clientDistPath =\n rsbuildConfig.environments?.[RSBUILD_ENVIRONMENT_NAMES.client]?.output\n ?.distPath\n const serverDistPath =\n rsbuildConfig.environments?.[RSBUILD_ENVIRONMENT_NAMES.server]?.output\n ?.distPath\n\n applyResolvedBaseAndOutput({\n resolvedStartConfig,\n root,\n publicBase,\n clientOutputDirectory: resolveRsbuildOutputDirectory({\n distPath: clientDistPath,\n rootDistPath,\n fallback: 'dist/client',\n subdirectory: 'client',\n }),\n serverOutputDirectory: resolveRsbuildOutputDirectory({\n distPath: serverDistPath,\n rootDistPath,\n fallback: 'dist/server',\n subdirectory: 'server',\n }),\n })\n\n const { startConfig } = getConfig()\n const routerBasepath = applyResolvedRouterBasepath({\n resolvedStartConfig,\n startConfig,\n })\n\n const resolvedEntryPlan = configContext.resolveEntries()\n const isDev = api.context.action === 'dev'\n\n const entryAliases = createRsbuildResolvedEntryAliases({\n entryPaths: resolvedEntryPlan.entryPaths,\n })\n\n const environmentPlan = createRsbuildEnvironmentPlan({\n root,\n entryAliases,\n clientOutputDirectory: resolvedStartConfig.outputDirectories.client,\n serverOutputDirectory: resolvedStartConfig.outputDirectories.server,\n publicBase: resolvedStartConfig.basePaths.publicBase,\n serverFnProviderEnv,\n environmentOverrides: corePluginOpts.rsbuild?.environments,\n rsc: rscOpts,\n dev: isDev,\n })\n const serverFnBase = createServerFnBasePath({\n routerBasepath,\n serverFnBase: startConfig.serverFns.base,\n })\n const inlineCssEnabled = !isDev && startConfig.server.build.inlineCss\n\n return mergeRsbuildConfig(rsbuildConfig, {\n source: {\n define: {\n 'process.env.TSS_SERVER_FN_BASE': JSON.stringify(serverFnBase),\n 'import.meta.env.TSS_SERVER_FN_BASE':\n JSON.stringify(serverFnBase),\n 'process.env.TSS_ROUTER_BASEPATH': JSON.stringify(routerBasepath),\n 'import.meta.env.TSS_ROUTER_BASEPATH':\n JSON.stringify(routerBasepath),\n 'process.env.TSS_DEV_SERVER': JSON.stringify(\n isDev ? 'true' : 'false',\n ),\n 'import.meta.env.TSS_DEV_SERVER': JSON.stringify(\n isDev ? 'true' : 'false',\n ),\n // Rsbuild dev already injects emitted CSS asset hrefs, so keep\n // Start's synthetic `/@tanstack-start/styles.css` path disabled.\n 'process.env.TSS_DEV_SSR_STYLES_ENABLED': JSON.stringify('false'),\n 'import.meta.env.TSS_DEV_SSR_STYLES_ENABLED':\n JSON.stringify('false'),\n 'process.env.TSS_DEV_SSR_STYLES_BASEPATH': JSON.stringify(\n resolvedStartConfig.basePaths.publicBase,\n ),\n 'import.meta.env.TSS_DEV_SSR_STYLES_BASEPATH': JSON.stringify(\n resolvedStartConfig.basePaths.publicBase,\n ),\n 'process.env.TSS_INLINE_CSS_ENABLED': JSON.stringify(\n inlineCssEnabled ? 'true' : 'false',\n ),\n 'import.meta.env.TSS_INLINE_CSS_ENABLED': JSON.stringify(\n inlineCssEnabled ? 'true' : 'false',\n ),\n },\n },\n server: {\n // SSR apps render every route on the server — disable HTML\n // fallback so rsbuild doesn't intercept /_serverFn/ URLs.\n htmlFallback: false,\n // server.setup returned callback runs after built-in middleware\n // but BEFORE fallback middleware — the ideal slot for SSR.\n ...(isDev &&\n startPluginOpts.rsbuild?.installDevServerMiddleware !== false\n ? {\n setup: createServerSetup({\n serverFnBasePath: serverFnBase,\n }),\n }\n : {}),\n },\n ...(isDev\n ? {\n dev: {\n lazyCompilation: false,\n ...(rscEnabled ? { liveReload: false } : {}),\n },\n }\n : {}),\n environments: environmentPlan.environments,\n resolve: {\n alias: environmentPlan.alias,\n },\n })\n })\n\n // ---------------------------------------------------------------\n // 2. StartCompiler transforms — server fns, isomorphic fns, etc.\n // ---------------------------------------------------------------\n registerStartCompilerTransforms(api, {\n framework: corePluginOpts.framework,\n // modifyRsbuildConfig copies rsbuildConfig.root into resolvedStartConfig.root,\n // so defer this read until transform time instead of falling back to\n // process.cwd() during plugin setup.\n root: () => resolvedStartConfig.root || process.cwd(),\n providerEnvName: serverFnProviderEnv,\n generateFunctionId: startPluginOpts.serverFns?.generateFunctionId,\n compilerTransforms: corePluginOpts.compilerTransforms,\n serverFnProviderModuleDirectives:\n corePluginOpts.serverFnProviderModuleDirectives,\n serverFnsById,\n onServerFnsByIdChange: () => {\n updateServerFnResolver?.()\n },\n })\n\n registerImportProtection(api, {\n getConfig,\n framework: corePluginOpts.framework,\n environments: [\n { name: RSBUILD_ENVIRONMENT_NAMES.client, type: 'client' },\n { name: RSBUILD_ENVIRONMENT_NAMES.server, type: 'server' },\n ...(serverFnProviderEnv !== RSBUILD_ENVIRONMENT_NAMES.server &&\n !rscEnabled\n ? [{ name: serverFnProviderEnv, type: 'server' as const }]\n : []),\n ],\n })\n\n // ---------------------------------------------------------------\n // 3. Virtual modules — manifest, server fn resolver, adapters,\n // RSC runtime, RSC HMR\n // ---------------------------------------------------------------\n const virtualModuleState = registerVirtualModules(api, {\n root: resolvedStartConfig.root || process.cwd(),\n getConfig,\n serverFnsById,\n providerEnvName: serverFnProviderEnv,\n ssrIsProvider,\n serializationAdapters: corePluginOpts.serializationAdapters,\n getDevClientEntryUrl: (publicBase: string) =>\n joinURL(publicBase, 'static/js/index.js'),\n rscEnabled,\n })\n updateServerFnResolver = virtualModuleState.updateServerFnResolver\n\n // ---------------------------------------------------------------\n // 4. Client build stats capture via processAssets\n // ---------------------------------------------------------------\n const { getClientBuild } = registerClientBuildCapture(api)\n\n // ---------------------------------------------------------------\n // 4b. Server manifest module generation (build only)\n // For ordinary multi-environment builds, Rsbuild can compile the\n // server environment after the client environment finishes. Generate\n // the final manifest as module source in that phase instead of\n // patching emitted server assets afterwards.\n // ---------------------------------------------------------------\n if (api.context.action !== 'dev') {\n const normalizedManifestPath = normalizePath(\n virtualModuleState.manifestPath,\n )\n const matchesManifestPath = (id: string) =>\n normalizePath(id) === normalizedManifestPath\n\n api.transform(\n {\n test: (id: string) => matchesManifestPath(id),\n environments: [RSBUILD_ENVIRONMENT_NAMES.server],\n },\n ({ code }) => {\n const clientBuild = getClientBuild()\n\n if (clientBuild) {\n return virtualModuleState.generateManifestContent(clientBuild)\n }\n\n if (!rscEnabled) {\n throw new Error(\n 'TanStack Start could not generate the rsbuild server manifest before the client build completed',\n )\n }\n\n // RSC builds cannot express the required client -> server ordering\n // through MultiCompiler dependencies, so keep the placeholder for\n // the RSC-only asset-patching fallback below.\n return code\n },\n )\n }\n\n // ---------------------------------------------------------------\n // 5. Router plugin wiring (generator + code splitter)\n // ---------------------------------------------------------------\n registerRouterPlugins(api, {\n getConfig,\n corePluginOpts,\n startPluginOpts,\n })\n\n // ---------------------------------------------------------------\n // 6. Dev SSR middleware — registered via server.setup in\n // modifyRsbuildConfig above (returned callback runs after\n // built-ins but before fallback middleware)\n // ---------------------------------------------------------------\n\n // ---------------------------------------------------------------\n // 6b. Dev watcher: ignore workspace package `dist/**` directories.\n //\n // In a real user app, `@tanstack/react-router` and friends live\n // inside `node_modules/` and are ignored by Rspack's default\n // watcher. In this monorepo, pnpm symlinks them to\n // `packages/*/dist` (realpath outside node_modules), so the\n // watcher follows them and treats their dist files as live\n // sources. If anything rewrites those files during dev, Rspack\n // sees transient half-written modules and fails to resolve\n // relative imports between them.\n //\n // Only apply this in monorepo development. In user apps this\n // is a no-op — their `node_modules/@tanstack/*/dist/**` is\n // already ignored by Rspack's default watchOptions.\n // ---------------------------------------------------------------\n if (isInsideRouterMonoRepo && api.context.action === 'dev') {\n api.modifyRspackConfig((config) => {\n const workspaceDistRealpaths = resolveWorkspacePackageDistRealpaths()\n if (workspaceDistRealpaths.length === 0) return\n\n const workspaceDistIgnored = new RegExp(\n workspaceDistRealpaths\n .map((path) => `^${escapeRegExp(path)}(?:[\\\\\\\\/]|$)`)\n .join('|'),\n )\n const ignored = config.watchOptions?.ignored\n\n config.watchOptions = {\n ...(config.watchOptions ?? {}),\n ignored:\n ignored == null\n ? new RegExp(\n `${defaultRspackWatchIgnored.source}|${workspaceDistIgnored.source}`,\n )\n : typeof ignored === 'string'\n ? [ignored, ...workspaceDistRealpaths]\n : Array.isArray(ignored)\n ? [...ignored, ...workspaceDistRealpaths]\n : new RegExp(\n `${ignored.source}|${workspaceDistIgnored.source}`,\n ),\n }\n })\n }\n\n // ---------------------------------------------------------------\n // 7. RSC: rspack layer rules + native RSC plugins\n // When RSC is enabled, we add:\n // - issuerLayer rule for react-server condition propagation\n // - SWC reactServerComponents: true\n // - rspack ServerPlugin (server env) / ClientPlugin (client env)\n // The Coordinator inside createPlugins() handles compilation\n // ordering (server→client→server-actions) automatically.\n // ---------------------------------------------------------------\n if (rscEnabled) {\n api.modifyRspackConfig((config, utils) => {\n const envName = utils.environment.name\n const isServerEnv = envName === RSBUILD_ENVIRONMENT_NAMES.server\n const isClientEnv = envName === RSBUILD_ENVIRONMENT_NAMES.client\n\n // Create RSC plugin pair lazily (once per build)\n if (!rscPlugins) {\n rscPlugins = utils.rspack.experiments.rsc.createPlugins()\n }\n\n if (isServerEnv) {\n // --- issuerLayer rule: modules imported from RSC layer\n // get react-server resolve condition ---\n const moduleRules = (config.module.rules ??= [])\n const root = resolvedStartConfig.root || process.cwd()\n\n // Split server-fn provider modules are the actual RSC execution\n // boundary in Start's layered model. They must compile in the\n // RSC layer so React and react-server-dom-rspack resolve their\n // react-server exports without forcing the whole SSR graph into\n // react-server conditions.\n moduleRules.push({\n resourceQuery: /(?:^|[?&])tss-serverfn-split(?:&|$)/,\n layer: RSBUILD_RSC_LAYERS.rsc,\n resolve: {\n conditionNames: ['react-server', '...'],\n },\n })\n\n // All modules imported from the RSC layer inherit\n // the react-server condition (transitive propagation), except\n // route split virtual modules. Those remain ordinary SSR/client\n // route code; only `?tsr-shared=1` modules may be shared with the\n // provider subtree.\n moduleRules.push({\n issuerLayer: RSBUILD_RSC_LAYERS.rsc,\n resourceQuery: {\n not: [/(?:^|[?&])tsr-split(?:=|&|$)/],\n },\n resolve: {\n conditionNames: ['react-server', '...'],\n },\n })\n\n // The RSC ServerPlugin injects imports like\n // `react-server-dom-rspack/server` into transformed modules.\n // Some modules in the server graph resolve from real package paths\n // outside the app root, so relying on the default relative\n // `node_modules` lookup is not enough. Seed resolve.modules with the\n // app root explicitly, without package-manager-specific heuristics.\n seedResolveModules(config, [`${root}/node_modules`, 'node_modules'])\n\n // Add ServerPlugin with HMR callback\n config.plugins.push(\n new rscPlugins.ServerPlugin({\n clientEntryName: 'index',\n runtimeEntryName: 'index',\n injectSsrModulesToEntries: ['index'],\n onServerComponentChanges: () => {\n // Send rsc:update to connected clients for HMR\n devServerRef?.sockWrite('custom', {\n event: 'rsc:update',\n })\n },\n }),\n )\n\n config.plugins.push({\n apply(compiler: RspackCompiler) {\n compiler.hooks.finishMake.tapPromise(\n {\n name: 'TanStackStartRscServerFnResolverRebuild',\n stage: -10,\n },\n async (compilation: RspackCompilationExtended) => {\n if (!hasKeys(serverFnsById)) {\n return\n }\n\n const resolverContent =\n virtualModuleState.generateCurrentResolverContent(true)\n virtualModuleState.tryUpdateServerFnResolver(\n resolverContent,\n )\n\n await rebuildModulesContaining(\n compilation,\n virtualModuleState.serverFnResolverPath,\n )\n },\n )\n },\n })\n\n if (api.context.action !== 'dev') {\n config.plugins.push({\n apply(compiler: RspackCompiler) {\n compiler.hooks.finishMake.tapPromise(\n {\n name: 'TanStackStartRscManifestRebuild',\n // The native RSC ServerPlugin completes the client-entry\n // handoff during its finishMake hook. Rebuild the manifest\n // after that point so the transform hook can emit the final\n // manifest source instead of the placeholder.\n stage: 10,\n },\n async (compilation: RspackCompilationExtended) => {\n const clientBuild = getClientBuild()\n\n if (!clientBuild) {\n return\n }\n\n virtualModuleState.updateManifest(clientBuild)\n\n await rebuildModulesContaining(\n compilation,\n virtualModuleState.manifestPath,\n )\n },\n )\n },\n })\n }\n }\n\n if (isClientEnv) {\n // Add ClientPlugin — the Coordinator links it to the\n // ServerPlugin's compilation state\n config.plugins.push(new rscPlugins.ClientPlugin())\n }\n\n // --- SWC reactServerComponents ---\n // Enable RSC directive detection where the native RSC plugins need it.\n // In the server build, scope it to the actual RSC provider subtree so\n // ordinary route-split modules (e.g. ?tsr-split=component) stay out of\n // RSC validation unless they are really imported by a provider module.\n if (isServerEnv) {\n enableSwcReactServerComponents(config, 'rsc-subtree')\n } else if (isClientEnv) {\n enableSwcReactServerComponents(config, 'all')\n }\n })\n\n // Capture dev server reference for RSC HMR socket writes\n if (api.context.action === 'dev') {\n api.onBeforeStartDevServer(({ server }) => {\n devServerRef = server\n })\n }\n }\n\n // ---------------------------------------------------------------\n // 8. Build ordering — client must complete before server starts\n // so that the manifest virtual module has real client build stats.\n // Uses rspack MultiCompiler.setDependencies() under the hood.\n //\n // IMPORTANT: When RSC is enabled we must NOT set dependencies.\n // The RSC Coordinator already orchestrates server↔client\n // compilation ordering by interleaving phases within compiler\n // hooks. Adding setDependencies(server, [client]) on top of\n // the Coordinator creates a deadlock: MultiCompiler blocks\n // the server compiler until client is `done`, but the\n // Coordinator blocks the client's `make` hook until the\n // server's entries phase completes — neither can start.\n // ---------------------------------------------------------------\n if (!rscEnabled) {\n api.onAfterCreateCompiler(({ compiler }) => {\n // MultiCompiler has a `compilers` array; single compiler does not\n if ('compilers' in compiler) {\n const serverCompiler = compiler.compilers.find(\n (c) => c.name === RSBUILD_ENVIRONMENT_NAMES.server,\n )\n if (serverCompiler) {\n compiler.setDependencies(serverCompiler, [\n RSBUILD_ENVIRONMENT_NAMES.client,\n ])\n }\n }\n })\n }\n\n // ---------------------------------------------------------------\n // 8b. Manifest asset replacement fallback (RSC build only)\n // Rsbuild's native RSC coordinator interleaves server and client\n // compilers, so the server manifest module can compile before Start's\n // normalized client build stats exist. Keep final replacement in the\n // server asset pipeline, after the client processAssets capture has a\n // chance to run.\n // ---------------------------------------------------------------\n if (api.context.action !== 'dev' && rscEnabled) {\n const manifestPlaceholderLiteral = JSON.stringify(\n START_MANIFEST_PLACEHOLDER,\n )\n api.modifyRspackConfig((config, utils) => {\n if (utils.environment.name !== RSBUILD_ENVIRONMENT_NAMES.server)\n return\n\n config.plugins.push({\n apply(compiler: RspackCompiler) {\n compiler.hooks.compilation.tap(\n 'TanStackStartManifestReplace',\n (compilation: RspackCompilationExtended) => {\n compilation.hooks.processAssets.tap(\n {\n name: 'TanStackStartManifestReplace',\n stage:\n utils.rspack.Compilation\n .PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,\n },\n () => {\n const assetsWithPlaceholder = compilation\n .getAssets()\n .flatMap((asset) => {\n if (!asset.name.endsWith('.js')) return []\n\n const sourceStr = String(asset.source.source())\n return sourceStr.includes(manifestPlaceholderLiteral)\n ? [{ asset, sourceStr }]\n : []\n })\n\n if (assetsWithPlaceholder.length === 0) return\n\n const clientBuild = getClientBuild()\n if (!clientBuild) {\n throw new Error(\n 'TanStack Start could not replace the rsbuild RSC server manifest placeholder because the client build was unavailable',\n )\n }\n\n const manifestValueLiteral =\n virtualModuleState.generateManifestValueLiteral(\n clientBuild,\n )\n\n for (const {\n asset,\n sourceStr,\n } of assetsWithPlaceholder) {\n compilation.updateAsset(\n asset.name,\n new utils.rspack.sources.RawSource(\n sourceStr.replace(\n manifestPlaceholderLiteral,\n manifestValueLiteral,\n ),\n ),\n )\n }\n },\n )\n },\n )\n },\n })\n })\n }\n\n // ---------------------------------------------------------------\n // 9. After client env compiles — refresh resolver + manifest\n // ---------------------------------------------------------------\n api.onAfterEnvironmentCompile(({ environment }) => {\n if (environment.name !== RSBUILD_ENVIRONMENT_NAMES.client) return\n\n virtualModuleState.updateServerFnResolver()\n\n const clientBuild = getClientBuild()\n if (clientBuild) {\n virtualModuleState.updateManifest(clientBuild)\n }\n })\n\n if (api.context.action === 'build') {\n api.onAfterBuild(async () => {\n const { startConfig } = getConfig()\n\n await postBuildWithRsbuild({\n startConfig,\n clientOutputDirectory: resolvedStartConfig.outputDirectories.client,\n serverOutputDirectory: resolvedStartConfig.outputDirectories.server,\n })\n })\n }\n },\n }\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nconst defaultRspackWatchIgnored = /[\\\\/](?:\\.git|node_modules)[\\\\/]/\n\nfunction seedResolveModules(\n config: RspackConfig,\n entries: Array<string>,\n): void {\n const resolveModules = (config.resolve.modules ??= [])\n\n for (const entry of entries) {\n if (!resolveModules.includes(entry)) {\n resolveModules.push(entry)\n }\n }\n}\n\nfunction rebuildModulesContaining(\n compilation: RspackCompilationExtended,\n identifierFragment: string,\n): Promise<void> {\n const modulesToRebuild = Array.from(compilation.modules).filter((mod) =>\n mod.identifier().includes(identifierFragment),\n )\n\n if (modulesToRebuild.length === 0) {\n return Promise.resolve()\n }\n\n return Promise.all(\n modulesToRebuild.map(\n (mod) =>\n new Promise<void>((resolve, reject) => {\n compilation.rebuildModule(mod, (err: Error | null) => {\n if (err) reject(err)\n else resolve()\n })\n }),\n ),\n ).then(() => undefined)\n}\n\n/**\n * Return the realpath of every packages/<name>/dist directory in the\n * TanStack Router monorepo. Only meaningful when called from inside the\n * monorepo — in user apps, callers should guard with\n * `isInsideRouterMonoRepo` before invoking this.\n */\nfunction resolveWorkspacePackageDistRealpaths(): Array<string> {\n // currentDir points at either <repo>/packages/start-plugin-core/src/rsbuild\n // or <repo>/packages/start-plugin-core/dist/<fmt>/rsbuild. Four levels up\n // lands on <repo>/packages in both layouts.\n const packagesDir = resolve(currentDir, '../../../../')\n if (!existsSync(packagesDir)) return []\n\n let entries: Array<string>\n try {\n entries = readdirSync(packagesDir)\n } catch {\n return []\n }\n\n const dists: Array<string> = []\n for (const entry of entries) {\n const distPath = join(packagesDir, entry, 'dist')\n try {\n if (!statSync(distPath).isDirectory()) continue\n } catch {\n continue\n }\n try {\n dists.push(realpathSync(distPath))\n } catch {\n dists.push(distPath)\n }\n }\n\n return dists\n}\n"],"mappings":"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"}
|
|
@@ -224,11 +224,11 @@ export declare const tanstackStartRsbuildOptionsSchema: z.ZodDefault<z.ZodOption
|
|
|
224
224
|
};
|
|
225
225
|
entry?: string | undefined;
|
|
226
226
|
}, {
|
|
227
|
-
entry?: string | undefined;
|
|
228
227
|
build?: {
|
|
229
228
|
staticNodeEnv?: boolean | undefined;
|
|
230
229
|
inlineCss?: boolean | undefined;
|
|
231
230
|
} | undefined;
|
|
231
|
+
entry?: string | undefined;
|
|
232
232
|
}>>>;
|
|
233
233
|
serverFns: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
234
234
|
base: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
@@ -2294,11 +2294,11 @@ export declare const tanstackStartRsbuildOptionsSchema: z.ZodDefault<z.ZodOption
|
|
|
2294
2294
|
dev: z.ZodOptional<z.ZodEnum<["error", "mock"]>>;
|
|
2295
2295
|
build: z.ZodOptional<z.ZodEnum<["error", "mock"]>>;
|
|
2296
2296
|
}, "strip", z.ZodTypeAny, {
|
|
2297
|
-
build?: "error" | "mock" | undefined;
|
|
2298
2297
|
dev?: "error" | "mock" | undefined;
|
|
2299
|
-
}, {
|
|
2300
2298
|
build?: "error" | "mock" | undefined;
|
|
2299
|
+
}, {
|
|
2301
2300
|
dev?: "error" | "mock" | undefined;
|
|
2301
|
+
build?: "error" | "mock" | undefined;
|
|
2302
2302
|
}>]>>;
|
|
2303
2303
|
mockAccess: z.ZodOptional<z.ZodEnum<["error", "warn", "off"]>>;
|
|
2304
2304
|
onViolation: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodUnion<[z.ZodBoolean, z.ZodVoid, z.ZodPromise<z.ZodUnion<[z.ZodBoolean, z.ZodVoid]>>]>>>;
|
|
@@ -2347,8 +2347,8 @@ export declare const tanstackStartRsbuildOptionsSchema: z.ZodDefault<z.ZodOption
|
|
|
2347
2347
|
exclude?: (string | RegExp)[] | undefined;
|
|
2348
2348
|
enabled?: boolean | undefined;
|
|
2349
2349
|
behavior?: "error" | "mock" | {
|
|
2350
|
-
build?: "error" | "mock" | undefined;
|
|
2351
2350
|
dev?: "error" | "mock" | undefined;
|
|
2351
|
+
build?: "error" | "mock" | undefined;
|
|
2352
2352
|
} | undefined;
|
|
2353
2353
|
mockAccess?: "error" | "warn" | "off" | undefined;
|
|
2354
2354
|
onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
|
|
@@ -2370,8 +2370,8 @@ export declare const tanstackStartRsbuildOptionsSchema: z.ZodDefault<z.ZodOption
|
|
|
2370
2370
|
exclude?: (string | RegExp)[] | undefined;
|
|
2371
2371
|
enabled?: boolean | undefined;
|
|
2372
2372
|
behavior?: "error" | "mock" | {
|
|
2373
|
-
build?: "error" | "mock" | undefined;
|
|
2374
2373
|
dev?: "error" | "mock" | undefined;
|
|
2374
|
+
build?: "error" | "mock" | undefined;
|
|
2375
2375
|
} | undefined;
|
|
2376
2376
|
mockAccess?: "error" | "warn" | "off" | undefined;
|
|
2377
2377
|
onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
|
|
@@ -2400,6 +2400,12 @@ export declare const tanstackStartRsbuildOptionsSchema: z.ZodDefault<z.ZodOption
|
|
|
2400
2400
|
};
|
|
2401
2401
|
entry?: string | undefined;
|
|
2402
2402
|
};
|
|
2403
|
+
dev: {
|
|
2404
|
+
ssrStyles: {
|
|
2405
|
+
enabled: boolean;
|
|
2406
|
+
basepath?: string | undefined;
|
|
2407
|
+
};
|
|
2408
|
+
};
|
|
2403
2409
|
srcDirectory: string;
|
|
2404
2410
|
start: {
|
|
2405
2411
|
entry?: string | undefined;
|
|
@@ -2525,12 +2531,6 @@ export declare const tanstackStartRsbuildOptionsSchema: z.ZodDefault<z.ZodOption
|
|
|
2525
2531
|
headers?: Record<string, string> | undefined;
|
|
2526
2532
|
} | undefined;
|
|
2527
2533
|
}[];
|
|
2528
|
-
dev: {
|
|
2529
|
-
ssrStyles: {
|
|
2530
|
-
enabled: boolean;
|
|
2531
|
-
basepath?: string | undefined;
|
|
2532
|
-
};
|
|
2533
|
-
};
|
|
2534
2534
|
sitemap?: {
|
|
2535
2535
|
enabled: boolean;
|
|
2536
2536
|
outputPath: string;
|
|
@@ -2704,8 +2704,8 @@ export declare const tanstackStartRsbuildOptionsSchema: z.ZodDefault<z.ZodOption
|
|
|
2704
2704
|
exclude?: (string | RegExp)[] | undefined;
|
|
2705
2705
|
enabled?: boolean | undefined;
|
|
2706
2706
|
behavior?: "error" | "mock" | {
|
|
2707
|
-
build?: "error" | "mock" | undefined;
|
|
2708
2707
|
dev?: "error" | "mock" | undefined;
|
|
2708
|
+
build?: "error" | "mock" | undefined;
|
|
2709
2709
|
} | undefined;
|
|
2710
2710
|
mockAccess?: "error" | "warn" | "off" | undefined;
|
|
2711
2711
|
onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
|
|
@@ -2723,11 +2723,17 @@ export declare const tanstackStartRsbuildOptionsSchema: z.ZodDefault<z.ZodOption
|
|
|
2723
2723
|
base?: string | undefined;
|
|
2724
2724
|
} | undefined;
|
|
2725
2725
|
server?: {
|
|
2726
|
-
entry?: string | undefined;
|
|
2727
2726
|
build?: {
|
|
2728
2727
|
staticNodeEnv?: boolean | undefined;
|
|
2729
2728
|
inlineCss?: boolean | undefined;
|
|
2730
2729
|
} | undefined;
|
|
2730
|
+
entry?: string | undefined;
|
|
2731
|
+
} | undefined;
|
|
2732
|
+
dev?: {
|
|
2733
|
+
ssrStyles?: {
|
|
2734
|
+
basepath?: string | undefined;
|
|
2735
|
+
enabled?: boolean | undefined;
|
|
2736
|
+
} | undefined;
|
|
2731
2737
|
} | undefined;
|
|
2732
2738
|
srcDirectory?: string | undefined;
|
|
2733
2739
|
start?: {
|
|
@@ -2970,12 +2976,6 @@ export declare const tanstackStartRsbuildOptionsSchema: z.ZodDefault<z.ZodOption
|
|
|
2970
2976
|
headers?: Record<string, string> | undefined;
|
|
2971
2977
|
} | undefined;
|
|
2972
2978
|
}[] | undefined;
|
|
2973
|
-
dev?: {
|
|
2974
|
-
ssrStyles?: {
|
|
2975
|
-
basepath?: string | undefined;
|
|
2976
|
-
enabled?: boolean | undefined;
|
|
2977
|
-
} | undefined;
|
|
2978
|
-
} | undefined;
|
|
2979
2979
|
spa?: {
|
|
2980
2980
|
enabled?: boolean | undefined;
|
|
2981
2981
|
prerender?: {
|
|
@@ -3033,8 +3033,8 @@ export declare const tanstackStartRsbuildOptionsSchema: z.ZodDefault<z.ZodOption
|
|
|
3033
3033
|
exclude?: (string | RegExp)[] | undefined;
|
|
3034
3034
|
enabled?: boolean | undefined;
|
|
3035
3035
|
behavior?: "error" | "mock" | {
|
|
3036
|
-
build?: "error" | "mock" | undefined;
|
|
3037
3036
|
dev?: "error" | "mock" | undefined;
|
|
3037
|
+
build?: "error" | "mock" | undefined;
|
|
3038
3038
|
} | undefined;
|
|
3039
3039
|
mockAccess?: "error" | "warn" | "off" | undefined;
|
|
3040
3040
|
onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
|
|
@@ -3110,6 +3110,12 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartRsbui
|
|
|
3110
3110
|
};
|
|
3111
3111
|
entry?: string | undefined;
|
|
3112
3112
|
};
|
|
3113
|
+
dev: {
|
|
3114
|
+
ssrStyles: {
|
|
3115
|
+
enabled: boolean;
|
|
3116
|
+
basepath?: string | undefined;
|
|
3117
|
+
};
|
|
3118
|
+
};
|
|
3113
3119
|
srcDirectory: string;
|
|
3114
3120
|
start: {
|
|
3115
3121
|
entry?: string | undefined;
|
|
@@ -3187,12 +3193,6 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartRsbui
|
|
|
3187
3193
|
headers?: Record<string, string> | undefined;
|
|
3188
3194
|
} | undefined;
|
|
3189
3195
|
}[];
|
|
3190
|
-
dev: {
|
|
3191
|
-
ssrStyles: {
|
|
3192
|
-
enabled: boolean;
|
|
3193
|
-
basepath?: string | undefined;
|
|
3194
|
-
};
|
|
3195
|
-
};
|
|
3196
3196
|
sitemap?: {
|
|
3197
3197
|
enabled: boolean;
|
|
3198
3198
|
outputPath: string;
|
|
@@ -3366,8 +3366,8 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartRsbui
|
|
|
3366
3366
|
exclude?: (string | RegExp)[] | undefined;
|
|
3367
3367
|
enabled?: boolean | undefined;
|
|
3368
3368
|
behavior?: "error" | "mock" | {
|
|
3369
|
-
build?: "error" | "mock" | undefined;
|
|
3370
3369
|
dev?: "error" | "mock" | undefined;
|
|
3370
|
+
build?: "error" | "mock" | undefined;
|
|
3371
3371
|
} | undefined;
|
|
3372
3372
|
mockAccess?: "error" | "warn" | "off" | undefined;
|
|
3373
3373
|
onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { RsbuildPluginAPI } from '@rsbuild/core';
|
|
2
|
-
import { CompileStartFrameworkOptions } from '../types.js';
|
|
2
|
+
import { CompileStartFrameworkOptions, StartCompilerImportTransform } from '../types.js';
|
|
3
3
|
import { GenerateFunctionIdFnOptional, ServerFn } from '../start-compiler/types.js';
|
|
4
4
|
export interface StartCompilerHostOptions {
|
|
5
5
|
framework: CompileStartFrameworkOptions;
|
|
6
6
|
root: string | (() => string);
|
|
7
7
|
providerEnvName: string;
|
|
8
8
|
generateFunctionId?: GenerateFunctionIdFnOptional;
|
|
9
|
+
compilerTransforms?: Array<StartCompilerImportTransform> | undefined;
|
|
10
|
+
serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined;
|
|
9
11
|
serverFnsById?: Record<string, ServerFn>;
|
|
10
12
|
onServerFnsByIdChange?: () => void;
|
|
11
13
|
}
|
|
@@ -40,10 +40,12 @@ function registerStartCompilerTransforms(api, opts) {
|
|
|
40
40
|
}];
|
|
41
41
|
const codeFilters = {
|
|
42
42
|
client: getTransformCodeFilterForEnv("client"),
|
|
43
|
-
server: getTransformCodeFilterForEnv("server")
|
|
43
|
+
server: getTransformCodeFilterForEnv("server", { compilerTransforms: opts.compilerTransforms })
|
|
44
44
|
};
|
|
45
45
|
for (const env of environments) {
|
|
46
46
|
const envCodeFilters = codeFilters[env.type];
|
|
47
|
+
const compilerTransforms = env.name === RSBUILD_ENVIRONMENT_NAMES.server ? opts.compilerTransforms : void 0;
|
|
48
|
+
const serverFnProviderModuleDirectives = env.name === opts.providerEnvName ? opts.serverFnProviderModuleDirectives : void 0;
|
|
47
49
|
api.transform({
|
|
48
50
|
test: TRANSFORM_ID_REGEX[0],
|
|
49
51
|
environments: [env.name],
|
|
@@ -64,6 +66,8 @@ function registerStartCompilerTransforms(api, opts) {
|
|
|
64
66
|
framework: opts.framework,
|
|
65
67
|
providerEnvName: opts.providerEnvName,
|
|
66
68
|
generateFunctionId: opts.generateFunctionId,
|
|
69
|
+
compilerTransforms,
|
|
70
|
+
serverFnProviderModuleDirectives,
|
|
67
71
|
onServerFnsById,
|
|
68
72
|
getKnownServerFns: () => serverFnsById,
|
|
69
73
|
encodeModuleSpecifierInDev: isDev ? rsbuildDevServerFnModuleSpecifierEncoder : void 0,
|
|
@@ -102,7 +106,7 @@ function registerStartCompilerTransforms(api, opts) {
|
|
|
102
106
|
});
|
|
103
107
|
compilers.set(env.name, compiler);
|
|
104
108
|
}
|
|
105
|
-
const detectedKinds = detectKindsInCode(code, env.type);
|
|
109
|
+
const detectedKinds = detectKindsInCode(code, env.type, { compilerTransforms });
|
|
106
110
|
const result = await compiler.compile({
|
|
107
111
|
id,
|
|
108
112
|
code,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-compiler-host.js","names":[],"sources":["../../../src/rsbuild/start-compiler-host.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport { pathToFileURL } from 'node:url'\nimport { TRANSFORM_ID_REGEX } from '../constants'\nimport { detectKindsInCode } from '../start-compiler/compiler'\nimport { getTransformCodeFilterForEnv } from '../start-compiler/config'\nimport {\n createStartCompiler,\n matchesCodeFilters,\n mergeServerFnsById,\n} from '../start-compiler/host'\nimport { cleanId } from '../start-compiler/utils'\nimport { RSBUILD_ENVIRONMENT_NAMES } from './planning'\nimport type { RsbuildPluginAPI, Rspack } from '@rsbuild/core'\nimport type { CompileStartFrameworkOptions } from '../types'\nimport type {\n DevServerFnModuleSpecifierEncoder,\n GenerateFunctionIdFnOptional,\n ServerFn,\n} from '../start-compiler/types'\n\ntype RsbuildTransformContext = Parameters<\n Parameters<RsbuildPluginAPI['transform']>[1]\n>[0]\ntype RsbuildInputFileSystem = NonNullable<Rspack.Compiler['inputFileSystem']>\n\n/**\n * Rsbuild dev server fn ref strategy: uses file:// URLs for absolute paths.\n * These are directly importable by Node's ESM VM runner without any bundler\n * path conventions (unlike Vite's /@id/ prefix).\n */\nconst rsbuildDevServerFnModuleSpecifierEncoder: DevServerFnModuleSpecifierEncoder =\n ({ extractedFilename }) => pathToFileURL(extractedFilename).href\n\nexport interface StartCompilerHostOptions {\n framework: CompileStartFrameworkOptions\n root: string | (() => string)\n providerEnvName: string\n generateFunctionId?: GenerateFunctionIdFnOptional\n serverFnsById?: Record<string, ServerFn>\n onServerFnsByIdChange?: () => void\n}\n\n/**\n * Registers the shared StartCompiler as rsbuild transforms for client + ssr environments.\n *\n * Uses `api.transform()` to hook into the rsbuild loader pipeline, and the\n * transform context's native `resolve()` for module resolution.\n */\nexport function registerStartCompilerTransforms(\n api: RsbuildPluginAPI,\n opts: StartCompilerHostOptions,\n): {\n serverFnsById: Record<string, ServerFn>\n} {\n const compilers = new Map<string, ReturnType<typeof createStartCompiler>>()\n const inputFileSystems = new Map<string, RsbuildInputFileSystem>()\n const transformContextStorage =\n new AsyncLocalStorage<RsbuildTransformContext>()\n const serverFnsById = opts.serverFnsById ?? {}\n const getRoot = () =>\n typeof opts.root === 'function' ? opts.root() : opts.root\n\n const onServerFnsById = (d: Record<string, ServerFn>) => {\n mergeServerFnsById(serverFnsById, d)\n opts.onServerFnsByIdChange?.()\n }\n\n const isDev = api.context.action === 'dev'\n const mode = isDev ? 'dev' : 'build'\n\n const environments: Array<{\n name: string\n type: 'client' | 'server'\n }> = [\n { name: RSBUILD_ENVIRONMENT_NAMES.client, type: 'client' },\n { name: RSBUILD_ENVIRONMENT_NAMES.server, type: 'server' },\n ]\n\n // Pre-compute code filter patterns per environment type\n const codeFilters: Record<'client' | 'server', Array<RegExp>> = {\n client: getTransformCodeFilterForEnv('client'),\n server: getTransformCodeFilterForEnv('server'),\n }\n\n for (const env of environments) {\n const envCodeFilters = codeFilters[env.type]\n\n api.transform(\n {\n test: TRANSFORM_ID_REGEX[0],\n environments: [env.name],\n order: 'pre',\n },\n async (ctx: RsbuildTransformContext) => {\n return transformContextStorage.run(ctx, async () => {\n const code = ctx.code\n const id = ctx.resourcePath + (ctx.resourceQuery || '')\n\n // Quick string-level check: does this file contain any patterns for this env?\n if (!matchesCodeFilters(code, envCodeFilters)) {\n return code\n }\n\n let compiler = compilers.get(env.name)\n if (!compiler) {\n const root = getRoot()\n\n compiler = createStartCompiler({\n env: env.type,\n envName: env.name,\n root,\n mode,\n framework: opts.framework,\n providerEnvName: opts.providerEnvName,\n generateFunctionId: opts.generateFunctionId,\n onServerFnsById,\n getKnownServerFns: () => serverFnsById,\n encodeModuleSpecifierInDev: isDev\n ? rsbuildDevServerFnModuleSpecifierEncoder\n : undefined,\n loadModule: async (moduleId: string) => {\n const activeCtx = transformContextStorage.getStore()\n if (!activeCtx) {\n throw new Error(\n `could not load module ${moduleId}: missing active rsbuild transform context for ${env.name}`,\n )\n }\n\n const inputFileSystem = inputFileSystems.get(env.name)\n if (!inputFileSystem) {\n throw new Error(\n `could not load module ${moduleId}: missing rspack input filesystem for ${env.name}`,\n )\n }\n\n const cleanedId = cleanId(moduleId)\n activeCtx.addDependency(cleanedId)\n const loaded = await readFileFromInputFileSystem(\n inputFileSystem,\n cleanedId,\n )\n const moduleCode = Buffer.isBuffer(loaded)\n ? loaded.toString('utf8')\n : loaded\n\n compiler!.ingestModule({ code: moduleCode, id: cleanedId })\n },\n resolveId: async (\n source: string,\n importer?: string,\n ): Promise<string | null> => {\n const activeCtx = transformContextStorage.getStore()\n if (!activeCtx) {\n throw new Error(\n `could not resolve ${source}: missing active rsbuild transform context for ${env.name}`,\n )\n }\n\n const context = importer\n ? importer.replace(/[/\\\\][^/\\\\]*$/, '')\n : getRoot()\n\n return await new Promise((resolve, reject) => {\n activeCtx.resolve(context, source, (error, resolved) => {\n if (error) {\n reject(error)\n return\n }\n\n if (!resolved) {\n resolve(null)\n return\n }\n\n resolve(cleanId(resolved))\n })\n })\n },\n })\n compilers.set(env.name, compiler)\n }\n\n const detectedKinds = detectKindsInCode(code, env.type)\n const result = await compiler.compile({ id, code, detectedKinds })\n\n if (!result) {\n return code\n }\n\n return {\n code: result.code,\n map: result.map ?? null,\n }\n })\n },\n )\n }\n\n api.modifyRspackConfig((config, utils) => {\n config.plugins.push({\n apply(compiler: Rspack.Compiler) {\n if (compiler.inputFileSystem) {\n inputFileSystems.set(utils.environment.name, compiler.inputFileSystem)\n }\n\n compiler.hooks.watchRun.tap(\n 'TanStackStartCompilerModuleInvalidation',\n (watchCompiler) => {\n const startCompiler = compilers.get(utils.environment.name)\n\n if (!startCompiler) {\n return\n }\n\n for (const file of watchCompiler.modifiedFiles ?? []) {\n startCompiler.invalidateModule(file)\n }\n\n for (const file of watchCompiler.removedFiles ?? []) {\n startCompiler.invalidateModule(file)\n }\n },\n )\n },\n })\n })\n\n return { serverFnsById }\n}\n\nfunction readFileFromInputFileSystem(\n inputFileSystem: RsbuildInputFileSystem,\n file: string,\n): Promise<string | Buffer> {\n return new Promise((resolve, reject) => {\n inputFileSystem.readFile(file, (error, data) => {\n if (error) {\n reject(error)\n return\n }\n\n if (data == null) {\n reject(new Error(`could not read module source for ${file}`))\n return\n }\n\n resolve(data)\n })\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"start-compiler-host.js","names":[],"sources":["../../../src/rsbuild/start-compiler-host.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport { pathToFileURL } from 'node:url'\nimport { TRANSFORM_ID_REGEX } from '../constants'\nimport { detectKindsInCode } from '../start-compiler/compiler'\nimport { getTransformCodeFilterForEnv } from '../start-compiler/config'\nimport {\n createStartCompiler,\n matchesCodeFilters,\n mergeServerFnsById,\n} from '../start-compiler/host'\nimport { cleanId } from '../start-compiler/utils'\nimport { RSBUILD_ENVIRONMENT_NAMES } from './planning'\nimport type { RsbuildPluginAPI, Rspack } from '@rsbuild/core'\nimport type {\n CompileStartFrameworkOptions,\n StartCompilerImportTransform,\n} from '../types'\nimport type {\n DevServerFnModuleSpecifierEncoder,\n GenerateFunctionIdFnOptional,\n ServerFn,\n} from '../start-compiler/types'\n\ntype RsbuildTransformContext = Parameters<\n Parameters<RsbuildPluginAPI['transform']>[1]\n>[0]\ntype RsbuildInputFileSystem = NonNullable<Rspack.Compiler['inputFileSystem']>\n\n/**\n * Rsbuild dev server fn ref strategy: uses file:// URLs for absolute paths.\n * These are directly importable by Node's ESM VM runner without any bundler\n * path conventions (unlike Vite's /@id/ prefix).\n */\nconst rsbuildDevServerFnModuleSpecifierEncoder: DevServerFnModuleSpecifierEncoder =\n ({ extractedFilename }) => pathToFileURL(extractedFilename).href\n\nexport interface StartCompilerHostOptions {\n framework: CompileStartFrameworkOptions\n root: string | (() => string)\n providerEnvName: string\n generateFunctionId?: GenerateFunctionIdFnOptional\n compilerTransforms?: Array<StartCompilerImportTransform> | undefined\n serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined\n serverFnsById?: Record<string, ServerFn>\n onServerFnsByIdChange?: () => void\n}\n\n/**\n * Registers the shared StartCompiler as rsbuild transforms for client + ssr environments.\n *\n * Uses `api.transform()` to hook into the rsbuild loader pipeline, and the\n * transform context's native `resolve()` for module resolution.\n */\nexport function registerStartCompilerTransforms(\n api: RsbuildPluginAPI,\n opts: StartCompilerHostOptions,\n): {\n serverFnsById: Record<string, ServerFn>\n} {\n const compilers = new Map<string, ReturnType<typeof createStartCompiler>>()\n const inputFileSystems = new Map<string, RsbuildInputFileSystem>()\n const transformContextStorage =\n new AsyncLocalStorage<RsbuildTransformContext>()\n const serverFnsById = opts.serverFnsById ?? {}\n const getRoot = () =>\n typeof opts.root === 'function' ? opts.root() : opts.root\n\n const onServerFnsById = (d: Record<string, ServerFn>) => {\n mergeServerFnsById(serverFnsById, d)\n opts.onServerFnsByIdChange?.()\n }\n\n const isDev = api.context.action === 'dev'\n const mode = isDev ? 'dev' : 'build'\n\n const environments: Array<{\n name: string\n type: 'client' | 'server'\n }> = [\n { name: RSBUILD_ENVIRONMENT_NAMES.client, type: 'client' },\n { name: RSBUILD_ENVIRONMENT_NAMES.server, type: 'server' },\n ]\n\n // Pre-compute code filter patterns per environment type\n const codeFilters: Record<'client' | 'server', Array<RegExp>> = {\n client: getTransformCodeFilterForEnv('client'),\n server: getTransformCodeFilterForEnv('server', {\n compilerTransforms: opts.compilerTransforms,\n }),\n }\n\n for (const env of environments) {\n const envCodeFilters = codeFilters[env.type]\n const compilerTransforms =\n env.name === RSBUILD_ENVIRONMENT_NAMES.server\n ? opts.compilerTransforms\n : undefined\n const serverFnProviderModuleDirectives =\n env.name === opts.providerEnvName\n ? opts.serverFnProviderModuleDirectives\n : undefined\n\n api.transform(\n {\n test: TRANSFORM_ID_REGEX[0],\n environments: [env.name],\n order: 'pre',\n },\n async (ctx: RsbuildTransformContext) => {\n return transformContextStorage.run(ctx, async () => {\n const code = ctx.code\n const id = ctx.resourcePath + (ctx.resourceQuery || '')\n\n // Quick string-level check: does this file contain any patterns for this env?\n if (!matchesCodeFilters(code, envCodeFilters)) {\n return code\n }\n\n let compiler = compilers.get(env.name)\n if (!compiler) {\n const root = getRoot()\n\n compiler = createStartCompiler({\n env: env.type,\n envName: env.name,\n root,\n mode,\n framework: opts.framework,\n providerEnvName: opts.providerEnvName,\n generateFunctionId: opts.generateFunctionId,\n compilerTransforms,\n serverFnProviderModuleDirectives,\n onServerFnsById,\n getKnownServerFns: () => serverFnsById,\n encodeModuleSpecifierInDev: isDev\n ? rsbuildDevServerFnModuleSpecifierEncoder\n : undefined,\n loadModule: async (moduleId: string) => {\n const activeCtx = transformContextStorage.getStore()\n if (!activeCtx) {\n throw new Error(\n `could not load module ${moduleId}: missing active rsbuild transform context for ${env.name}`,\n )\n }\n\n const inputFileSystem = inputFileSystems.get(env.name)\n if (!inputFileSystem) {\n throw new Error(\n `could not load module ${moduleId}: missing rspack input filesystem for ${env.name}`,\n )\n }\n\n const cleanedId = cleanId(moduleId)\n activeCtx.addDependency(cleanedId)\n const loaded = await readFileFromInputFileSystem(\n inputFileSystem,\n cleanedId,\n )\n const moduleCode = Buffer.isBuffer(loaded)\n ? loaded.toString('utf8')\n : loaded\n\n compiler!.ingestModule({ code: moduleCode, id: cleanedId })\n },\n resolveId: async (\n source: string,\n importer?: string,\n ): Promise<string | null> => {\n const activeCtx = transformContextStorage.getStore()\n if (!activeCtx) {\n throw new Error(\n `could not resolve ${source}: missing active rsbuild transform context for ${env.name}`,\n )\n }\n\n const context = importer\n ? importer.replace(/[/\\\\][^/\\\\]*$/, '')\n : getRoot()\n\n return await new Promise((resolve, reject) => {\n activeCtx.resolve(context, source, (error, resolved) => {\n if (error) {\n reject(error)\n return\n }\n\n if (!resolved) {\n resolve(null)\n return\n }\n\n resolve(cleanId(resolved))\n })\n })\n },\n })\n compilers.set(env.name, compiler)\n }\n\n const detectedKinds = detectKindsInCode(code, env.type, {\n compilerTransforms,\n })\n const result = await compiler.compile({ id, code, detectedKinds })\n\n if (!result) {\n return code\n }\n\n return {\n code: result.code,\n map: result.map ?? null,\n }\n })\n },\n )\n }\n\n api.modifyRspackConfig((config, utils) => {\n config.plugins.push({\n apply(compiler: Rspack.Compiler) {\n if (compiler.inputFileSystem) {\n inputFileSystems.set(utils.environment.name, compiler.inputFileSystem)\n }\n\n compiler.hooks.watchRun.tap(\n 'TanStackStartCompilerModuleInvalidation',\n (watchCompiler) => {\n const startCompiler = compilers.get(utils.environment.name)\n\n if (!startCompiler) {\n return\n }\n\n for (const file of watchCompiler.modifiedFiles ?? []) {\n startCompiler.invalidateModule(file)\n }\n\n for (const file of watchCompiler.removedFiles ?? []) {\n startCompiler.invalidateModule(file)\n }\n },\n )\n },\n })\n })\n\n return { serverFnsById }\n}\n\nfunction readFileFromInputFileSystem(\n inputFileSystem: RsbuildInputFileSystem,\n file: string,\n): Promise<string | Buffer> {\n return new Promise((resolve, reject) => {\n inputFileSystem.readFile(file, (error, data) => {\n if (error) {\n reject(error)\n return\n }\n\n if (data == null) {\n reject(new Error(`could not read module source for ${file}`))\n return\n }\n\n resolve(data)\n })\n })\n}\n"],"mappings":"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"}
|
|
@@ -8,8 +8,6 @@ import { TanStackStartRsbuildInputConfig } from './schema.js';
|
|
|
8
8
|
* The router-plugin package exports rspack-compatible unplugin wrappers:
|
|
9
9
|
* - TanStackRouterGeneratorRspack: file-based route generation
|
|
10
10
|
* - TanStackRouterCodeSplitterRspack: route code splitting
|
|
11
|
-
*
|
|
12
|
-
* These are dynamically imported to avoid hard dependency on router-plugin/rspack.
|
|
13
11
|
*/
|
|
14
12
|
export declare function registerRouterPlugins(api: RsbuildPluginAPI, opts: {
|
|
15
13
|
getConfig: GetConfigFn;
|
|
@@ -3,6 +3,8 @@ import { prerenderRoutesPlugin } from "../start-router-plugin/generator-plugins/
|
|
|
3
3
|
import { buildRouteTreeFileFooterFromConfig } from "../start-router-plugin/route-tree-footer.js";
|
|
4
4
|
import { RSBUILD_ENVIRONMENT_NAMES } from "./planning.js";
|
|
5
5
|
import path from "pathe";
|
|
6
|
+
import { createRouterPluginContext } from "@tanstack/router-plugin/context";
|
|
7
|
+
import { TanStackRouterCodeSplitterRspack, TanStackRouterGeneratorRspack } from "@tanstack/router-plugin/rspack";
|
|
6
8
|
//#region src/rsbuild/start-router-plugin.ts
|
|
7
9
|
/**
|
|
8
10
|
* Registers the TanStack Router generator and code-splitter plugins
|
|
@@ -11,16 +13,14 @@ import path from "pathe";
|
|
|
11
13
|
* The router-plugin package exports rspack-compatible unplugin wrappers:
|
|
12
14
|
* - TanStackRouterGeneratorRspack: file-based route generation
|
|
13
15
|
* - TanStackRouterCodeSplitterRspack: route code splitting
|
|
14
|
-
*
|
|
15
|
-
* These are dynamically imported to avoid hard dependency on router-plugin/rspack.
|
|
16
16
|
*/
|
|
17
17
|
function registerRouterPlugins(api, opts) {
|
|
18
|
-
|
|
18
|
+
const routerPluginContext = createRouterPluginContext();
|
|
19
|
+
api.modifyRspackConfig((config, utils) => {
|
|
19
20
|
const envName = utils.environment.name;
|
|
20
21
|
const { startConfig } = opts.getConfig();
|
|
21
22
|
const routerConfig = startConfig.router;
|
|
22
|
-
if (envName === RSBUILD_ENVIRONMENT_NAMES.client)
|
|
23
|
-
const { TanStackRouterGeneratorRspack } = await import("@tanstack/router-plugin/rspack");
|
|
23
|
+
if (envName === RSBUILD_ENVIRONMENT_NAMES.client) {
|
|
24
24
|
const generatorPlugin = TanStackRouterGeneratorRspack({
|
|
25
25
|
...routerConfig,
|
|
26
26
|
target: opts.corePluginOpts.framework,
|
|
@@ -32,28 +32,25 @@ function registerRouterPlugins(api, opts) {
|
|
|
32
32
|
});
|
|
33
33
|
},
|
|
34
34
|
plugins: [routesManifestPlugin(), ...opts.startPluginOpts?.prerender?.enabled === true ? [prerenderRoutesPlugin()] : []]
|
|
35
|
-
});
|
|
35
|
+
}, routerPluginContext);
|
|
36
36
|
utils.appendPlugins(generatorPlugin);
|
|
37
|
-
}
|
|
37
|
+
}
|
|
38
38
|
if (envName === RSBUILD_ENVIRONMENT_NAMES.client || envName === RSBUILD_ENVIRONMENT_NAMES.server) {
|
|
39
39
|
const isClient = envName === RSBUILD_ENVIRONMENT_NAMES.client;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
});
|
|
55
|
-
utils.appendPlugins(splitterPlugin);
|
|
56
|
-
} catch {}
|
|
40
|
+
const splitterPlugin = TanStackRouterCodeSplitterRspack({
|
|
41
|
+
...routerConfig,
|
|
42
|
+
target: opts.corePluginOpts.framework,
|
|
43
|
+
codeSplittingOptions: {
|
|
44
|
+
...routerConfig.codeSplittingOptions,
|
|
45
|
+
deleteNodes: isClient ? [
|
|
46
|
+
"ssr",
|
|
47
|
+
"server",
|
|
48
|
+
"headers"
|
|
49
|
+
] : void 0,
|
|
50
|
+
addHmr: isClient
|
|
51
|
+
}
|
|
52
|
+
}, routerPluginContext);
|
|
53
|
+
utils.appendPlugins(splitterPlugin);
|
|
57
54
|
}
|
|
58
55
|
});
|
|
59
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-router-plugin.js","names":[],"sources":["../../../src/rsbuild/start-router-plugin.ts"],"sourcesContent":["import path from 'pathe'\nimport { routesManifestPlugin } from '../start-router-plugin/generator-plugins/routes-manifest-plugin'\nimport { prerenderRoutesPlugin } from '../start-router-plugin/generator-plugins/prerender-routes-plugin'\nimport { buildRouteTreeFileFooterFromConfig } from '../start-router-plugin/route-tree-footer'\nimport { RSBUILD_ENVIRONMENT_NAMES } from './planning'\nimport type { RsbuildPluginAPI } from '@rsbuild/core'\nimport type { GetConfigFn, TanStackStartCoreOptions } from '../types'\nimport type { TanStackStartRsbuildInputConfig } from './schema'\n\n/**\n * Registers the TanStack Router generator and code-splitter plugins\n * as rspack plugins via `modifyRspackConfig`.\n *\n * The router-plugin package exports rspack-compatible unplugin wrappers:\n * - TanStackRouterGeneratorRspack: file-based route generation\n * - TanStackRouterCodeSplitterRspack: route code splitting\n
|
|
1
|
+
{"version":3,"file":"start-router-plugin.js","names":[],"sources":["../../../src/rsbuild/start-router-plugin.ts"],"sourcesContent":["import path from 'pathe'\nimport { createRouterPluginContext } from '@tanstack/router-plugin/context'\nimport {\n TanStackRouterCodeSplitterRspack,\n TanStackRouterGeneratorRspack,\n} from '@tanstack/router-plugin/rspack'\nimport { routesManifestPlugin } from '../start-router-plugin/generator-plugins/routes-manifest-plugin'\nimport { prerenderRoutesPlugin } from '../start-router-plugin/generator-plugins/prerender-routes-plugin'\nimport { buildRouteTreeFileFooterFromConfig } from '../start-router-plugin/route-tree-footer'\nimport { RSBUILD_ENVIRONMENT_NAMES } from './planning'\nimport type { RsbuildPluginAPI } from '@rsbuild/core'\nimport type { GetConfigFn, TanStackStartCoreOptions } from '../types'\nimport type { TanStackStartRsbuildInputConfig } from './schema'\n\n/**\n * Registers the TanStack Router generator and code-splitter plugins\n * as rspack plugins via `modifyRspackConfig`.\n *\n * The router-plugin package exports rspack-compatible unplugin wrappers:\n * - TanStackRouterGeneratorRspack: file-based route generation\n * - TanStackRouterCodeSplitterRspack: route code splitting\n */\nexport function registerRouterPlugins(\n api: RsbuildPluginAPI,\n opts: {\n getConfig: GetConfigFn\n corePluginOpts: TanStackStartCoreOptions\n startPluginOpts: TanStackStartRsbuildInputConfig\n },\n): void {\n const routerPluginContext = createRouterPluginContext()\n\n api.modifyRspackConfig((config, utils) => {\n const envName = utils.environment.name\n const { startConfig } = opts.getConfig()\n const routerConfig = startConfig.router\n\n // Generator only runs once — register for the client environment\n if (envName === RSBUILD_ENVIRONMENT_NAMES.client) {\n const generatorPlugin = TanStackRouterGeneratorRspack(\n {\n ...routerConfig,\n target: opts.corePluginOpts.framework,\n routeTreeFileFooter: () => {\n return buildRouteTreeFileFooterFromConfig({\n generatedRouteTreePath: path.resolve(\n routerConfig.generatedRouteTree,\n ),\n getConfig: opts.getConfig,\n corePluginOpts: opts.corePluginOpts,\n })\n },\n plugins: [\n routesManifestPlugin(),\n ...(opts.startPluginOpts?.prerender?.enabled === true\n ? [prerenderRoutesPlugin()]\n : []),\n ],\n },\n routerPluginContext,\n )\n utils.appendPlugins(generatorPlugin as any)\n }\n\n if (\n envName === RSBUILD_ENVIRONMENT_NAMES.client ||\n envName === RSBUILD_ENVIRONMENT_NAMES.server\n ) {\n const isClient = envName === RSBUILD_ENVIRONMENT_NAMES.client\n const splitterPlugin = TanStackRouterCodeSplitterRspack(\n {\n ...routerConfig,\n target: opts.corePluginOpts.framework,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n deleteNodes: isClient ? ['ssr', 'server', 'headers'] : undefined,\n addHmr: isClient,\n },\n },\n routerPluginContext,\n )\n utils.appendPlugins(splitterPlugin as any)\n }\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAsBA,SAAgB,sBACd,KACA,MAKM;CACN,MAAM,sBAAsB,2BAA2B;AAEvD,KAAI,oBAAoB,QAAQ,UAAU;EACxC,MAAM,UAAU,MAAM,YAAY;EAClC,MAAM,EAAE,gBAAgB,KAAK,WAAW;EACxC,MAAM,eAAe,YAAY;AAGjC,MAAI,YAAY,0BAA0B,QAAQ;GAChD,MAAM,kBAAkB,8BACtB;IACE,GAAG;IACH,QAAQ,KAAK,eAAe;IAC5B,2BAA2B;AACzB,YAAO,mCAAmC;MACxC,wBAAwB,KAAK,QAC3B,aAAa,mBACd;MACD,WAAW,KAAK;MAChB,gBAAgB,KAAK;MACtB,CAAC;;IAEJ,SAAS,CACP,sBAAsB,EACtB,GAAI,KAAK,iBAAiB,WAAW,YAAY,OAC7C,CAAC,uBAAuB,CAAC,GACzB,EAAE,CACP;IACF,EACD,oBACD;AACD,SAAM,cAAc,gBAAuB;;AAG7C,MACE,YAAY,0BAA0B,UACtC,YAAY,0BAA0B,QACtC;GACA,MAAM,WAAW,YAAY,0BAA0B;GACvD,MAAM,iBAAiB,iCACrB;IACE,GAAG;IACH,QAAQ,KAAK,eAAe;IAC5B,sBAAsB;KACpB,GAAG,aAAa;KAChB,aAAa,WAAW;MAAC;MAAO;MAAU;MAAU,GAAG,KAAA;KACvD,QAAQ;KACT;IACF,EACD,oBACD;AACD,SAAM,cAAc,eAAsB;;GAE5C"}
|