@tanstack/start-plugin-core 1.169.13 → 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.
@@ -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
- api.modifyRspackConfig(async (config, utils) => {
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) try {
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
- } catch {}
37
+ }
38
38
  if (envName === RSBUILD_ENVIRONMENT_NAMES.client || envName === RSBUILD_ENVIRONMENT_NAMES.server) {
39
39
  const isClient = envName === RSBUILD_ENVIRONMENT_NAMES.client;
40
- try {
41
- const { TanStackRouterCodeSplitterRspack } = await import("@tanstack/router-plugin/rspack");
42
- const splitterPlugin = TanStackRouterCodeSplitterRspack({
43
- ...routerConfig,
44
- target: opts.corePluginOpts.framework,
45
- codeSplittingOptions: {
46
- ...routerConfig.codeSplittingOptions,
47
- deleteNodes: isClient ? [
48
- "ssr",
49
- "server",
50
- "headers"
51
- ] : void 0,
52
- addHmr: isClient
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 *\n * These are dynamically imported to avoid hard dependency on router-plugin/rspack.\n */\nexport function registerRouterPlugins(\n api: RsbuildPluginAPI,\n opts: {\n getConfig: GetConfigFn\n corePluginOpts: TanStackStartCoreOptions\n startPluginOpts: TanStackStartRsbuildInputConfig\n },\n): void {\n api.modifyRspackConfig(async (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 try {\n const { TanStackRouterGeneratorRspack } =\n await import('@tanstack/router-plugin/rspack')\n const generatorPlugin = TanStackRouterGeneratorRspack({\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 utils.appendPlugins(generatorPlugin as any)\n } catch {\n // router-plugin/rspack not available — skip\n }\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 try {\n const { TanStackRouterCodeSplitterRspack } =\n await import('@tanstack/router-plugin/rspack')\n const splitterPlugin = TanStackRouterCodeSplitterRspack({\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 utils.appendPlugins(splitterPlugin as any)\n } catch {\n // router-plugin/rspack not available — skip\n }\n }\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,SAAgB,sBACd,KACA,MAKM;AACN,KAAI,mBAAmB,OAAO,QAAQ,UAAU;EAC9C,MAAM,UAAU,MAAM,YAAY;EAClC,MAAM,EAAE,gBAAgB,KAAK,WAAW;EACxC,MAAM,eAAe,YAAY;AAGjC,MAAI,YAAY,0BAA0B,OACxC,KAAI;GACF,MAAM,EAAE,kCACN,MAAM,OAAO;GACf,MAAM,kBAAkB,8BAA8B;IACpD,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,CAAC;AACF,SAAM,cAAc,gBAAuB;UACrC;AAKV,MACE,YAAY,0BAA0B,UACtC,YAAY,0BAA0B,QACtC;GACA,MAAM,WAAW,YAAY,0BAA0B;AACvD,OAAI;IACF,MAAM,EAAE,qCACN,MAAM,OAAO;IACf,MAAM,iBAAiB,iCAAiC;KACtD,GAAG;KACH,QAAQ,KAAK,eAAe;KAC5B,sBAAsB;MACpB,GAAG,aAAa;MAChB,aAAa,WAAW;OAAC;OAAO;OAAU;OAAU,GAAG,KAAA;MACvD,QAAQ;MACT;KACF,CAAC;AACF,UAAM,cAAc,eAAsB;WACpC;;GAIV"}
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"}
@@ -6,6 +6,7 @@ import "../../start-router-plugin/constants.js";
6
6
  import { pruneServerOnlySubtrees } from "../../start-router-plugin/pruneServerOnlySubtrees.js";
7
7
  import path from "pathe";
8
8
  import { normalizePath } from "vite";
9
+ import { createRouterPluginContext } from "@tanstack/router-plugin/context";
9
10
  import { tanStackRouterCodeSplitter, tanstackRouterGenerator } from "@tanstack/router-plugin/vite";
10
11
  //#region src/vite/start-router-plugin/plugin.ts
11
12
  function isServerOnlyNode(node) {
@@ -13,6 +14,7 @@ function isServerOnlyNode(node) {
13
14
  return node.createFileRouteProps.has("server") && node.createFileRouteProps.size === 1;
14
15
  }
15
16
  function tanStackStartRouter(startPluginOpts, getConfig, corePluginOpts) {
17
+ const routerPluginContext = createRouterPluginContext();
16
18
  const getGeneratedRouteTreePath = () => {
17
19
  const { startConfig } = getConfig();
18
20
  return path.resolve(startConfig.router.generatedRouteTree);
@@ -98,7 +100,7 @@ function tanStackStartRouter(startPluginOpts, getConfig, corePluginOpts) {
98
100
  routeTreeFileFooter: getRouteTreeFileFooter,
99
101
  plugins
100
102
  };
101
- }),
103
+ }, routerPluginContext),
102
104
  tanStackRouterCodeSplitter(() => {
103
105
  const routerConfig = getConfig().startConfig.router;
104
106
  return {
@@ -114,7 +116,7 @@ function tanStackStartRouter(startPluginOpts, getConfig, corePluginOpts) {
114
116
  },
115
117
  plugin: { vite: { environmentName: VITE_ENVIRONMENT_NAMES.client } }
116
118
  };
117
- }),
119
+ }, routerPluginContext),
118
120
  tanStackRouterCodeSplitter(() => {
119
121
  const routerConfig = getConfig().startConfig.router;
120
122
  return {
@@ -125,7 +127,7 @@ function tanStackStartRouter(startPluginOpts, getConfig, corePluginOpts) {
125
127
  },
126
128
  plugin: { vite: { environmentName: VITE_ENVIRONMENT_NAMES.server } }
127
129
  };
128
- })
130
+ }, routerPluginContext)
129
131
  ];
130
132
  }
131
133
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","names":[],"sources":["../../../../src/vite/start-router-plugin/plugin.ts"],"sourcesContent":["import {\n tanStackRouterCodeSplitter,\n tanstackRouterGenerator,\n} from '@tanstack/router-plugin/vite'\nimport path from 'pathe'\nimport { normalizePath } from 'vite'\nimport { VITE_ENVIRONMENT_NAMES } from '../../constants'\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 { pruneServerOnlySubtrees } from '../../start-router-plugin/pruneServerOnlySubtrees'\nimport { SERVER_PROP } from '../../start-router-plugin/constants'\nimport type { GetConfigFn } from '../../types'\nimport type { TanStackStartVitePluginCoreOptions } from '../types'\nimport type {\n Generator,\n GeneratorPlugin,\n RouteNode,\n} from '@tanstack/router-generator'\nimport type { DevEnvironment, Plugin, PluginOption } from 'vite'\nimport type { TanStackStartInputConfig } from '../../schema'\n\nfunction isServerOnlyNode(node: RouteNode | undefined) {\n if (!node?.createFileRouteProps) {\n return false\n }\n return (\n node.createFileRouteProps.has(SERVER_PROP) &&\n node.createFileRouteProps.size === 1\n )\n}\n\nexport function tanStackStartRouter(\n startPluginOpts: TanStackStartInputConfig,\n getConfig: GetConfigFn,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n): Array<PluginOption> {\n const getGeneratedRouteTreePath = () => {\n const { startConfig } = getConfig()\n return path.resolve(startConfig.router.generatedRouteTree)\n }\n\n let clientEnvironment: DevEnvironment | null = null\n function invalidate() {\n if (!clientEnvironment) {\n return\n }\n\n const mod = clientEnvironment.moduleGraph.getModuleById(\n getGeneratedRouteTreePath(),\n )\n if (mod) {\n clientEnvironment.moduleGraph.invalidateModule(mod)\n }\n clientEnvironment.hot.send({ type: 'full-reload', path: '*' })\n }\n\n let generatorInstance: Generator | null = null\n\n const clientTreeGeneratorPlugin: GeneratorPlugin = {\n name: 'start-client-tree-plugin',\n init({ generator }) {\n generatorInstance = generator\n },\n afterTransform({ node, prevNode }) {\n if (isServerOnlyNode(node) !== isServerOnlyNode(prevNode)) {\n invalidate()\n }\n },\n }\n\n let routeTreeFileFooter: Array<string> | null = null\n\n function getRouteTreeFileFooter() {\n if (routeTreeFileFooter) {\n return routeTreeFileFooter\n }\n routeTreeFileFooter = [\n ...buildRouteTreeFileFooterFromConfig({\n generatedRouteTreePath: getGeneratedRouteTreePath(),\n getConfig,\n corePluginOpts,\n }),\n ]\n return routeTreeFileFooter\n }\n\n let resolvedGeneratedRouteTreePath: string | null = null\n const clientTreePlugin: Plugin = {\n name: 'tanstack-start:route-tree-client-plugin',\n enforce: 'pre',\n applyToEnvironment: (env) => env.name === VITE_ENVIRONMENT_NAMES.client,\n configureServer(server) {\n clientEnvironment = server.environments[VITE_ENVIRONMENT_NAMES.client]\n },\n config() {\n type LoadObjectHook = Extract<\n typeof clientTreePlugin.load,\n { filter?: unknown }\n >\n resolvedGeneratedRouteTreePath = normalizePath(\n getGeneratedRouteTreePath(),\n )\n ;(clientTreePlugin.load as LoadObjectHook).filter = {\n id: { include: new RegExp(resolvedGeneratedRouteTreePath) },\n }\n },\n\n load: {\n filter: {\n // this will be set in the config hook above since it relies on `config` hook being called first\n },\n async handler() {\n if (!generatorInstance) {\n throw new Error('Generator instance not initialized')\n }\n const crawlingResult = await generatorInstance.getCrawlingResult()\n if (!crawlingResult) {\n throw new Error('Crawling result not available')\n }\n const prunedAcc = pruneServerOnlySubtrees(crawlingResult)\n const acc = {\n ...crawlingResult.acc,\n ...prunedAcc,\n }\n const buildResult = generatorInstance.buildRouteTree({\n ...crawlingResult,\n acc,\n config: {\n // importRoutesUsingAbsolutePaths: true,\n // addExtensions: true,\n disableTypes: true,\n enableRouteTreeFormatting: false,\n routeTreeFileHeader: [],\n routeTreeFileFooter: [],\n },\n })\n return { code: buildResult.routeTreeContent, map: null }\n },\n },\n }\n return [\n clientTreePlugin,\n tanstackRouterGenerator(() => {\n const routerConfig = getConfig().startConfig.router\n const plugins = [clientTreeGeneratorPlugin, routesManifestPlugin()]\n if (startPluginOpts.prerender?.enabled === true) {\n plugins.push(prerenderRoutesPlugin())\n }\n return {\n ...routerConfig,\n target: corePluginOpts.framework,\n routeTreeFileFooter: getRouteTreeFileFooter,\n plugins,\n }\n }),\n tanStackRouterCodeSplitter(() => {\n const routerConfig = getConfig().startConfig.router\n return {\n ...routerConfig,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n deleteNodes: ['ssr', 'server', 'headers'],\n addHmr: true,\n },\n plugin: {\n vite: { environmentName: VITE_ENVIRONMENT_NAMES.client },\n },\n }\n }),\n tanStackRouterCodeSplitter(() => {\n const routerConfig = getConfig().startConfig.router\n return {\n ...routerConfig,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n addHmr: false,\n },\n plugin: {\n vite: { environmentName: VITE_ENVIRONMENT_NAMES.server },\n },\n }\n }),\n ]\n}\n"],"mappings":";;;;;;;;;;AAsBA,SAAS,iBAAiB,MAA6B;AACrD,KAAI,CAAC,MAAM,qBACT,QAAO;AAET,QACE,KAAK,qBAAqB,IAAA,SAAgB,IAC1C,KAAK,qBAAqB,SAAS;;AAIvC,SAAgB,oBACd,iBACA,WACA,gBACqB;CACrB,MAAM,kCAAkC;EACtC,MAAM,EAAE,gBAAgB,WAAW;AACnC,SAAO,KAAK,QAAQ,YAAY,OAAO,mBAAmB;;CAG5D,IAAI,oBAA2C;CAC/C,SAAS,aAAa;AACpB,MAAI,CAAC,kBACH;EAGF,MAAM,MAAM,kBAAkB,YAAY,cACxC,2BAA2B,CAC5B;AACD,MAAI,IACF,mBAAkB,YAAY,iBAAiB,IAAI;AAErD,oBAAkB,IAAI,KAAK;GAAE,MAAM;GAAe,MAAM;GAAK,CAAC;;CAGhE,IAAI,oBAAsC;CAE1C,MAAM,4BAA6C;EACjD,MAAM;EACN,KAAK,EAAE,aAAa;AAClB,uBAAoB;;EAEtB,eAAe,EAAE,MAAM,YAAY;AACjC,OAAI,iBAAiB,KAAK,KAAK,iBAAiB,SAAS,CACvD,aAAY;;EAGjB;CAED,IAAI,sBAA4C;CAEhD,SAAS,yBAAyB;AAChC,MAAI,oBACF,QAAO;AAET,wBAAsB,CACpB,GAAG,mCAAmC;GACpC,wBAAwB,2BAA2B;GACnD;GACA;GACD,CAAC,CACH;AACD,SAAO;;CAGT,IAAI,iCAAgD;CACpD,MAAM,mBAA2B;EAC/B,MAAM;EACN,SAAS;EACT,qBAAqB,QAAQ,IAAI,SAAS,uBAAuB;EACjE,gBAAgB,QAAQ;AACtB,uBAAoB,OAAO,aAAa,uBAAuB;;EAEjE,SAAS;AAKP,oCAAiC,cAC/B,2BAA2B,CAC5B;AACC,oBAAiB,KAAwB,SAAS,EAClD,IAAI,EAAE,SAAS,IAAI,OAAO,+BAA+B,EAAE,EAC5D;;EAGH,MAAM;GACJ,QAAQ,EAEP;GACD,MAAM,UAAU;AACd,QAAI,CAAC,kBACH,OAAM,IAAI,MAAM,qCAAqC;IAEvD,MAAM,iBAAiB,MAAM,kBAAkB,mBAAmB;AAClE,QAAI,CAAC,eACH,OAAM,IAAI,MAAM,gCAAgC;IAElD,MAAM,YAAY,wBAAwB,eAAe;IACzD,MAAM,MAAM;KACV,GAAG,eAAe;KAClB,GAAG;KACJ;AAaD,WAAO;KAAE,MAZW,kBAAkB,eAAe;MACnD,GAAG;MACH;MACA,QAAQ;OAGN,cAAc;OACd,2BAA2B;OAC3B,qBAAqB,EAAE;OACvB,qBAAqB,EAAE;OACxB;MACF,CAAC,CACyB;KAAkB,KAAK;KAAM;;GAE3D;EACF;AACD,QAAO;EACL;EACA,8BAA8B;GAC5B,MAAM,eAAe,WAAW,CAAC,YAAY;GAC7C,MAAM,UAAU,CAAC,2BAA2B,sBAAsB,CAAC;AACnE,OAAI,gBAAgB,WAAW,YAAY,KACzC,SAAQ,KAAK,uBAAuB,CAAC;AAEvC,UAAO;IACL,GAAG;IACH,QAAQ,eAAe;IACvB,qBAAqB;IACrB;IACD;IACD;EACF,iCAAiC;GAC/B,MAAM,eAAe,WAAW,CAAC,YAAY;AAC7C,UAAO;IACL,GAAG;IACH,sBAAsB;KACpB,GAAG,aAAa;KAChB,aAAa;MAAC;MAAO;MAAU;MAAU;KACzC,QAAQ;KACT;IACD,QAAQ,EACN,MAAM,EAAE,iBAAiB,uBAAuB,QAAQ,EACzD;IACF;IACD;EACF,iCAAiC;GAC/B,MAAM,eAAe,WAAW,CAAC,YAAY;AAC7C,UAAO;IACL,GAAG;IACH,sBAAsB;KACpB,GAAG,aAAa;KAChB,QAAQ;KACT;IACD,QAAQ,EACN,MAAM,EAAE,iBAAiB,uBAAuB,QAAQ,EACzD;IACF;IACD;EACH"}
1
+ {"version":3,"file":"plugin.js","names":[],"sources":["../../../../src/vite/start-router-plugin/plugin.ts"],"sourcesContent":["import { createRouterPluginContext } from '@tanstack/router-plugin/context'\nimport {\n tanStackRouterCodeSplitter,\n tanstackRouterGenerator,\n} from '@tanstack/router-plugin/vite'\nimport path from 'pathe'\nimport { normalizePath } from 'vite'\nimport { VITE_ENVIRONMENT_NAMES } from '../../constants'\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 { pruneServerOnlySubtrees } from '../../start-router-plugin/pruneServerOnlySubtrees'\nimport { SERVER_PROP } from '../../start-router-plugin/constants'\nimport type { GetConfigFn } from '../../types'\nimport type { TanStackStartVitePluginCoreOptions } from '../types'\nimport type {\n Generator,\n GeneratorPlugin,\n RouteNode,\n} from '@tanstack/router-generator'\nimport type { DevEnvironment, Plugin, PluginOption } from 'vite'\nimport type { TanStackStartInputConfig } from '../../schema'\n\nfunction isServerOnlyNode(node: RouteNode | undefined) {\n if (!node?.createFileRouteProps) {\n return false\n }\n return (\n node.createFileRouteProps.has(SERVER_PROP) &&\n node.createFileRouteProps.size === 1\n )\n}\n\nexport function tanStackStartRouter(\n startPluginOpts: TanStackStartInputConfig,\n getConfig: GetConfigFn,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n): Array<PluginOption> {\n const routerPluginContext = createRouterPluginContext()\n\n const getGeneratedRouteTreePath = () => {\n const { startConfig } = getConfig()\n return path.resolve(startConfig.router.generatedRouteTree)\n }\n\n let clientEnvironment: DevEnvironment | null = null\n function invalidate() {\n if (!clientEnvironment) {\n return\n }\n\n const mod = clientEnvironment.moduleGraph.getModuleById(\n getGeneratedRouteTreePath(),\n )\n if (mod) {\n clientEnvironment.moduleGraph.invalidateModule(mod)\n }\n clientEnvironment.hot.send({ type: 'full-reload', path: '*' })\n }\n\n let generatorInstance: Generator | null = null\n\n const clientTreeGeneratorPlugin: GeneratorPlugin = {\n name: 'start-client-tree-plugin',\n init({ generator }) {\n generatorInstance = generator\n },\n afterTransform({ node, prevNode }) {\n if (isServerOnlyNode(node) !== isServerOnlyNode(prevNode)) {\n invalidate()\n }\n },\n }\n\n let routeTreeFileFooter: Array<string> | null = null\n\n function getRouteTreeFileFooter() {\n if (routeTreeFileFooter) {\n return routeTreeFileFooter\n }\n routeTreeFileFooter = [\n ...buildRouteTreeFileFooterFromConfig({\n generatedRouteTreePath: getGeneratedRouteTreePath(),\n getConfig,\n corePluginOpts,\n }),\n ]\n return routeTreeFileFooter\n }\n\n let resolvedGeneratedRouteTreePath: string | null = null\n const clientTreePlugin: Plugin = {\n name: 'tanstack-start:route-tree-client-plugin',\n enforce: 'pre',\n applyToEnvironment: (env) => env.name === VITE_ENVIRONMENT_NAMES.client,\n configureServer(server) {\n clientEnvironment = server.environments[VITE_ENVIRONMENT_NAMES.client]\n },\n config() {\n type LoadObjectHook = Extract<\n typeof clientTreePlugin.load,\n { filter?: unknown }\n >\n resolvedGeneratedRouteTreePath = normalizePath(\n getGeneratedRouteTreePath(),\n )\n ;(clientTreePlugin.load as LoadObjectHook).filter = {\n id: { include: new RegExp(resolvedGeneratedRouteTreePath) },\n }\n },\n\n load: {\n filter: {\n // this will be set in the config hook above since it relies on `config` hook being called first\n },\n async handler() {\n if (!generatorInstance) {\n throw new Error('Generator instance not initialized')\n }\n const crawlingResult = await generatorInstance.getCrawlingResult()\n if (!crawlingResult) {\n throw new Error('Crawling result not available')\n }\n const prunedAcc = pruneServerOnlySubtrees(crawlingResult)\n const acc = {\n ...crawlingResult.acc,\n ...prunedAcc,\n }\n const buildResult = generatorInstance.buildRouteTree({\n ...crawlingResult,\n acc,\n config: {\n // importRoutesUsingAbsolutePaths: true,\n // addExtensions: true,\n disableTypes: true,\n enableRouteTreeFormatting: false,\n routeTreeFileHeader: [],\n routeTreeFileFooter: [],\n },\n })\n return { code: buildResult.routeTreeContent, map: null }\n },\n },\n }\n return [\n clientTreePlugin,\n tanstackRouterGenerator(() => {\n const routerConfig = getConfig().startConfig.router\n const plugins = [clientTreeGeneratorPlugin, routesManifestPlugin()]\n if (startPluginOpts.prerender?.enabled === true) {\n plugins.push(prerenderRoutesPlugin())\n }\n return {\n ...routerConfig,\n target: corePluginOpts.framework,\n routeTreeFileFooter: getRouteTreeFileFooter,\n plugins,\n }\n }, routerPluginContext),\n tanStackRouterCodeSplitter(() => {\n const routerConfig = getConfig().startConfig.router\n return {\n ...routerConfig,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n deleteNodes: ['ssr', 'server', 'headers'],\n addHmr: true,\n },\n plugin: {\n vite: { environmentName: VITE_ENVIRONMENT_NAMES.client },\n },\n }\n }, routerPluginContext),\n tanStackRouterCodeSplitter(() => {\n const routerConfig = getConfig().startConfig.router\n return {\n ...routerConfig,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n addHmr: false,\n },\n plugin: {\n vite: { environmentName: VITE_ENVIRONMENT_NAMES.server },\n },\n }\n }, routerPluginContext),\n ]\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/start-plugin-core",
3
- "version": "1.169.13",
3
+ "version": "1.169.14",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -87,11 +87,11 @@
87
87
  "xmlbuilder2": "^4.0.3",
88
88
  "zod": "^3.24.2",
89
89
  "@tanstack/router-core": "1.169.1",
90
+ "@tanstack/router-plugin": "1.167.32",
90
91
  "@tanstack/router-generator": "1.166.39",
91
- "@tanstack/router-plugin": "1.167.31",
92
- "@tanstack/router-utils": "1.161.7",
93
92
  "@tanstack/start-client-core": "1.168.1",
94
- "@tanstack/start-server-core": "1.167.26"
93
+ "@tanstack/start-server-core": "1.167.26",
94
+ "@tanstack/router-utils": "1.161.7"
95
95
  },
96
96
  "devDependencies": {
97
97
  "@rsbuild/core": "^2.0.1",
@@ -1,4 +1,9 @@
1
1
  import path from 'pathe'
2
+ import { createRouterPluginContext } from '@tanstack/router-plugin/context'
3
+ import {
4
+ TanStackRouterCodeSplitterRspack,
5
+ TanStackRouterGeneratorRspack,
6
+ } from '@tanstack/router-plugin/rspack'
2
7
  import { routesManifestPlugin } from '../start-router-plugin/generator-plugins/routes-manifest-plugin'
3
8
  import { prerenderRoutesPlugin } from '../start-router-plugin/generator-plugins/prerender-routes-plugin'
4
9
  import { buildRouteTreeFileFooterFromConfig } from '../start-router-plugin/route-tree-footer'
@@ -14,8 +19,6 @@ import type { TanStackStartRsbuildInputConfig } from './schema'
14
19
  * The router-plugin package exports rspack-compatible unplugin wrappers:
15
20
  * - TanStackRouterGeneratorRspack: file-based route generation
16
21
  * - TanStackRouterCodeSplitterRspack: route code splitting
17
- *
18
- * These are dynamically imported to avoid hard dependency on router-plugin/rspack.
19
22
  */
20
23
  export function registerRouterPlugins(
21
24
  api: RsbuildPluginAPI,
@@ -25,17 +28,17 @@ export function registerRouterPlugins(
25
28
  startPluginOpts: TanStackStartRsbuildInputConfig
26
29
  },
27
30
  ): void {
28
- api.modifyRspackConfig(async (config, utils) => {
31
+ const routerPluginContext = createRouterPluginContext()
32
+
33
+ api.modifyRspackConfig((config, utils) => {
29
34
  const envName = utils.environment.name
30
35
  const { startConfig } = opts.getConfig()
31
36
  const routerConfig = startConfig.router
32
37
 
33
38
  // Generator only runs once — register for the client environment
34
39
  if (envName === RSBUILD_ENVIRONMENT_NAMES.client) {
35
- try {
36
- const { TanStackRouterGeneratorRspack } =
37
- await import('@tanstack/router-plugin/rspack')
38
- const generatorPlugin = TanStackRouterGeneratorRspack({
40
+ const generatorPlugin = TanStackRouterGeneratorRspack(
41
+ {
39
42
  ...routerConfig,
40
43
  target: opts.corePluginOpts.framework,
41
44
  routeTreeFileFooter: () => {
@@ -53,11 +56,10 @@ export function registerRouterPlugins(
53
56
  ? [prerenderRoutesPlugin()]
54
57
  : []),
55
58
  ],
56
- })
57
- utils.appendPlugins(generatorPlugin as any)
58
- } catch {
59
- // router-plugin/rspack not available — skip
60
- }
59
+ },
60
+ routerPluginContext,
61
+ )
62
+ utils.appendPlugins(generatorPlugin as any)
61
63
  }
62
64
 
63
65
  if (
@@ -65,10 +67,8 @@ export function registerRouterPlugins(
65
67
  envName === RSBUILD_ENVIRONMENT_NAMES.server
66
68
  ) {
67
69
  const isClient = envName === RSBUILD_ENVIRONMENT_NAMES.client
68
- try {
69
- const { TanStackRouterCodeSplitterRspack } =
70
- await import('@tanstack/router-plugin/rspack')
71
- const splitterPlugin = TanStackRouterCodeSplitterRspack({
70
+ const splitterPlugin = TanStackRouterCodeSplitterRspack(
71
+ {
72
72
  ...routerConfig,
73
73
  target: opts.corePluginOpts.framework,
74
74
  codeSplittingOptions: {
@@ -76,11 +76,10 @@ export function registerRouterPlugins(
76
76
  deleteNodes: isClient ? ['ssr', 'server', 'headers'] : undefined,
77
77
  addHmr: isClient,
78
78
  },
79
- })
80
- utils.appendPlugins(splitterPlugin as any)
81
- } catch {
82
- // router-plugin/rspack not available — skip
83
- }
79
+ },
80
+ routerPluginContext,
81
+ )
82
+ utils.appendPlugins(splitterPlugin as any)
84
83
  }
85
84
  })
86
85
  }
@@ -1,3 +1,4 @@
1
+ import { createRouterPluginContext } from '@tanstack/router-plugin/context'
1
2
  import {
2
3
  tanStackRouterCodeSplitter,
3
4
  tanstackRouterGenerator,
@@ -35,6 +36,8 @@ export function tanStackStartRouter(
35
36
  getConfig: GetConfigFn,
36
37
  corePluginOpts: TanStackStartVitePluginCoreOptions,
37
38
  ): Array<PluginOption> {
39
+ const routerPluginContext = createRouterPluginContext()
40
+
38
41
  const getGeneratedRouteTreePath = () => {
39
42
  const { startConfig } = getConfig()
40
43
  return path.resolve(startConfig.router.generatedRouteTree)
@@ -153,7 +156,7 @@ export function tanStackStartRouter(
153
156
  routeTreeFileFooter: getRouteTreeFileFooter,
154
157
  plugins,
155
158
  }
156
- }),
159
+ }, routerPluginContext),
157
160
  tanStackRouterCodeSplitter(() => {
158
161
  const routerConfig = getConfig().startConfig.router
159
162
  return {
@@ -167,7 +170,7 @@ export function tanStackStartRouter(
167
170
  vite: { environmentName: VITE_ENVIRONMENT_NAMES.client },
168
171
  },
169
172
  }
170
- }),
173
+ }, routerPluginContext),
171
174
  tanStackRouterCodeSplitter(() => {
172
175
  const routerConfig = getConfig().startConfig.router
173
176
  return {
@@ -180,6 +183,6 @@ export function tanStackStartRouter(
180
183
  vite: { environmentName: VITE_ENVIRONMENT_NAMES.server },
181
184
  },
182
185
  }
183
- }),
186
+ }, routerPluginContext),
184
187
  ]
185
188
  }