@tanstack/router-plugin 1.151.3 → 1.151.4
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/cjs/core/router-code-splitter-plugin.cjs +57 -28
- package/dist/cjs/core/router-code-splitter-plugin.cjs.map +1 -1
- package/dist/esm/core/router-code-splitter-plugin.js +57 -28
- package/dist/esm/core/router-code-splitter-plugin.js.map +1 -1
- package/package.json +3 -3
- package/src/core/router-code-splitter-plugin.ts +74 -39
|
@@ -7,27 +7,38 @@ const compilers = require("./code-splitter/compilers.cjs");
|
|
|
7
7
|
const constants = require("./constants.cjs");
|
|
8
8
|
const pathIds = require("./code-splitter/path-ids.cjs");
|
|
9
9
|
const utils = require("./utils.cjs");
|
|
10
|
-
const bannedBeforeExternalPlugins = [
|
|
11
|
-
{
|
|
12
|
-
identifier: "@react-refresh",
|
|
13
|
-
pkg: "@vitejs/plugin-react",
|
|
14
|
-
usage: "viteReact()",
|
|
15
|
-
frameworks: ["vite"]
|
|
16
|
-
}
|
|
17
|
-
];
|
|
18
|
-
class FoundPluginInBeforeCode extends Error {
|
|
19
|
-
constructor(externalPlugin, pluginFramework) {
|
|
20
|
-
super(`We detected that the '${externalPlugin.pkg}' was passed before '@tanstack/router-plugin/${pluginFramework}'. Please make sure that '@tanstack/router-plugin' is passed before '${externalPlugin.pkg}' and try again:
|
|
21
|
-
e.g.
|
|
22
|
-
plugins: [
|
|
23
|
-
tanstackRouter(), // Place this before ${externalPlugin.usage}
|
|
24
|
-
${externalPlugin.usage},
|
|
25
|
-
]
|
|
26
|
-
`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
10
|
const PLUGIN_NAME = "unplugin:router-code-splitter";
|
|
30
|
-
const
|
|
11
|
+
const CODE_SPLITTER_PLUGIN_NAME = "tanstack-router:code-splitter:compile-reference-file";
|
|
12
|
+
const TRANSFORMATION_PLUGINS_BY_FRAMEWORK = {
|
|
13
|
+
react: [
|
|
14
|
+
{
|
|
15
|
+
// Babel-based React plugin
|
|
16
|
+
pluginNames: ["vite:react-babel", "vite:react-refresh"],
|
|
17
|
+
pkg: "@vitejs/plugin-react",
|
|
18
|
+
usage: "react()"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
// SWC-based React plugin
|
|
22
|
+
pluginNames: ["vite:react-swc", "vite:react-swc:resolve-runtime"],
|
|
23
|
+
pkg: "@vitejs/plugin-react-swc",
|
|
24
|
+
usage: "reactSwc()"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
// OXC-based React plugin (deprecated but should still be handled)
|
|
28
|
+
pluginNames: ["vite:react-oxc:config", "vite:react-oxc:refresh-runtime"],
|
|
29
|
+
pkg: "@vitejs/plugin-react-oxc",
|
|
30
|
+
usage: "reactOxc()"
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
solid: [
|
|
34
|
+
{
|
|
35
|
+
pluginNames: ["solid"],
|
|
36
|
+
pkg: "vite-plugin-solid",
|
|
37
|
+
usage: "solid()"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
};
|
|
41
|
+
const unpluginRouterCodeSplitterFactory = (options = {}, { framework: _framework }) => {
|
|
31
42
|
let ROOT = process.cwd();
|
|
32
43
|
let userConfig;
|
|
33
44
|
function initUserConfig() {
|
|
@@ -146,14 +157,6 @@ ${message}`
|
|
|
146
157
|
const normalizedId = utils.normalizePath(id);
|
|
147
158
|
const generatorFileInfo = globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId);
|
|
148
159
|
if (generatorFileInfo && includedCode.some((included) => code.includes(included))) {
|
|
149
|
-
for (const externalPlugin of bannedBeforeExternalPlugins) {
|
|
150
|
-
if (!externalPlugin.frameworks.includes(framework)) {
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
if (code.includes(externalPlugin.identifier)) {
|
|
154
|
-
throw new FoundPluginInBeforeCode(externalPlugin, framework);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
160
|
return handleCompilingReferenceFile(
|
|
158
161
|
code,
|
|
159
162
|
normalizedId,
|
|
@@ -167,6 +170,32 @@ ${message}`
|
|
|
167
170
|
configResolved(config2) {
|
|
168
171
|
ROOT = config2.root;
|
|
169
172
|
initUserConfig();
|
|
173
|
+
const routerPluginIndex = config2.plugins.findIndex(
|
|
174
|
+
(p) => p.name === CODE_SPLITTER_PLUGIN_NAME
|
|
175
|
+
);
|
|
176
|
+
if (routerPluginIndex === -1) return;
|
|
177
|
+
const frameworkPlugins = TRANSFORMATION_PLUGINS_BY_FRAMEWORK[userConfig.target];
|
|
178
|
+
if (!frameworkPlugins) return;
|
|
179
|
+
for (const transformPlugin of frameworkPlugins) {
|
|
180
|
+
const transformPluginIndex = config2.plugins.findIndex(
|
|
181
|
+
(p) => transformPlugin.pluginNames.includes(p.name)
|
|
182
|
+
);
|
|
183
|
+
if (transformPluginIndex !== -1 && transformPluginIndex < routerPluginIndex) {
|
|
184
|
+
throw new Error(
|
|
185
|
+
`Plugin order error: '${transformPlugin.pkg}' is placed before '@tanstack/router-plugin'.
|
|
186
|
+
|
|
187
|
+
The TanStack Router plugin must come BEFORE JSX transformation plugins.
|
|
188
|
+
|
|
189
|
+
Please update your Vite config:
|
|
190
|
+
|
|
191
|
+
plugins: [
|
|
192
|
+
tanstackRouter(),
|
|
193
|
+
${transformPlugin.usage},
|
|
194
|
+
]
|
|
195
|
+
`
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
170
199
|
},
|
|
171
200
|
applyToEnvironment(environment) {
|
|
172
201
|
if (userConfig.plugin?.vite?.environmentName) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-code-splitter-plugin.cjs","sources":["../../../src/core/router-code-splitter-plugin.ts"],"sourcesContent":["/**\n * It is important to familiarize yourself with how the code-splitting works in this plugin.\n * https://github.com/TanStack/router/pull/3355\n */\n\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport {\n compileCodeSplitReferenceRoute,\n compileCodeSplitVirtualRoute,\n detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport {\n defaultCodeSplitGroupings,\n splitRouteIdentNodes,\n tsrSplit,\n} from './constants'\nimport { decodeIdentifier } from './code-splitter/path-ids'\nimport { debug, normalizePath } from './utils'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type {\n UnpluginContextMeta,\n UnpluginFactory,\n TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\ntype BannedBeforeExternalPlugin = {\n identifier: string\n pkg: string\n usage: string\n frameworks: Array<UnpluginContextMeta['framework']>\n}\n\nconst bannedBeforeExternalPlugins: Array<BannedBeforeExternalPlugin> = [\n {\n identifier: '@react-refresh',\n pkg: '@vitejs/plugin-react',\n usage: 'viteReact()',\n frameworks: ['vite'],\n },\n]\n\nclass FoundPluginInBeforeCode extends Error {\n constructor(\n externalPlugin: BannedBeforeExternalPlugin,\n pluginFramework: string,\n ) {\n super(`We detected that the '${externalPlugin.pkg}' was passed before '@tanstack/router-plugin/${pluginFramework}'. Please make sure that '@tanstack/router-plugin' is passed before '${externalPlugin.pkg}' and try again: \ne.g.\nplugins: [\n tanstackRouter(), // Place this before ${externalPlugin.usage}\n ${externalPlugin.usage},\n]\n`)\n }\n}\n\nconst PLUGIN_NAME = 'unplugin:router-code-splitter'\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}, { framework }) => {\n let ROOT: string = process.cwd()\n let userConfig: Config\n\n function initUserConfig() {\n if (typeof options === 'function') {\n userConfig = options()\n } else {\n userConfig = getConfig(options, ROOT)\n }\n }\n const isProduction = process.env.NODE_ENV === 'production'\n\n const getGlobalCodeSplitGroupings = () => {\n return (\n userConfig.codeSplittingOptions?.defaultBehavior ||\n defaultCodeSplitGroupings\n )\n }\n const getShouldSplitFn = () => {\n return userConfig.codeSplittingOptions?.splitBehavior\n }\n\n const handleCompilingReferenceFile = (\n code: string,\n id: string,\n generatorNodeInfo: GetRoutesByFileMapResultValue,\n ): UnpluginTransformResult => {\n if (debug) console.info('Compiling Route: ', id)\n\n const fromCode = detectCodeSplitGroupingsFromRoute({\n code,\n })\n\n if (fromCode.groupings) {\n const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const userShouldSplitFn = getShouldSplitFn()\n\n const pluginSplitBehavior = userShouldSplitFn?.({\n routeId: generatorNodeInfo.routePath,\n }) as CodeSplitGroupings | undefined\n\n if (pluginSplitBehavior) {\n const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings returned when using \\`splitBehavior\\` for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const splitGroupings: CodeSplitGroupings =\n fromCode.groupings || pluginSplitBehavior || getGlobalCodeSplitGroupings()\n\n const compiledReferenceRoute = compileCodeSplitReferenceRoute({\n code,\n codeSplitGroupings: splitGroupings,\n targetFramework: userConfig.target,\n filename: id,\n id,\n deleteNodes: userConfig.codeSplittingOptions?.deleteNodes\n ? new Set(userConfig.codeSplittingOptions.deleteNodes)\n : undefined,\n addHmr:\n (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction,\n })\n\n if (compiledReferenceRoute === null) {\n if (debug) {\n console.info(\n `No changes made to route \"${id}\", skipping code-splitting.`,\n )\n }\n return null\n }\n if (debug) {\n logDiff(code, compiledReferenceRoute.code)\n console.log('Output:\\n', compiledReferenceRoute.code + '\\n\\n')\n }\n\n return compiledReferenceRoute\n }\n\n const handleCompilingVirtualFile = (\n code: string,\n id: string,\n ): UnpluginTransformResult => {\n if (debug) console.info('Splitting Route: ', id)\n\n const [_, ...pathnameParts] = id.split('?')\n\n const searchParams = new URLSearchParams(pathnameParts.join('?'))\n const splitValue = searchParams.get(tsrSplit)\n\n if (!splitValue) {\n throw new Error(\n `The split value for the virtual route \"${id}\" was not found.`,\n )\n }\n\n const rawGrouping = decodeIdentifier(splitValue)\n const grouping = [...new Set(rawGrouping)].filter((p) =>\n splitRouteIdentNodes.includes(p as any),\n ) as Array<SplitRouteIdentNodes>\n\n const result = compileCodeSplitVirtualRoute({\n code,\n filename: id,\n splitTargets: grouping,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n }\n\n const includedCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n ]\n return [\n {\n name: 'tanstack-router:code-splitter:compile-reference-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: {\n exclude: tsrSplit,\n // this is necessary for webpack / rspack to avoid matching .html files\n include: /\\.(m|c)?(j|t)sx?$/,\n },\n code: {\n include: includedCode,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const generatorFileInfo =\n globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId)\n if (\n generatorFileInfo &&\n includedCode.some((included) => code.includes(included))\n ) {\n for (const externalPlugin of bannedBeforeExternalPlugins) {\n if (!externalPlugin.frameworks.includes(framework)) {\n continue\n }\n\n if (code.includes(externalPlugin.identifier)) {\n throw new FoundPluginInBeforeCode(externalPlugin, framework)\n }\n }\n\n return handleCompilingReferenceFile(\n code,\n normalizedId,\n generatorFileInfo,\n )\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n ROOT = config.root\n initUserConfig()\n },\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n\n rspack(compiler) {\n ROOT = process.cwd()\n initUserConfig()\n\n if (compiler.options.mode === 'production') {\n compiler.hooks.done.tap(PLUGIN_NAME, () => {\n console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n })\n }\n },\n\n webpack(compiler) {\n ROOT = process.cwd()\n initUserConfig()\n\n if (compiler.options.mode === 'production') {\n compiler.hooks.done.tap(PLUGIN_NAME, () => {\n console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n })\n }\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-virtual-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-split/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n return handleCompilingVirtualFile(code, normalizedId)\n },\n },\n },\n ]\n}\n"],"names":["getConfig","defaultCodeSplitGroupings","debug","detectCodeSplitGroupingsFromRoute","splitGroupingsSchema","compileCodeSplitReferenceRoute","logDiff","tsrSplit","decodeIdentifier","splitRouteIdentNodes","compileCodeSplitVirtualRoute","normalizePath","config","pathToFileURL","fileURLToPath"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"router-code-splitter-plugin.cjs","sources":["../../../src/core/router-code-splitter-plugin.ts"],"sourcesContent":["/**\n * It is important to familiarize yourself with how the code-splitting works in this plugin.\n * https://github.com/TanStack/router/pull/3355\n */\n\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport {\n compileCodeSplitReferenceRoute,\n compileCodeSplitVirtualRoute,\n detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport {\n defaultCodeSplitGroupings,\n splitRouteIdentNodes,\n tsrSplit,\n} from './constants'\nimport { decodeIdentifier } from './code-splitter/path-ids'\nimport { debug, normalizePath } from './utils'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type {\n UnpluginFactory,\n TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\nconst PLUGIN_NAME = 'unplugin:router-code-splitter'\nconst CODE_SPLITTER_PLUGIN_NAME =\n 'tanstack-router:code-splitter:compile-reference-file'\n\ntype TransformationPluginInfo = {\n pluginNames: Array<string>\n pkg: string\n usage: string\n}\n\n/**\n * JSX transformation plugins grouped by framework.\n * These plugins must come AFTER the TanStack Router plugin in the Vite config.\n */\nconst TRANSFORMATION_PLUGINS_BY_FRAMEWORK: Record<\n string,\n Array<TransformationPluginInfo>\n> = {\n react: [\n {\n // Babel-based React plugin\n pluginNames: ['vite:react-babel', 'vite:react-refresh'],\n pkg: '@vitejs/plugin-react',\n usage: 'react()',\n },\n {\n // SWC-based React plugin\n pluginNames: ['vite:react-swc', 'vite:react-swc:resolve-runtime'],\n pkg: '@vitejs/plugin-react-swc',\n usage: 'reactSwc()',\n },\n {\n // OXC-based React plugin (deprecated but should still be handled)\n pluginNames: ['vite:react-oxc:config', 'vite:react-oxc:refresh-runtime'],\n pkg: '@vitejs/plugin-react-oxc',\n usage: 'reactOxc()',\n },\n ],\n solid: [\n {\n pluginNames: ['solid'],\n pkg: 'vite-plugin-solid',\n usage: 'solid()',\n },\n ],\n}\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}, { framework: _framework }) => {\n let ROOT: string = process.cwd()\n let userConfig: Config\n\n function initUserConfig() {\n if (typeof options === 'function') {\n userConfig = options()\n } else {\n userConfig = getConfig(options, ROOT)\n }\n }\n const isProduction = process.env.NODE_ENV === 'production'\n\n const getGlobalCodeSplitGroupings = () => {\n return (\n userConfig.codeSplittingOptions?.defaultBehavior ||\n defaultCodeSplitGroupings\n )\n }\n const getShouldSplitFn = () => {\n return userConfig.codeSplittingOptions?.splitBehavior\n }\n\n const handleCompilingReferenceFile = (\n code: string,\n id: string,\n generatorNodeInfo: GetRoutesByFileMapResultValue,\n ): UnpluginTransformResult => {\n if (debug) console.info('Compiling Route: ', id)\n\n const fromCode = detectCodeSplitGroupingsFromRoute({\n code,\n })\n\n if (fromCode.groupings) {\n const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const userShouldSplitFn = getShouldSplitFn()\n\n const pluginSplitBehavior = userShouldSplitFn?.({\n routeId: generatorNodeInfo.routePath,\n }) as CodeSplitGroupings | undefined\n\n if (pluginSplitBehavior) {\n const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings returned when using \\`splitBehavior\\` for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const splitGroupings: CodeSplitGroupings =\n fromCode.groupings || pluginSplitBehavior || getGlobalCodeSplitGroupings()\n\n const compiledReferenceRoute = compileCodeSplitReferenceRoute({\n code,\n codeSplitGroupings: splitGroupings,\n targetFramework: userConfig.target,\n filename: id,\n id,\n deleteNodes: userConfig.codeSplittingOptions?.deleteNodes\n ? new Set(userConfig.codeSplittingOptions.deleteNodes)\n : undefined,\n addHmr:\n (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction,\n })\n\n if (compiledReferenceRoute === null) {\n if (debug) {\n console.info(\n `No changes made to route \"${id}\", skipping code-splitting.`,\n )\n }\n return null\n }\n if (debug) {\n logDiff(code, compiledReferenceRoute.code)\n console.log('Output:\\n', compiledReferenceRoute.code + '\\n\\n')\n }\n\n return compiledReferenceRoute\n }\n\n const handleCompilingVirtualFile = (\n code: string,\n id: string,\n ): UnpluginTransformResult => {\n if (debug) console.info('Splitting Route: ', id)\n\n const [_, ...pathnameParts] = id.split('?')\n\n const searchParams = new URLSearchParams(pathnameParts.join('?'))\n const splitValue = searchParams.get(tsrSplit)\n\n if (!splitValue) {\n throw new Error(\n `The split value for the virtual route \"${id}\" was not found.`,\n )\n }\n\n const rawGrouping = decodeIdentifier(splitValue)\n const grouping = [...new Set(rawGrouping)].filter((p) =>\n splitRouteIdentNodes.includes(p as any),\n ) as Array<SplitRouteIdentNodes>\n\n const result = compileCodeSplitVirtualRoute({\n code,\n filename: id,\n splitTargets: grouping,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n }\n\n const includedCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n ]\n return [\n {\n name: 'tanstack-router:code-splitter:compile-reference-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: {\n exclude: tsrSplit,\n // this is necessary for webpack / rspack to avoid matching .html files\n include: /\\.(m|c)?(j|t)sx?$/,\n },\n code: {\n include: includedCode,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const generatorFileInfo =\n globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId)\n if (\n generatorFileInfo &&\n includedCode.some((included) => code.includes(included))\n ) {\n return handleCompilingReferenceFile(\n code,\n normalizedId,\n generatorFileInfo,\n )\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n ROOT = config.root\n initUserConfig()\n\n // Validate plugin order - router must come before JSX transformation plugins\n const routerPluginIndex = config.plugins.findIndex(\n (p) => p.name === CODE_SPLITTER_PLUGIN_NAME,\n )\n\n if (routerPluginIndex === -1) return\n\n const frameworkPlugins =\n TRANSFORMATION_PLUGINS_BY_FRAMEWORK[userConfig.target]\n if (!frameworkPlugins) return\n\n for (const transformPlugin of frameworkPlugins) {\n const transformPluginIndex = config.plugins.findIndex((p) =>\n transformPlugin.pluginNames.includes(p.name),\n )\n\n if (\n transformPluginIndex !== -1 &&\n transformPluginIndex < routerPluginIndex\n ) {\n throw new Error(\n `Plugin order error: '${transformPlugin.pkg}' is placed before '@tanstack/router-plugin'.\\n\\n` +\n `The TanStack Router plugin must come BEFORE JSX transformation plugins.\\n\\n` +\n `Please update your Vite config:\\n\\n` +\n ` plugins: [\\n` +\n ` tanstackRouter(),\\n` +\n ` ${transformPlugin.usage},\\n` +\n ` ]\\n`,\n )\n }\n }\n },\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n\n rspack(compiler) {\n ROOT = process.cwd()\n initUserConfig()\n\n if (compiler.options.mode === 'production') {\n compiler.hooks.done.tap(PLUGIN_NAME, () => {\n console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n })\n }\n },\n\n webpack(compiler) {\n ROOT = process.cwd()\n initUserConfig()\n\n if (compiler.options.mode === 'production') {\n compiler.hooks.done.tap(PLUGIN_NAME, () => {\n console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n })\n }\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-virtual-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-split/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n return handleCompilingVirtualFile(code, normalizedId)\n },\n },\n },\n ]\n}\n"],"names":["getConfig","defaultCodeSplitGroupings","debug","detectCodeSplitGroupingsFromRoute","splitGroupingsSchema","compileCodeSplitReferenceRoute","logDiff","tsrSplit","decodeIdentifier","splitRouteIdentNodes","compileCodeSplitVirtualRoute","normalizePath","config","pathToFileURL","fileURLToPath"],"mappings":"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"}
|
|
@@ -5,27 +5,38 @@ import { detectCodeSplitGroupingsFromRoute, compileCodeSplitReferenceRoute, comp
|
|
|
5
5
|
import { tsrSplit, splitRouteIdentNodes, defaultCodeSplitGroupings } from "./constants.js";
|
|
6
6
|
import { decodeIdentifier } from "./code-splitter/path-ids.js";
|
|
7
7
|
import { normalizePath, debug } from "./utils.js";
|
|
8
|
-
const bannedBeforeExternalPlugins = [
|
|
9
|
-
{
|
|
10
|
-
identifier: "@react-refresh",
|
|
11
|
-
pkg: "@vitejs/plugin-react",
|
|
12
|
-
usage: "viteReact()",
|
|
13
|
-
frameworks: ["vite"]
|
|
14
|
-
}
|
|
15
|
-
];
|
|
16
|
-
class FoundPluginInBeforeCode extends Error {
|
|
17
|
-
constructor(externalPlugin, pluginFramework) {
|
|
18
|
-
super(`We detected that the '${externalPlugin.pkg}' was passed before '@tanstack/router-plugin/${pluginFramework}'. Please make sure that '@tanstack/router-plugin' is passed before '${externalPlugin.pkg}' and try again:
|
|
19
|
-
e.g.
|
|
20
|
-
plugins: [
|
|
21
|
-
tanstackRouter(), // Place this before ${externalPlugin.usage}
|
|
22
|
-
${externalPlugin.usage},
|
|
23
|
-
]
|
|
24
|
-
`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
8
|
const PLUGIN_NAME = "unplugin:router-code-splitter";
|
|
28
|
-
const
|
|
9
|
+
const CODE_SPLITTER_PLUGIN_NAME = "tanstack-router:code-splitter:compile-reference-file";
|
|
10
|
+
const TRANSFORMATION_PLUGINS_BY_FRAMEWORK = {
|
|
11
|
+
react: [
|
|
12
|
+
{
|
|
13
|
+
// Babel-based React plugin
|
|
14
|
+
pluginNames: ["vite:react-babel", "vite:react-refresh"],
|
|
15
|
+
pkg: "@vitejs/plugin-react",
|
|
16
|
+
usage: "react()"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
// SWC-based React plugin
|
|
20
|
+
pluginNames: ["vite:react-swc", "vite:react-swc:resolve-runtime"],
|
|
21
|
+
pkg: "@vitejs/plugin-react-swc",
|
|
22
|
+
usage: "reactSwc()"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
// OXC-based React plugin (deprecated but should still be handled)
|
|
26
|
+
pluginNames: ["vite:react-oxc:config", "vite:react-oxc:refresh-runtime"],
|
|
27
|
+
pkg: "@vitejs/plugin-react-oxc",
|
|
28
|
+
usage: "reactOxc()"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
solid: [
|
|
32
|
+
{
|
|
33
|
+
pluginNames: ["solid"],
|
|
34
|
+
pkg: "vite-plugin-solid",
|
|
35
|
+
usage: "solid()"
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
};
|
|
39
|
+
const unpluginRouterCodeSplitterFactory = (options = {}, { framework: _framework }) => {
|
|
29
40
|
let ROOT = process.cwd();
|
|
30
41
|
let userConfig;
|
|
31
42
|
function initUserConfig() {
|
|
@@ -144,14 +155,6 @@ ${message}`
|
|
|
144
155
|
const normalizedId = normalizePath(id);
|
|
145
156
|
const generatorFileInfo = globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId);
|
|
146
157
|
if (generatorFileInfo && includedCode.some((included) => code.includes(included))) {
|
|
147
|
-
for (const externalPlugin of bannedBeforeExternalPlugins) {
|
|
148
|
-
if (!externalPlugin.frameworks.includes(framework)) {
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
if (code.includes(externalPlugin.identifier)) {
|
|
152
|
-
throw new FoundPluginInBeforeCode(externalPlugin, framework);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
158
|
return handleCompilingReferenceFile(
|
|
156
159
|
code,
|
|
157
160
|
normalizedId,
|
|
@@ -165,6 +168,32 @@ ${message}`
|
|
|
165
168
|
configResolved(config) {
|
|
166
169
|
ROOT = config.root;
|
|
167
170
|
initUserConfig();
|
|
171
|
+
const routerPluginIndex = config.plugins.findIndex(
|
|
172
|
+
(p) => p.name === CODE_SPLITTER_PLUGIN_NAME
|
|
173
|
+
);
|
|
174
|
+
if (routerPluginIndex === -1) return;
|
|
175
|
+
const frameworkPlugins = TRANSFORMATION_PLUGINS_BY_FRAMEWORK[userConfig.target];
|
|
176
|
+
if (!frameworkPlugins) return;
|
|
177
|
+
for (const transformPlugin of frameworkPlugins) {
|
|
178
|
+
const transformPluginIndex = config.plugins.findIndex(
|
|
179
|
+
(p) => transformPlugin.pluginNames.includes(p.name)
|
|
180
|
+
);
|
|
181
|
+
if (transformPluginIndex !== -1 && transformPluginIndex < routerPluginIndex) {
|
|
182
|
+
throw new Error(
|
|
183
|
+
`Plugin order error: '${transformPlugin.pkg}' is placed before '@tanstack/router-plugin'.
|
|
184
|
+
|
|
185
|
+
The TanStack Router plugin must come BEFORE JSX transformation plugins.
|
|
186
|
+
|
|
187
|
+
Please update your Vite config:
|
|
188
|
+
|
|
189
|
+
plugins: [
|
|
190
|
+
tanstackRouter(),
|
|
191
|
+
${transformPlugin.usage},
|
|
192
|
+
]
|
|
193
|
+
`
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
168
197
|
},
|
|
169
198
|
applyToEnvironment(environment) {
|
|
170
199
|
if (userConfig.plugin?.vite?.environmentName) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-code-splitter-plugin.js","sources":["../../../src/core/router-code-splitter-plugin.ts"],"sourcesContent":["/**\n * It is important to familiarize yourself with how the code-splitting works in this plugin.\n * https://github.com/TanStack/router/pull/3355\n */\n\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport {\n compileCodeSplitReferenceRoute,\n compileCodeSplitVirtualRoute,\n detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport {\n defaultCodeSplitGroupings,\n splitRouteIdentNodes,\n tsrSplit,\n} from './constants'\nimport { decodeIdentifier } from './code-splitter/path-ids'\nimport { debug, normalizePath } from './utils'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type {\n UnpluginContextMeta,\n UnpluginFactory,\n TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\ntype BannedBeforeExternalPlugin = {\n identifier: string\n pkg: string\n usage: string\n frameworks: Array<UnpluginContextMeta['framework']>\n}\n\nconst bannedBeforeExternalPlugins: Array<BannedBeforeExternalPlugin> = [\n {\n identifier: '@react-refresh',\n pkg: '@vitejs/plugin-react',\n usage: 'viteReact()',\n frameworks: ['vite'],\n },\n]\n\nclass FoundPluginInBeforeCode extends Error {\n constructor(\n externalPlugin: BannedBeforeExternalPlugin,\n pluginFramework: string,\n ) {\n super(`We detected that the '${externalPlugin.pkg}' was passed before '@tanstack/router-plugin/${pluginFramework}'. Please make sure that '@tanstack/router-plugin' is passed before '${externalPlugin.pkg}' and try again: \ne.g.\nplugins: [\n tanstackRouter(), // Place this before ${externalPlugin.usage}\n ${externalPlugin.usage},\n]\n`)\n }\n}\n\nconst PLUGIN_NAME = 'unplugin:router-code-splitter'\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}, { framework }) => {\n let ROOT: string = process.cwd()\n let userConfig: Config\n\n function initUserConfig() {\n if (typeof options === 'function') {\n userConfig = options()\n } else {\n userConfig = getConfig(options, ROOT)\n }\n }\n const isProduction = process.env.NODE_ENV === 'production'\n\n const getGlobalCodeSplitGroupings = () => {\n return (\n userConfig.codeSplittingOptions?.defaultBehavior ||\n defaultCodeSplitGroupings\n )\n }\n const getShouldSplitFn = () => {\n return userConfig.codeSplittingOptions?.splitBehavior\n }\n\n const handleCompilingReferenceFile = (\n code: string,\n id: string,\n generatorNodeInfo: GetRoutesByFileMapResultValue,\n ): UnpluginTransformResult => {\n if (debug) console.info('Compiling Route: ', id)\n\n const fromCode = detectCodeSplitGroupingsFromRoute({\n code,\n })\n\n if (fromCode.groupings) {\n const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const userShouldSplitFn = getShouldSplitFn()\n\n const pluginSplitBehavior = userShouldSplitFn?.({\n routeId: generatorNodeInfo.routePath,\n }) as CodeSplitGroupings | undefined\n\n if (pluginSplitBehavior) {\n const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings returned when using \\`splitBehavior\\` for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const splitGroupings: CodeSplitGroupings =\n fromCode.groupings || pluginSplitBehavior || getGlobalCodeSplitGroupings()\n\n const compiledReferenceRoute = compileCodeSplitReferenceRoute({\n code,\n codeSplitGroupings: splitGroupings,\n targetFramework: userConfig.target,\n filename: id,\n id,\n deleteNodes: userConfig.codeSplittingOptions?.deleteNodes\n ? new Set(userConfig.codeSplittingOptions.deleteNodes)\n : undefined,\n addHmr:\n (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction,\n })\n\n if (compiledReferenceRoute === null) {\n if (debug) {\n console.info(\n `No changes made to route \"${id}\", skipping code-splitting.`,\n )\n }\n return null\n }\n if (debug) {\n logDiff(code, compiledReferenceRoute.code)\n console.log('Output:\\n', compiledReferenceRoute.code + '\\n\\n')\n }\n\n return compiledReferenceRoute\n }\n\n const handleCompilingVirtualFile = (\n code: string,\n id: string,\n ): UnpluginTransformResult => {\n if (debug) console.info('Splitting Route: ', id)\n\n const [_, ...pathnameParts] = id.split('?')\n\n const searchParams = new URLSearchParams(pathnameParts.join('?'))\n const splitValue = searchParams.get(tsrSplit)\n\n if (!splitValue) {\n throw new Error(\n `The split value for the virtual route \"${id}\" was not found.`,\n )\n }\n\n const rawGrouping = decodeIdentifier(splitValue)\n const grouping = [...new Set(rawGrouping)].filter((p) =>\n splitRouteIdentNodes.includes(p as any),\n ) as Array<SplitRouteIdentNodes>\n\n const result = compileCodeSplitVirtualRoute({\n code,\n filename: id,\n splitTargets: grouping,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n }\n\n const includedCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n ]\n return [\n {\n name: 'tanstack-router:code-splitter:compile-reference-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: {\n exclude: tsrSplit,\n // this is necessary for webpack / rspack to avoid matching .html files\n include: /\\.(m|c)?(j|t)sx?$/,\n },\n code: {\n include: includedCode,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const generatorFileInfo =\n globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId)\n if (\n generatorFileInfo &&\n includedCode.some((included) => code.includes(included))\n ) {\n for (const externalPlugin of bannedBeforeExternalPlugins) {\n if (!externalPlugin.frameworks.includes(framework)) {\n continue\n }\n\n if (code.includes(externalPlugin.identifier)) {\n throw new FoundPluginInBeforeCode(externalPlugin, framework)\n }\n }\n\n return handleCompilingReferenceFile(\n code,\n normalizedId,\n generatorFileInfo,\n )\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n ROOT = config.root\n initUserConfig()\n },\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n\n rspack(compiler) {\n ROOT = process.cwd()\n initUserConfig()\n\n if (compiler.options.mode === 'production') {\n compiler.hooks.done.tap(PLUGIN_NAME, () => {\n console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n })\n }\n },\n\n webpack(compiler) {\n ROOT = process.cwd()\n initUserConfig()\n\n if (compiler.options.mode === 'production') {\n compiler.hooks.done.tap(PLUGIN_NAME, () => {\n console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n })\n }\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-virtual-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-split/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n return handleCompilingVirtualFile(code, normalizedId)\n },\n },\n },\n ]\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"router-code-splitter-plugin.js","sources":["../../../src/core/router-code-splitter-plugin.ts"],"sourcesContent":["/**\n * It is important to familiarize yourself with how the code-splitting works in this plugin.\n * https://github.com/TanStack/router/pull/3355\n */\n\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport {\n compileCodeSplitReferenceRoute,\n compileCodeSplitVirtualRoute,\n detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport {\n defaultCodeSplitGroupings,\n splitRouteIdentNodes,\n tsrSplit,\n} from './constants'\nimport { decodeIdentifier } from './code-splitter/path-ids'\nimport { debug, normalizePath } from './utils'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type {\n UnpluginFactory,\n TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\nconst PLUGIN_NAME = 'unplugin:router-code-splitter'\nconst CODE_SPLITTER_PLUGIN_NAME =\n 'tanstack-router:code-splitter:compile-reference-file'\n\ntype TransformationPluginInfo = {\n pluginNames: Array<string>\n pkg: string\n usage: string\n}\n\n/**\n * JSX transformation plugins grouped by framework.\n * These plugins must come AFTER the TanStack Router plugin in the Vite config.\n */\nconst TRANSFORMATION_PLUGINS_BY_FRAMEWORK: Record<\n string,\n Array<TransformationPluginInfo>\n> = {\n react: [\n {\n // Babel-based React plugin\n pluginNames: ['vite:react-babel', 'vite:react-refresh'],\n pkg: '@vitejs/plugin-react',\n usage: 'react()',\n },\n {\n // SWC-based React plugin\n pluginNames: ['vite:react-swc', 'vite:react-swc:resolve-runtime'],\n pkg: '@vitejs/plugin-react-swc',\n usage: 'reactSwc()',\n },\n {\n // OXC-based React plugin (deprecated but should still be handled)\n pluginNames: ['vite:react-oxc:config', 'vite:react-oxc:refresh-runtime'],\n pkg: '@vitejs/plugin-react-oxc',\n usage: 'reactOxc()',\n },\n ],\n solid: [\n {\n pluginNames: ['solid'],\n pkg: 'vite-plugin-solid',\n usage: 'solid()',\n },\n ],\n}\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}, { framework: _framework }) => {\n let ROOT: string = process.cwd()\n let userConfig: Config\n\n function initUserConfig() {\n if (typeof options === 'function') {\n userConfig = options()\n } else {\n userConfig = getConfig(options, ROOT)\n }\n }\n const isProduction = process.env.NODE_ENV === 'production'\n\n const getGlobalCodeSplitGroupings = () => {\n return (\n userConfig.codeSplittingOptions?.defaultBehavior ||\n defaultCodeSplitGroupings\n )\n }\n const getShouldSplitFn = () => {\n return userConfig.codeSplittingOptions?.splitBehavior\n }\n\n const handleCompilingReferenceFile = (\n code: string,\n id: string,\n generatorNodeInfo: GetRoutesByFileMapResultValue,\n ): UnpluginTransformResult => {\n if (debug) console.info('Compiling Route: ', id)\n\n const fromCode = detectCodeSplitGroupingsFromRoute({\n code,\n })\n\n if (fromCode.groupings) {\n const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const userShouldSplitFn = getShouldSplitFn()\n\n const pluginSplitBehavior = userShouldSplitFn?.({\n routeId: generatorNodeInfo.routePath,\n }) as CodeSplitGroupings | undefined\n\n if (pluginSplitBehavior) {\n const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings returned when using \\`splitBehavior\\` for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const splitGroupings: CodeSplitGroupings =\n fromCode.groupings || pluginSplitBehavior || getGlobalCodeSplitGroupings()\n\n const compiledReferenceRoute = compileCodeSplitReferenceRoute({\n code,\n codeSplitGroupings: splitGroupings,\n targetFramework: userConfig.target,\n filename: id,\n id,\n deleteNodes: userConfig.codeSplittingOptions?.deleteNodes\n ? new Set(userConfig.codeSplittingOptions.deleteNodes)\n : undefined,\n addHmr:\n (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction,\n })\n\n if (compiledReferenceRoute === null) {\n if (debug) {\n console.info(\n `No changes made to route \"${id}\", skipping code-splitting.`,\n )\n }\n return null\n }\n if (debug) {\n logDiff(code, compiledReferenceRoute.code)\n console.log('Output:\\n', compiledReferenceRoute.code + '\\n\\n')\n }\n\n return compiledReferenceRoute\n }\n\n const handleCompilingVirtualFile = (\n code: string,\n id: string,\n ): UnpluginTransformResult => {\n if (debug) console.info('Splitting Route: ', id)\n\n const [_, ...pathnameParts] = id.split('?')\n\n const searchParams = new URLSearchParams(pathnameParts.join('?'))\n const splitValue = searchParams.get(tsrSplit)\n\n if (!splitValue) {\n throw new Error(\n `The split value for the virtual route \"${id}\" was not found.`,\n )\n }\n\n const rawGrouping = decodeIdentifier(splitValue)\n const grouping = [...new Set(rawGrouping)].filter((p) =>\n splitRouteIdentNodes.includes(p as any),\n ) as Array<SplitRouteIdentNodes>\n\n const result = compileCodeSplitVirtualRoute({\n code,\n filename: id,\n splitTargets: grouping,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n }\n\n const includedCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n ]\n return [\n {\n name: 'tanstack-router:code-splitter:compile-reference-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: {\n exclude: tsrSplit,\n // this is necessary for webpack / rspack to avoid matching .html files\n include: /\\.(m|c)?(j|t)sx?$/,\n },\n code: {\n include: includedCode,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const generatorFileInfo =\n globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId)\n if (\n generatorFileInfo &&\n includedCode.some((included) => code.includes(included))\n ) {\n return handleCompilingReferenceFile(\n code,\n normalizedId,\n generatorFileInfo,\n )\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n ROOT = config.root\n initUserConfig()\n\n // Validate plugin order - router must come before JSX transformation plugins\n const routerPluginIndex = config.plugins.findIndex(\n (p) => p.name === CODE_SPLITTER_PLUGIN_NAME,\n )\n\n if (routerPluginIndex === -1) return\n\n const frameworkPlugins =\n TRANSFORMATION_PLUGINS_BY_FRAMEWORK[userConfig.target]\n if (!frameworkPlugins) return\n\n for (const transformPlugin of frameworkPlugins) {\n const transformPluginIndex = config.plugins.findIndex((p) =>\n transformPlugin.pluginNames.includes(p.name),\n )\n\n if (\n transformPluginIndex !== -1 &&\n transformPluginIndex < routerPluginIndex\n ) {\n throw new Error(\n `Plugin order error: '${transformPlugin.pkg}' is placed before '@tanstack/router-plugin'.\\n\\n` +\n `The TanStack Router plugin must come BEFORE JSX transformation plugins.\\n\\n` +\n `Please update your Vite config:\\n\\n` +\n ` plugins: [\\n` +\n ` tanstackRouter(),\\n` +\n ` ${transformPlugin.usage},\\n` +\n ` ]\\n`,\n )\n }\n }\n },\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n\n rspack(compiler) {\n ROOT = process.cwd()\n initUserConfig()\n\n if (compiler.options.mode === 'production') {\n compiler.hooks.done.tap(PLUGIN_NAME, () => {\n console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n })\n }\n },\n\n webpack(compiler) {\n ROOT = process.cwd()\n initUserConfig()\n\n if (compiler.options.mode === 'production') {\n compiler.hooks.done.tap(PLUGIN_NAME, () => {\n console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n })\n }\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-virtual-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-split/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n return handleCompilingVirtualFile(code, normalizedId)\n },\n },\n },\n ]\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/router-plugin",
|
|
3
|
-
"version": "1.151.
|
|
3
|
+
"version": "1.151.4",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -98,9 +98,9 @@
|
|
|
98
98
|
"unplugin": "^2.1.2",
|
|
99
99
|
"zod": "^3.24.2",
|
|
100
100
|
"@tanstack/router-core": "1.151.3",
|
|
101
|
-
"@tanstack/router-
|
|
101
|
+
"@tanstack/router-generator": "1.151.3",
|
|
102
102
|
"@tanstack/virtual-file-routes": "1.145.4",
|
|
103
|
-
"@tanstack/router-
|
|
103
|
+
"@tanstack/router-utils": "1.143.11"
|
|
104
104
|
},
|
|
105
105
|
"devDependencies": {
|
|
106
106
|
"@types/babel__core": "^7.20.5",
|
|
@@ -22,47 +22,60 @@ import type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'
|
|
|
22
22
|
import type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'
|
|
23
23
|
import type { Config } from './config'
|
|
24
24
|
import type {
|
|
25
|
-
UnpluginContextMeta,
|
|
26
25
|
UnpluginFactory,
|
|
27
26
|
TransformResult as UnpluginTransformResult,
|
|
28
27
|
} from 'unplugin'
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
const PLUGIN_NAME = 'unplugin:router-code-splitter'
|
|
30
|
+
const CODE_SPLITTER_PLUGIN_NAME =
|
|
31
|
+
'tanstack-router:code-splitter:compile-reference-file'
|
|
32
|
+
|
|
33
|
+
type TransformationPluginInfo = {
|
|
34
|
+
pluginNames: Array<string>
|
|
32
35
|
pkg: string
|
|
33
36
|
usage: string
|
|
34
|
-
frameworks: Array<UnpluginContextMeta['framework']>
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
39
|
+
/**
|
|
40
|
+
* JSX transformation plugins grouped by framework.
|
|
41
|
+
* These plugins must come AFTER the TanStack Router plugin in the Vite config.
|
|
42
|
+
*/
|
|
43
|
+
const TRANSFORMATION_PLUGINS_BY_FRAMEWORK: Record<
|
|
44
|
+
string,
|
|
45
|
+
Array<TransformationPluginInfo>
|
|
46
|
+
> = {
|
|
47
|
+
react: [
|
|
48
|
+
{
|
|
49
|
+
// Babel-based React plugin
|
|
50
|
+
pluginNames: ['vite:react-babel', 'vite:react-refresh'],
|
|
51
|
+
pkg: '@vitejs/plugin-react',
|
|
52
|
+
usage: 'react()',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
// SWC-based React plugin
|
|
56
|
+
pluginNames: ['vite:react-swc', 'vite:react-swc:resolve-runtime'],
|
|
57
|
+
pkg: '@vitejs/plugin-react-swc',
|
|
58
|
+
usage: 'reactSwc()',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
// OXC-based React plugin (deprecated but should still be handled)
|
|
62
|
+
pluginNames: ['vite:react-oxc:config', 'vite:react-oxc:refresh-runtime'],
|
|
63
|
+
pkg: '@vitejs/plugin-react-oxc',
|
|
64
|
+
usage: 'reactOxc()',
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
solid: [
|
|
68
|
+
{
|
|
69
|
+
pluginNames: ['solid'],
|
|
70
|
+
pkg: 'vite-plugin-solid',
|
|
71
|
+
usage: 'solid()',
|
|
72
|
+
},
|
|
73
|
+
],
|
|
59
74
|
}
|
|
60
75
|
|
|
61
|
-
const PLUGIN_NAME = 'unplugin:router-code-splitter'
|
|
62
|
-
|
|
63
76
|
export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
|
|
64
77
|
Partial<Config | (() => Config)> | undefined
|
|
65
|
-
> = (options = {}, { framework }) => {
|
|
78
|
+
> = (options = {}, { framework: _framework }) => {
|
|
66
79
|
let ROOT: string = process.cwd()
|
|
67
80
|
let userConfig: Config
|
|
68
81
|
|
|
@@ -219,16 +232,6 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
|
|
|
219
232
|
generatorFileInfo &&
|
|
220
233
|
includedCode.some((included) => code.includes(included))
|
|
221
234
|
) {
|
|
222
|
-
for (const externalPlugin of bannedBeforeExternalPlugins) {
|
|
223
|
-
if (!externalPlugin.frameworks.includes(framework)) {
|
|
224
|
-
continue
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (code.includes(externalPlugin.identifier)) {
|
|
228
|
-
throw new FoundPluginInBeforeCode(externalPlugin, framework)
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
235
|
return handleCompilingReferenceFile(
|
|
233
236
|
code,
|
|
234
237
|
normalizedId,
|
|
@@ -244,6 +247,38 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
|
|
|
244
247
|
configResolved(config) {
|
|
245
248
|
ROOT = config.root
|
|
246
249
|
initUserConfig()
|
|
250
|
+
|
|
251
|
+
// Validate plugin order - router must come before JSX transformation plugins
|
|
252
|
+
const routerPluginIndex = config.plugins.findIndex(
|
|
253
|
+
(p) => p.name === CODE_SPLITTER_PLUGIN_NAME,
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
if (routerPluginIndex === -1) return
|
|
257
|
+
|
|
258
|
+
const frameworkPlugins =
|
|
259
|
+
TRANSFORMATION_PLUGINS_BY_FRAMEWORK[userConfig.target]
|
|
260
|
+
if (!frameworkPlugins) return
|
|
261
|
+
|
|
262
|
+
for (const transformPlugin of frameworkPlugins) {
|
|
263
|
+
const transformPluginIndex = config.plugins.findIndex((p) =>
|
|
264
|
+
transformPlugin.pluginNames.includes(p.name),
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
if (
|
|
268
|
+
transformPluginIndex !== -1 &&
|
|
269
|
+
transformPluginIndex < routerPluginIndex
|
|
270
|
+
) {
|
|
271
|
+
throw new Error(
|
|
272
|
+
`Plugin order error: '${transformPlugin.pkg}' is placed before '@tanstack/router-plugin'.\n\n` +
|
|
273
|
+
`The TanStack Router plugin must come BEFORE JSX transformation plugins.\n\n` +
|
|
274
|
+
`Please update your Vite config:\n\n` +
|
|
275
|
+
` plugins: [\n` +
|
|
276
|
+
` tanstackRouter(),\n` +
|
|
277
|
+
` ${transformPlugin.usage},\n` +
|
|
278
|
+
` ]\n`,
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
247
282
|
},
|
|
248
283
|
applyToEnvironment(environment) {
|
|
249
284
|
if (userConfig.plugin?.vite?.environmentName) {
|