@tanstack/router-plugin 1.146.2 → 1.147.0
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/route-autoimport-plugin.cjs +5 -4
- package/dist/cjs/core/route-autoimport-plugin.cjs.map +1 -1
- package/dist/cjs/core/router-code-splitter-plugin.cjs +9 -4
- package/dist/cjs/core/router-code-splitter-plugin.cjs.map +1 -1
- package/dist/cjs/core/router-hmr-plugin.cjs +5 -4
- package/dist/cjs/core/router-hmr-plugin.cjs.map +1 -1
- package/dist/cjs/core/utils.cjs +4 -0
- package/dist/cjs/core/utils.cjs.map +1 -1
- package/dist/cjs/core/utils.d.cts +8 -0
- package/dist/esm/core/route-autoimport-plugin.js +6 -5
- package/dist/esm/core/route-autoimport-plugin.js.map +1 -1
- package/dist/esm/core/router-code-splitter-plugin.js +10 -5
- package/dist/esm/core/router-code-splitter-plugin.js.map +1 -1
- package/dist/esm/core/router-hmr-plugin.js +6 -5
- package/dist/esm/core/router-hmr-plugin.js.map +1 -1
- package/dist/esm/core/utils.d.ts +8 -0
- package/dist/esm/core/utils.js +5 -1
- package/dist/esm/core/utils.js.map +1 -1
- package/package.json +4 -4
- package/src/core/route-autoimport-plugin.ts +6 -5
- package/src/core/router-code-splitter-plugin.ts +11 -5
- package/src/core/router-hmr-plugin.ts +6 -5
- package/src/core/utils.ts +11 -0
|
@@ -42,7 +42,8 @@ const unpluginRouteAutoImportFactory = (options = {}) => {
|
|
|
42
42
|
code: /createFileRoute\(|createLazyFileRoute\(/
|
|
43
43
|
},
|
|
44
44
|
handler(code, id) {
|
|
45
|
-
|
|
45
|
+
const normalizedId = utils.normalizePath(id);
|
|
46
|
+
if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {
|
|
46
47
|
return null;
|
|
47
48
|
}
|
|
48
49
|
let routeType;
|
|
@@ -73,15 +74,15 @@ const unpluginRouteAutoImportFactory = (options = {}) => {
|
|
|
73
74
|
}
|
|
74
75
|
});
|
|
75
76
|
if (!isCreateRouteFunctionImported) {
|
|
76
|
-
if (utils.debug) console.info("Adding autoimports to route ",
|
|
77
|
+
if (utils.debug) console.info("Adding autoimports to route ", normalizedId);
|
|
77
78
|
const autoImportStatement = template__namespace.statement(
|
|
78
79
|
`import { ${routeType} } from '${routerImportPath}'`
|
|
79
80
|
)();
|
|
80
81
|
ast.program.body.unshift(autoImportStatement);
|
|
81
82
|
const result = routerUtils.generateFromAst(ast, {
|
|
82
83
|
sourceMaps: true,
|
|
83
|
-
filename:
|
|
84
|
-
sourceFileName:
|
|
84
|
+
filename: normalizedId,
|
|
85
|
+
sourceFileName: normalizedId
|
|
85
86
|
});
|
|
86
87
|
if (utils.debug) {
|
|
87
88
|
routerUtils.logDiff(code, result.code);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-autoimport-plugin.cjs","sources":["../../../src/core/route-autoimport-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport babel from '@babel/core'\nimport * as template from '@babel/template'\nimport { getConfig } from './config'\nimport { debug } from './utils'\nimport type { Config } from './config'\nimport type { UnpluginFactory } from 'unplugin'\n\n/**\n * This plugin adds imports for createFileRoute and createLazyFileRoute to the file route.\n */\nexport const unpluginRouteAutoImportFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}) => {\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 return {\n name: 'tanstack-router:autoimport',\n enforce: 'pre',\n\n transform: {\n filter: {\n // this is necessary for webpack / rspack to avoid matching .html files\n id: /\\.(m|c)?(j|t)sx?$/,\n code: /createFileRoute\\(|createLazyFileRoute\\(/,\n },\n handler(code, id) {\n if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(
|
|
1
|
+
{"version":3,"file":"route-autoimport-plugin.cjs","sources":["../../../src/core/route-autoimport-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport babel from '@babel/core'\nimport * as template from '@babel/template'\nimport { getConfig } from './config'\nimport { debug, normalizePath } from './utils'\nimport type { Config } from './config'\nimport type { UnpluginFactory } from 'unplugin'\n\n/**\n * This plugin adds imports for createFileRoute and createLazyFileRoute to the file route.\n */\nexport const unpluginRouteAutoImportFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}) => {\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 return {\n name: 'tanstack-router:autoimport',\n enforce: 'pre',\n\n transform: {\n filter: {\n // this is necessary for webpack / rspack to avoid matching .html files\n id: /\\.(m|c)?(j|t)sx?$/,\n code: /createFileRoute\\(|createLazyFileRoute\\(/,\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {\n return null\n }\n let routeType: 'createFileRoute' | 'createLazyFileRoute'\n if (code.includes('createFileRoute(')) {\n routeType = 'createFileRoute'\n } else if (code.includes('createLazyFileRoute(')) {\n routeType = 'createLazyFileRoute'\n } else {\n return null\n }\n\n const routerImportPath = `@tanstack/${userConfig.target}-router`\n\n const ast = parseAst({ code })\n\n let isCreateRouteFunctionImported = false as boolean\n\n babel.traverse(ast, {\n Program: {\n enter(programPath) {\n programPath.traverse({\n ImportDeclaration(path) {\n const importedSpecifiers = path.node.specifiers.map(\n (specifier) => specifier.local.name,\n )\n if (\n importedSpecifiers.includes(routeType) &&\n path.node.source.value === routerImportPath\n ) {\n isCreateRouteFunctionImported = true\n }\n },\n })\n },\n },\n })\n\n if (!isCreateRouteFunctionImported) {\n if (debug) console.info('Adding autoimports to route ', normalizedId)\n\n const autoImportStatement = template.statement(\n `import { ${routeType} } from '${routerImportPath}'`,\n )()\n ast.program.body.unshift(autoImportStatement)\n\n const result = generateFromAst(ast, {\n sourceMaps: true,\n filename: normalizedId,\n sourceFileName: normalizedId,\n })\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n return result\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n ROOT = config.root\n initUserConfig()\n },\n // this check may only happen after config is resolved, so we use applyToEnvironment (apply is too early)\n applyToEnvironment() {\n return userConfig.verboseFileRoutes === false\n },\n },\n\n rspack() {\n ROOT = process.cwd()\n initUserConfig()\n },\n\n webpack() {\n ROOT = process.cwd()\n initUserConfig()\n },\n }\n}\n"],"names":["getConfig","normalizePath","parseAst","debug","template","generateFromAst","logDiff","config"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAWO,MAAM,iCAET,CAAC,UAAU,OAAO;AACpB,MAAI,OAAe,QAAQ,IAAA;AAC3B,MAAI;AAEJ,WAAS,iBAAiB;AACxB,QAAI,OAAO,YAAY,YAAY;AACjC,mBAAa,QAAA;AAAA,IACf,OAAO;AACL,mBAAaA,OAAAA,UAAU,SAAS,IAAI;AAAA,IACtC;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,WAAW;AAAA,MACT,QAAQ;AAAA;AAAA,QAEN,IAAI;AAAA,QACJ,MAAM;AAAA,MAAA;AAAA,MAER,QAAQ,MAAM,IAAI;AAChB,cAAM,eAAeC,MAAAA,cAAc,EAAE;AACrC,YAAI,CAAC,WAAW,sBAAsB,IAAI,YAAY,GAAG;AACvD,iBAAO;AAAA,QACT;AACA,YAAI;AACJ,YAAI,KAAK,SAAS,kBAAkB,GAAG;AACrC,sBAAY;AAAA,QACd,WAAW,KAAK,SAAS,sBAAsB,GAAG;AAChD,sBAAY;AAAA,QACd,OAAO;AACL,iBAAO;AAAA,QACT;AAEA,cAAM,mBAAmB,aAAa,WAAW,MAAM;AAEvD,cAAM,MAAMC,YAAAA,SAAS,EAAE,MAAM;AAE7B,YAAI,gCAAgC;AAEpC,cAAM,SAAS,KAAK;AAAA,UAClB,SAAS;AAAA,YACP,MAAM,aAAa;AACjB,0BAAY,SAAS;AAAA,gBACnB,kBAAkB,MAAM;AACtB,wBAAM,qBAAqB,KAAK,KAAK,WAAW;AAAA,oBAC9C,CAAC,cAAc,UAAU,MAAM;AAAA,kBAAA;AAEjC,sBACE,mBAAmB,SAAS,SAAS,KACrC,KAAK,KAAK,OAAO,UAAU,kBAC3B;AACA,oDAAgC;AAAA,kBAClC;AAAA,gBACF;AAAA,cAAA,CACD;AAAA,YACH;AAAA,UAAA;AAAA,QACF,CACD;AAED,YAAI,CAAC,+BAA+B;AAClC,cAAIC,MAAAA,MAAO,SAAQ,KAAK,gCAAgC,YAAY;AAEpE,gBAAM,sBAAsBC,oBAAS;AAAA,YACnC,YAAY,SAAS,YAAY,gBAAgB;AAAA,UAAA,EACnD;AACA,cAAI,QAAQ,KAAK,QAAQ,mBAAmB;AAE5C,gBAAM,SAASC,YAAAA,gBAAgB,KAAK;AAAA,YAClC,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,gBAAgB;AAAA,UAAA,CACjB;AACD,cAAIF,aAAO;AACTG,gCAAQ,MAAM,OAAO,IAAI;AACzB,oBAAQ,IAAI,aAAa,OAAO,OAAO,MAAM;AAAA,UAC/C;AACA,iBAAO;AAAA,QACT;AAEA,eAAO;AAAA,MACT;AAAA,IAAA;AAAA,IAGF,MAAM;AAAA,MACJ,eAAeC,SAAQ;AACrB,eAAOA,QAAO;AACd,uBAAA;AAAA,MACF;AAAA;AAAA,MAEA,qBAAqB;AACnB,eAAO,WAAW,sBAAsB;AAAA,MAC1C;AAAA,IAAA;AAAA,IAGF,SAAS;AACP,aAAO,QAAQ,IAAA;AACf,qBAAA;AAAA,IACF;AAAA,IAEA,UAAU;AACR,aAAO,QAAQ,IAAA;AACf,qBAAA;AAAA,IACF;AAAA,EAAA;AAEJ;;"}
|
|
@@ -143,7 +143,8 @@ ${message}`
|
|
|
143
143
|
}
|
|
144
144
|
},
|
|
145
145
|
handler(code, id) {
|
|
146
|
-
const
|
|
146
|
+
const normalizedId = utils.normalizePath(id);
|
|
147
|
+
const generatorFileInfo = globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId);
|
|
147
148
|
if (generatorFileInfo && includedCode.some((included) => code.includes(included))) {
|
|
148
149
|
for (const externalPlugin of bannedBeforeExternalPlugins) {
|
|
149
150
|
if (!externalPlugin.frameworks.includes(framework)) {
|
|
@@ -153,7 +154,11 @@ ${message}`
|
|
|
153
154
|
throw new FoundPluginInBeforeCode(externalPlugin, framework);
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
|
-
return handleCompilingReferenceFile(
|
|
157
|
+
return handleCompilingReferenceFile(
|
|
158
|
+
code,
|
|
159
|
+
normalizedId,
|
|
160
|
+
generatorFileInfo
|
|
161
|
+
);
|
|
157
162
|
}
|
|
158
163
|
return null;
|
|
159
164
|
}
|
|
@@ -199,8 +204,8 @@ ${message}`
|
|
|
199
204
|
handler(code, id) {
|
|
200
205
|
const url = node_url.pathToFileURL(id);
|
|
201
206
|
url.searchParams.delete("v");
|
|
202
|
-
|
|
203
|
-
return handleCompilingVirtualFile(code,
|
|
207
|
+
const normalizedId = utils.normalizePath(node_url.fileURLToPath(url));
|
|
208
|
+
return handleCompilingVirtualFile(code, normalizedId);
|
|
204
209
|
}
|
|
205
210
|
}
|
|
206
211
|
}
|
|
@@ -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 } 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 generatorFileInfo = globalThis.TSR_ROUTES_BY_ID_MAP?.get(id)\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(code, id, generatorFileInfo)\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 id = fileURLToPath(url).replace(/\\\\/g, '/')\n return handleCompilingVirtualFile(code, id)\n },\n },\n },\n ]\n}\n"],"names":["getConfig","defaultCodeSplitGroupings","debug","detectCodeSplitGroupingsFromRoute","splitGroupingsSchema","compileCodeSplitReferenceRoute","logDiff","tsrSplit","decodeIdentifier","splitRouteIdentNodes","compileCodeSplitVirtualRoute","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 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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"}
|
|
@@ -24,16 +24,17 @@ const unpluginRouterHmrFactory = (options = {}) => {
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
handler(code, id) {
|
|
27
|
-
|
|
27
|
+
const normalizedId = utils.normalizePath(id);
|
|
28
|
+
if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {
|
|
28
29
|
return null;
|
|
29
30
|
}
|
|
30
|
-
if (utils.debug) console.info("Adding HMR handling to route ",
|
|
31
|
+
if (utils.debug) console.info("Adding HMR handling to route ", normalizedId);
|
|
31
32
|
const ast = routerUtils.parseAst({ code });
|
|
32
33
|
ast.program.body.push(routeHmrStatement.routeHmrStatement);
|
|
33
34
|
const result = routerUtils.generateFromAst(ast, {
|
|
34
35
|
sourceMaps: true,
|
|
35
|
-
filename:
|
|
36
|
-
sourceFileName:
|
|
36
|
+
filename: normalizedId,
|
|
37
|
+
sourceFileName: normalizedId
|
|
37
38
|
});
|
|
38
39
|
if (utils.debug) {
|
|
39
40
|
routerUtils.logDiff(code, result.code);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-hmr-plugin.cjs","sources":["../../../src/core/router-hmr-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport { routeHmrStatement } from './route-hmr-statement'\nimport { debug } from './utils'\nimport { getConfig } from './config'\nimport type { UnpluginFactory } from 'unplugin'\nimport type { Config } from './config'\n\n/**\n * This plugin adds HMR support for file routes.\n * It is only added to the composed plugin in dev when autoCodeSplitting is disabled, since the code splitting plugin\n * handles HMR for code-split routes itself.\n */\n\nconst includeCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n]\nexport const unpluginRouterHmrFactory: UnpluginFactory<\n Partial<Config> | undefined\n> = (options = {}) => {\n let ROOT: string = process.cwd()\n let userConfig = options as Config\n\n return {\n name: 'tanstack-router:hmr',\n enforce: 'pre',\n transform: {\n filter: {\n // this is necessary for webpack / rspack to avoid matching .html files\n id: /\\.(m|c)?(j|t)sx?$/,\n code: {\n include: includeCode,\n },\n },\n handler(code, id) {\n if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(
|
|
1
|
+
{"version":3,"file":"router-hmr-plugin.cjs","sources":["../../../src/core/router-hmr-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport { routeHmrStatement } from './route-hmr-statement'\nimport { debug, normalizePath } from './utils'\nimport { getConfig } from './config'\nimport type { UnpluginFactory } from 'unplugin'\nimport type { Config } from './config'\n\n/**\n * This plugin adds HMR support for file routes.\n * It is only added to the composed plugin in dev when autoCodeSplitting is disabled, since the code splitting plugin\n * handles HMR for code-split routes itself.\n */\n\nconst includeCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n]\nexport const unpluginRouterHmrFactory: UnpluginFactory<\n Partial<Config> | undefined\n> = (options = {}) => {\n let ROOT: string = process.cwd()\n let userConfig = options as Config\n\n return {\n name: 'tanstack-router:hmr',\n enforce: 'pre',\n transform: {\n filter: {\n // this is necessary for webpack / rspack to avoid matching .html files\n id: /\\.(m|c)?(j|t)sx?$/,\n code: {\n include: includeCode,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {\n return null\n }\n\n if (debug) console.info('Adding HMR handling to route ', normalizedId)\n\n const ast = parseAst({ code })\n ast.program.body.push(routeHmrStatement)\n const result = generateFromAst(ast, {\n sourceMaps: true,\n filename: normalizedId,\n sourceFileName: normalizedId,\n })\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n return result\n },\n },\n vite: {\n configResolved(config) {\n ROOT = config.root\n userConfig = getConfig(options, ROOT)\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}\n"],"names":["normalizePath","debug","parseAst","routeHmrStatement","generateFromAst","logDiff","config","getConfig"],"mappings":";;;;;;AAaA,MAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AACF;AACO,MAAM,2BAET,CAAC,UAAU,OAAO;AACpB,MAAI,OAAe,QAAQ,IAAA;AAC3B,MAAI,aAAa;AAEjB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,MACT,QAAQ;AAAA;AAAA,QAEN,IAAI;AAAA,QACJ,MAAM;AAAA,UACJ,SAAS;AAAA,QAAA;AAAA,MACX;AAAA,MAEF,QAAQ,MAAM,IAAI;AAChB,cAAM,eAAeA,MAAAA,cAAc,EAAE;AACrC,YAAI,CAAC,WAAW,sBAAsB,IAAI,YAAY,GAAG;AACvD,iBAAO;AAAA,QACT;AAEA,YAAIC,MAAAA,MAAO,SAAQ,KAAK,iCAAiC,YAAY;AAErE,cAAM,MAAMC,YAAAA,SAAS,EAAE,MAAM;AAC7B,YAAI,QAAQ,KAAK,KAAKC,kBAAAA,iBAAiB;AACvC,cAAM,SAASC,YAAAA,gBAAgB,KAAK;AAAA,UAClC,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,gBAAgB;AAAA,QAAA,CACjB;AACD,YAAIH,aAAO;AACTI,8BAAQ,MAAM,OAAO,IAAI;AACzB,kBAAQ,IAAI,aAAa,OAAO,OAAO,MAAM;AAAA,QAC/C;AACA,eAAO;AAAA,MACT;AAAA,IAAA;AAAA,IAEF,MAAM;AAAA,MACJ,eAAeC,UAAQ;AACrB,eAAOA,SAAO;AACd,qBAAaC,OAAAA,UAAU,SAAS,IAAI;AAAA,MACtC;AAAA,MACA,mBAAmB,aAAa;AAC9B,YAAI,WAAW,QAAQ,MAAM,iBAAiB;AAC5C,iBAAO,WAAW,OAAO,KAAK,oBAAoB,YAAY;AAAA,QAChE;AACA,eAAO;AAAA,MACT;AAAA,IAAA;AAAA,EACF;AAEJ;;"}
|
package/dist/cjs/core/utils.cjs
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const debug = process.env.TSR_VITE_DEBUG && ["true", "router-plugin"].includes(process.env.TSR_VITE_DEBUG);
|
|
4
|
+
function normalizePath(path) {
|
|
5
|
+
return path.replace(/\\/g, "/");
|
|
6
|
+
}
|
|
4
7
|
exports.debug = debug;
|
|
8
|
+
exports.normalizePath = normalizePath;
|
|
5
9
|
//# sourceMappingURL=utils.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","sources":["../../../src/core/utils.ts"],"sourcesContent":["export const debug =\n process.env.TSR_VITE_DEBUG &&\n ['true', 'router-plugin'].includes(process.env.TSR_VITE_DEBUG)\n"],"names":[],"mappings":";;AAAO,MAAM,QACX,QAAQ,IAAI,kBACZ,CAAC,QAAQ,eAAe,EAAE,SAAS,QAAQ,IAAI,cAAc
|
|
1
|
+
{"version":3,"file":"utils.cjs","sources":["../../../src/core/utils.ts"],"sourcesContent":["export const debug =\n process.env.TSR_VITE_DEBUG &&\n ['true', 'router-plugin'].includes(process.env.TSR_VITE_DEBUG)\n\n/**\n * Normalizes a file path by converting Windows backslashes to forward slashes.\n * This ensures consistent path handling across different bundlers and operating systems.\n *\n * The route generator stores paths with forward slashes, but rspack/webpack on Windows\n * pass native paths with backslashes to transform handlers.\n */\nexport function normalizePath(path: string): string {\n return path.replace(/\\\\/g, '/')\n}\n"],"names":[],"mappings":";;AAAO,MAAM,QACX,QAAQ,IAAI,kBACZ,CAAC,QAAQ,eAAe,EAAE,SAAS,QAAQ,IAAI,cAAc;AASxD,SAAS,cAAc,MAAsB;AAClD,SAAO,KAAK,QAAQ,OAAO,GAAG;AAChC;;;"}
|
|
@@ -1 +1,9 @@
|
|
|
1
1
|
export declare const debug: boolean | "" | undefined;
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a file path by converting Windows backslashes to forward slashes.
|
|
4
|
+
* This ensures consistent path handling across different bundlers and operating systems.
|
|
5
|
+
*
|
|
6
|
+
* The route generator stores paths with forward slashes, but rspack/webpack on Windows
|
|
7
|
+
* pass native paths with backslashes to transform handlers.
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizePath(path: string): string;
|
|
@@ -2,7 +2,7 @@ import { parseAst, generateFromAst, logDiff } from "@tanstack/router-utils";
|
|
|
2
2
|
import babel from "@babel/core";
|
|
3
3
|
import * as template from "@babel/template";
|
|
4
4
|
import { getConfig } from "./config.js";
|
|
5
|
-
import { debug } from "./utils.js";
|
|
5
|
+
import { normalizePath, debug } from "./utils.js";
|
|
6
6
|
const unpluginRouteAutoImportFactory = (options = {}) => {
|
|
7
7
|
let ROOT = process.cwd();
|
|
8
8
|
let userConfig;
|
|
@@ -23,7 +23,8 @@ const unpluginRouteAutoImportFactory = (options = {}) => {
|
|
|
23
23
|
code: /createFileRoute\(|createLazyFileRoute\(/
|
|
24
24
|
},
|
|
25
25
|
handler(code, id) {
|
|
26
|
-
|
|
26
|
+
const normalizedId = normalizePath(id);
|
|
27
|
+
if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {
|
|
27
28
|
return null;
|
|
28
29
|
}
|
|
29
30
|
let routeType;
|
|
@@ -54,15 +55,15 @@ const unpluginRouteAutoImportFactory = (options = {}) => {
|
|
|
54
55
|
}
|
|
55
56
|
});
|
|
56
57
|
if (!isCreateRouteFunctionImported) {
|
|
57
|
-
if (debug) console.info("Adding autoimports to route ",
|
|
58
|
+
if (debug) console.info("Adding autoimports to route ", normalizedId);
|
|
58
59
|
const autoImportStatement = template.statement(
|
|
59
60
|
`import { ${routeType} } from '${routerImportPath}'`
|
|
60
61
|
)();
|
|
61
62
|
ast.program.body.unshift(autoImportStatement);
|
|
62
63
|
const result = generateFromAst(ast, {
|
|
63
64
|
sourceMaps: true,
|
|
64
|
-
filename:
|
|
65
|
-
sourceFileName:
|
|
65
|
+
filename: normalizedId,
|
|
66
|
+
sourceFileName: normalizedId
|
|
66
67
|
});
|
|
67
68
|
if (debug) {
|
|
68
69
|
logDiff(code, result.code);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-autoimport-plugin.js","sources":["../../../src/core/route-autoimport-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport babel from '@babel/core'\nimport * as template from '@babel/template'\nimport { getConfig } from './config'\nimport { debug } from './utils'\nimport type { Config } from './config'\nimport type { UnpluginFactory } from 'unplugin'\n\n/**\n * This plugin adds imports for createFileRoute and createLazyFileRoute to the file route.\n */\nexport const unpluginRouteAutoImportFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}) => {\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 return {\n name: 'tanstack-router:autoimport',\n enforce: 'pre',\n\n transform: {\n filter: {\n // this is necessary for webpack / rspack to avoid matching .html files\n id: /\\.(m|c)?(j|t)sx?$/,\n code: /createFileRoute\\(|createLazyFileRoute\\(/,\n },\n handler(code, id) {\n if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(
|
|
1
|
+
{"version":3,"file":"route-autoimport-plugin.js","sources":["../../../src/core/route-autoimport-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport babel from '@babel/core'\nimport * as template from '@babel/template'\nimport { getConfig } from './config'\nimport { debug, normalizePath } from './utils'\nimport type { Config } from './config'\nimport type { UnpluginFactory } from 'unplugin'\n\n/**\n * This plugin adds imports for createFileRoute and createLazyFileRoute to the file route.\n */\nexport const unpluginRouteAutoImportFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}) => {\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 return {\n name: 'tanstack-router:autoimport',\n enforce: 'pre',\n\n transform: {\n filter: {\n // this is necessary for webpack / rspack to avoid matching .html files\n id: /\\.(m|c)?(j|t)sx?$/,\n code: /createFileRoute\\(|createLazyFileRoute\\(/,\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {\n return null\n }\n let routeType: 'createFileRoute' | 'createLazyFileRoute'\n if (code.includes('createFileRoute(')) {\n routeType = 'createFileRoute'\n } else if (code.includes('createLazyFileRoute(')) {\n routeType = 'createLazyFileRoute'\n } else {\n return null\n }\n\n const routerImportPath = `@tanstack/${userConfig.target}-router`\n\n const ast = parseAst({ code })\n\n let isCreateRouteFunctionImported = false as boolean\n\n babel.traverse(ast, {\n Program: {\n enter(programPath) {\n programPath.traverse({\n ImportDeclaration(path) {\n const importedSpecifiers = path.node.specifiers.map(\n (specifier) => specifier.local.name,\n )\n if (\n importedSpecifiers.includes(routeType) &&\n path.node.source.value === routerImportPath\n ) {\n isCreateRouteFunctionImported = true\n }\n },\n })\n },\n },\n })\n\n if (!isCreateRouteFunctionImported) {\n if (debug) console.info('Adding autoimports to route ', normalizedId)\n\n const autoImportStatement = template.statement(\n `import { ${routeType} } from '${routerImportPath}'`,\n )()\n ast.program.body.unshift(autoImportStatement)\n\n const result = generateFromAst(ast, {\n sourceMaps: true,\n filename: normalizedId,\n sourceFileName: normalizedId,\n })\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n return result\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n ROOT = config.root\n initUserConfig()\n },\n // this check may only happen after config is resolved, so we use applyToEnvironment (apply is too early)\n applyToEnvironment() {\n return userConfig.verboseFileRoutes === false\n },\n },\n\n rspack() {\n ROOT = process.cwd()\n initUserConfig()\n },\n\n webpack() {\n ROOT = process.cwd()\n initUserConfig()\n },\n }\n}\n"],"names":[],"mappings":";;;;;AAWO,MAAM,iCAET,CAAC,UAAU,OAAO;AACpB,MAAI,OAAe,QAAQ,IAAA;AAC3B,MAAI;AAEJ,WAAS,iBAAiB;AACxB,QAAI,OAAO,YAAY,YAAY;AACjC,mBAAa,QAAA;AAAA,IACf,OAAO;AACL,mBAAa,UAAU,SAAS,IAAI;AAAA,IACtC;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,WAAW;AAAA,MACT,QAAQ;AAAA;AAAA,QAEN,IAAI;AAAA,QACJ,MAAM;AAAA,MAAA;AAAA,MAER,QAAQ,MAAM,IAAI;AAChB,cAAM,eAAe,cAAc,EAAE;AACrC,YAAI,CAAC,WAAW,sBAAsB,IAAI,YAAY,GAAG;AACvD,iBAAO;AAAA,QACT;AACA,YAAI;AACJ,YAAI,KAAK,SAAS,kBAAkB,GAAG;AACrC,sBAAY;AAAA,QACd,WAAW,KAAK,SAAS,sBAAsB,GAAG;AAChD,sBAAY;AAAA,QACd,OAAO;AACL,iBAAO;AAAA,QACT;AAEA,cAAM,mBAAmB,aAAa,WAAW,MAAM;AAEvD,cAAM,MAAM,SAAS,EAAE,MAAM;AAE7B,YAAI,gCAAgC;AAEpC,cAAM,SAAS,KAAK;AAAA,UAClB,SAAS;AAAA,YACP,MAAM,aAAa;AACjB,0BAAY,SAAS;AAAA,gBACnB,kBAAkB,MAAM;AACtB,wBAAM,qBAAqB,KAAK,KAAK,WAAW;AAAA,oBAC9C,CAAC,cAAc,UAAU,MAAM;AAAA,kBAAA;AAEjC,sBACE,mBAAmB,SAAS,SAAS,KACrC,KAAK,KAAK,OAAO,UAAU,kBAC3B;AACA,oDAAgC;AAAA,kBAClC;AAAA,gBACF;AAAA,cAAA,CACD;AAAA,YACH;AAAA,UAAA;AAAA,QACF,CACD;AAED,YAAI,CAAC,+BAA+B;AAClC,cAAI,MAAO,SAAQ,KAAK,gCAAgC,YAAY;AAEpE,gBAAM,sBAAsB,SAAS;AAAA,YACnC,YAAY,SAAS,YAAY,gBAAgB;AAAA,UAAA,EACnD;AACA,cAAI,QAAQ,KAAK,QAAQ,mBAAmB;AAE5C,gBAAM,SAAS,gBAAgB,KAAK;AAAA,YAClC,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,gBAAgB;AAAA,UAAA,CACjB;AACD,cAAI,OAAO;AACT,oBAAQ,MAAM,OAAO,IAAI;AACzB,oBAAQ,IAAI,aAAa,OAAO,OAAO,MAAM;AAAA,UAC/C;AACA,iBAAO;AAAA,QACT;AAEA,eAAO;AAAA,MACT;AAAA,IAAA;AAAA,IAGF,MAAM;AAAA,MACJ,eAAe,QAAQ;AACrB,eAAO,OAAO;AACd,uBAAA;AAAA,MACF;AAAA;AAAA,MAEA,qBAAqB;AACnB,eAAO,WAAW,sBAAsB;AAAA,MAC1C;AAAA,IAAA;AAAA,IAGF,SAAS;AACP,aAAO,QAAQ,IAAA;AACf,qBAAA;AAAA,IACF;AAAA,IAEA,UAAU;AACR,aAAO,QAAQ,IAAA;AACf,qBAAA;AAAA,IACF;AAAA,EAAA;AAEJ;"}
|
|
@@ -4,7 +4,7 @@ import { getConfig, splitGroupingsSchema } from "./config.js";
|
|
|
4
4
|
import { detectCodeSplitGroupingsFromRoute, compileCodeSplitReferenceRoute, compileCodeSplitVirtualRoute } from "./code-splitter/compilers.js";
|
|
5
5
|
import { tsrSplit, splitRouteIdentNodes, defaultCodeSplitGroupings } from "./constants.js";
|
|
6
6
|
import { decodeIdentifier } from "./code-splitter/path-ids.js";
|
|
7
|
-
import { debug } from "./utils.js";
|
|
7
|
+
import { normalizePath, debug } from "./utils.js";
|
|
8
8
|
const bannedBeforeExternalPlugins = [
|
|
9
9
|
{
|
|
10
10
|
identifier: "@react-refresh",
|
|
@@ -141,7 +141,8 @@ ${message}`
|
|
|
141
141
|
}
|
|
142
142
|
},
|
|
143
143
|
handler(code, id) {
|
|
144
|
-
const
|
|
144
|
+
const normalizedId = normalizePath(id);
|
|
145
|
+
const generatorFileInfo = globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId);
|
|
145
146
|
if (generatorFileInfo && includedCode.some((included) => code.includes(included))) {
|
|
146
147
|
for (const externalPlugin of bannedBeforeExternalPlugins) {
|
|
147
148
|
if (!externalPlugin.frameworks.includes(framework)) {
|
|
@@ -151,7 +152,11 @@ ${message}`
|
|
|
151
152
|
throw new FoundPluginInBeforeCode(externalPlugin, framework);
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
|
-
return handleCompilingReferenceFile(
|
|
155
|
+
return handleCompilingReferenceFile(
|
|
156
|
+
code,
|
|
157
|
+
normalizedId,
|
|
158
|
+
generatorFileInfo
|
|
159
|
+
);
|
|
155
160
|
}
|
|
156
161
|
return null;
|
|
157
162
|
}
|
|
@@ -197,8 +202,8 @@ ${message}`
|
|
|
197
202
|
handler(code, id) {
|
|
198
203
|
const url = pathToFileURL(id);
|
|
199
204
|
url.searchParams.delete("v");
|
|
200
|
-
|
|
201
|
-
return handleCompilingVirtualFile(code,
|
|
205
|
+
const normalizedId = normalizePath(fileURLToPath(url));
|
|
206
|
+
return handleCompilingVirtualFile(code, normalizedId);
|
|
202
207
|
}
|
|
203
208
|
}
|
|
204
209
|
}
|
|
@@ -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 } 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 generatorFileInfo = globalThis.TSR_ROUTES_BY_ID_MAP?.get(id)\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(code, id, generatorFileInfo)\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 id = fileURLToPath(url).replace(/\\\\/g, '/')\n return handleCompilingVirtualFile(code, id)\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 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,6 +1,6 @@
|
|
|
1
1
|
import { parseAst, generateFromAst, logDiff } from "@tanstack/router-utils";
|
|
2
2
|
import { routeHmrStatement } from "./route-hmr-statement.js";
|
|
3
|
-
import { debug } from "./utils.js";
|
|
3
|
+
import { normalizePath, debug } from "./utils.js";
|
|
4
4
|
import { getConfig } from "./config.js";
|
|
5
5
|
const includeCode = [
|
|
6
6
|
"createFileRoute(",
|
|
@@ -22,16 +22,17 @@ const unpluginRouterHmrFactory = (options = {}) => {
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
handler(code, id) {
|
|
25
|
-
|
|
25
|
+
const normalizedId = normalizePath(id);
|
|
26
|
+
if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {
|
|
26
27
|
return null;
|
|
27
28
|
}
|
|
28
|
-
if (debug) console.info("Adding HMR handling to route ",
|
|
29
|
+
if (debug) console.info("Adding HMR handling to route ", normalizedId);
|
|
29
30
|
const ast = parseAst({ code });
|
|
30
31
|
ast.program.body.push(routeHmrStatement);
|
|
31
32
|
const result = generateFromAst(ast, {
|
|
32
33
|
sourceMaps: true,
|
|
33
|
-
filename:
|
|
34
|
-
sourceFileName:
|
|
34
|
+
filename: normalizedId,
|
|
35
|
+
sourceFileName: normalizedId
|
|
35
36
|
});
|
|
36
37
|
if (debug) {
|
|
37
38
|
logDiff(code, result.code);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-hmr-plugin.js","sources":["../../../src/core/router-hmr-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport { routeHmrStatement } from './route-hmr-statement'\nimport { debug } from './utils'\nimport { getConfig } from './config'\nimport type { UnpluginFactory } from 'unplugin'\nimport type { Config } from './config'\n\n/**\n * This plugin adds HMR support for file routes.\n * It is only added to the composed plugin in dev when autoCodeSplitting is disabled, since the code splitting plugin\n * handles HMR for code-split routes itself.\n */\n\nconst includeCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n]\nexport const unpluginRouterHmrFactory: UnpluginFactory<\n Partial<Config> | undefined\n> = (options = {}) => {\n let ROOT: string = process.cwd()\n let userConfig = options as Config\n\n return {\n name: 'tanstack-router:hmr',\n enforce: 'pre',\n transform: {\n filter: {\n // this is necessary for webpack / rspack to avoid matching .html files\n id: /\\.(m|c)?(j|t)sx?$/,\n code: {\n include: includeCode,\n },\n },\n handler(code, id) {\n if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(
|
|
1
|
+
{"version":3,"file":"router-hmr-plugin.js","sources":["../../../src/core/router-hmr-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport { routeHmrStatement } from './route-hmr-statement'\nimport { debug, normalizePath } from './utils'\nimport { getConfig } from './config'\nimport type { UnpluginFactory } from 'unplugin'\nimport type { Config } from './config'\n\n/**\n * This plugin adds HMR support for file routes.\n * It is only added to the composed plugin in dev when autoCodeSplitting is disabled, since the code splitting plugin\n * handles HMR for code-split routes itself.\n */\n\nconst includeCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n]\nexport const unpluginRouterHmrFactory: UnpluginFactory<\n Partial<Config> | undefined\n> = (options = {}) => {\n let ROOT: string = process.cwd()\n let userConfig = options as Config\n\n return {\n name: 'tanstack-router:hmr',\n enforce: 'pre',\n transform: {\n filter: {\n // this is necessary for webpack / rspack to avoid matching .html files\n id: /\\.(m|c)?(j|t)sx?$/,\n code: {\n include: includeCode,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {\n return null\n }\n\n if (debug) console.info('Adding HMR handling to route ', normalizedId)\n\n const ast = parseAst({ code })\n ast.program.body.push(routeHmrStatement)\n const result = generateFromAst(ast, {\n sourceMaps: true,\n filename: normalizedId,\n sourceFileName: normalizedId,\n })\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n return result\n },\n },\n vite: {\n configResolved(config) {\n ROOT = config.root\n userConfig = getConfig(options, ROOT)\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}\n"],"names":[],"mappings":";;;;AAaA,MAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AACF;AACO,MAAM,2BAET,CAAC,UAAU,OAAO;AACpB,MAAI,OAAe,QAAQ,IAAA;AAC3B,MAAI,aAAa;AAEjB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,MACT,QAAQ;AAAA;AAAA,QAEN,IAAI;AAAA,QACJ,MAAM;AAAA,UACJ,SAAS;AAAA,QAAA;AAAA,MACX;AAAA,MAEF,QAAQ,MAAM,IAAI;AAChB,cAAM,eAAe,cAAc,EAAE;AACrC,YAAI,CAAC,WAAW,sBAAsB,IAAI,YAAY,GAAG;AACvD,iBAAO;AAAA,QACT;AAEA,YAAI,MAAO,SAAQ,KAAK,iCAAiC,YAAY;AAErE,cAAM,MAAM,SAAS,EAAE,MAAM;AAC7B,YAAI,QAAQ,KAAK,KAAK,iBAAiB;AACvC,cAAM,SAAS,gBAAgB,KAAK;AAAA,UAClC,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,gBAAgB;AAAA,QAAA,CACjB;AACD,YAAI,OAAO;AACT,kBAAQ,MAAM,OAAO,IAAI;AACzB,kBAAQ,IAAI,aAAa,OAAO,OAAO,MAAM;AAAA,QAC/C;AACA,eAAO;AAAA,MACT;AAAA,IAAA;AAAA,IAEF,MAAM;AAAA,MACJ,eAAe,QAAQ;AACrB,eAAO,OAAO;AACd,qBAAa,UAAU,SAAS,IAAI;AAAA,MACtC;AAAA,MACA,mBAAmB,aAAa;AAC9B,YAAI,WAAW,QAAQ,MAAM,iBAAiB;AAC5C,iBAAO,WAAW,OAAO,KAAK,oBAAoB,YAAY;AAAA,QAChE;AACA,eAAO;AAAA,MACT;AAAA,IAAA;AAAA,EACF;AAEJ;"}
|
package/dist/esm/core/utils.d.ts
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
1
|
export declare const debug: boolean | "" | undefined;
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a file path by converting Windows backslashes to forward slashes.
|
|
4
|
+
* This ensures consistent path handling across different bundlers and operating systems.
|
|
5
|
+
*
|
|
6
|
+
* The route generator stores paths with forward slashes, but rspack/webpack on Windows
|
|
7
|
+
* pass native paths with backslashes to transform handlers.
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizePath(path: string): string;
|
package/dist/esm/core/utils.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const debug = process.env.TSR_VITE_DEBUG && ["true", "router-plugin"].includes(process.env.TSR_VITE_DEBUG);
|
|
2
|
+
function normalizePath(path) {
|
|
3
|
+
return path.replace(/\\/g, "/");
|
|
4
|
+
}
|
|
2
5
|
export {
|
|
3
|
-
debug
|
|
6
|
+
debug,
|
|
7
|
+
normalizePath
|
|
4
8
|
};
|
|
5
9
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../src/core/utils.ts"],"sourcesContent":["export const debug =\n process.env.TSR_VITE_DEBUG &&\n ['true', 'router-plugin'].includes(process.env.TSR_VITE_DEBUG)\n"],"names":[],"mappings":"AAAO,MAAM,QACX,QAAQ,IAAI,kBACZ,CAAC,QAAQ,eAAe,EAAE,SAAS,QAAQ,IAAI,cAAc;"}
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../src/core/utils.ts"],"sourcesContent":["export const debug =\n process.env.TSR_VITE_DEBUG &&\n ['true', 'router-plugin'].includes(process.env.TSR_VITE_DEBUG)\n\n/**\n * Normalizes a file path by converting Windows backslashes to forward slashes.\n * This ensures consistent path handling across different bundlers and operating systems.\n *\n * The route generator stores paths with forward slashes, but rspack/webpack on Windows\n * pass native paths with backslashes to transform handlers.\n */\nexport function normalizePath(path: string): string {\n return path.replace(/\\\\/g, '/')\n}\n"],"names":[],"mappings":"AAAO,MAAM,QACX,QAAQ,IAAI,kBACZ,CAAC,QAAQ,eAAe,EAAE,SAAS,QAAQ,IAAI,cAAc;AASxD,SAAS,cAAc,MAAsB;AAClD,SAAO,KAAK,QAAQ,OAAO,GAAG;AAChC;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/router-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.147.0",
|
|
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.146.2",
|
|
101
|
-
"@tanstack/router-
|
|
101
|
+
"@tanstack/router-generator": "1.146.2",
|
|
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",
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"vite": ">=5.0.0 || >=6.0.0 || >=7.0.0",
|
|
113
113
|
"vite-plugin-solid": "^2.11.10",
|
|
114
114
|
"webpack": ">=5.92.0",
|
|
115
|
-
"@tanstack/react-router": "^1.
|
|
115
|
+
"@tanstack/react-router": "^1.147.0"
|
|
116
116
|
},
|
|
117
117
|
"peerDependenciesMeta": {
|
|
118
118
|
"@rsbuild/core": {
|
|
@@ -2,7 +2,7 @@ import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'
|
|
|
2
2
|
import babel from '@babel/core'
|
|
3
3
|
import * as template from '@babel/template'
|
|
4
4
|
import { getConfig } from './config'
|
|
5
|
-
import { debug } from './utils'
|
|
5
|
+
import { debug, normalizePath } from './utils'
|
|
6
6
|
import type { Config } from './config'
|
|
7
7
|
import type { UnpluginFactory } from 'unplugin'
|
|
8
8
|
|
|
@@ -33,7 +33,8 @@ export const unpluginRouteAutoImportFactory: UnpluginFactory<
|
|
|
33
33
|
code: /createFileRoute\(|createLazyFileRoute\(/,
|
|
34
34
|
},
|
|
35
35
|
handler(code, id) {
|
|
36
|
-
|
|
36
|
+
const normalizedId = normalizePath(id)
|
|
37
|
+
if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {
|
|
37
38
|
return null
|
|
38
39
|
}
|
|
39
40
|
let routeType: 'createFileRoute' | 'createLazyFileRoute'
|
|
@@ -72,7 +73,7 @@ export const unpluginRouteAutoImportFactory: UnpluginFactory<
|
|
|
72
73
|
})
|
|
73
74
|
|
|
74
75
|
if (!isCreateRouteFunctionImported) {
|
|
75
|
-
if (debug) console.info('Adding autoimports to route ',
|
|
76
|
+
if (debug) console.info('Adding autoimports to route ', normalizedId)
|
|
76
77
|
|
|
77
78
|
const autoImportStatement = template.statement(
|
|
78
79
|
`import { ${routeType} } from '${routerImportPath}'`,
|
|
@@ -81,8 +82,8 @@ export const unpluginRouteAutoImportFactory: UnpluginFactory<
|
|
|
81
82
|
|
|
82
83
|
const result = generateFromAst(ast, {
|
|
83
84
|
sourceMaps: true,
|
|
84
|
-
filename:
|
|
85
|
-
sourceFileName:
|
|
85
|
+
filename: normalizedId,
|
|
86
|
+
sourceFileName: normalizedId,
|
|
86
87
|
})
|
|
87
88
|
if (debug) {
|
|
88
89
|
logDiff(code, result.code)
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
tsrSplit,
|
|
18
18
|
} from './constants'
|
|
19
19
|
import { decodeIdentifier } from './code-splitter/path-ids'
|
|
20
|
-
import { debug } from './utils'
|
|
20
|
+
import { debug, normalizePath } from './utils'
|
|
21
21
|
import type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'
|
|
22
22
|
import type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'
|
|
23
23
|
import type { Config } from './config'
|
|
@@ -212,7 +212,9 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
|
|
|
212
212
|
},
|
|
213
213
|
},
|
|
214
214
|
handler(code, id) {
|
|
215
|
-
const
|
|
215
|
+
const normalizedId = normalizePath(id)
|
|
216
|
+
const generatorFileInfo =
|
|
217
|
+
globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId)
|
|
216
218
|
if (
|
|
217
219
|
generatorFileInfo &&
|
|
218
220
|
includedCode.some((included) => code.includes(included))
|
|
@@ -227,7 +229,11 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
|
|
|
227
229
|
}
|
|
228
230
|
}
|
|
229
231
|
|
|
230
|
-
return handleCompilingReferenceFile(
|
|
232
|
+
return handleCompilingReferenceFile(
|
|
233
|
+
code,
|
|
234
|
+
normalizedId,
|
|
235
|
+
generatorFileInfo,
|
|
236
|
+
)
|
|
231
237
|
}
|
|
232
238
|
|
|
233
239
|
return null
|
|
@@ -280,8 +286,8 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
|
|
|
280
286
|
handler(code, id) {
|
|
281
287
|
const url = pathToFileURL(id)
|
|
282
288
|
url.searchParams.delete('v')
|
|
283
|
-
|
|
284
|
-
return handleCompilingVirtualFile(code,
|
|
289
|
+
const normalizedId = normalizePath(fileURLToPath(url))
|
|
290
|
+
return handleCompilingVirtualFile(code, normalizedId)
|
|
285
291
|
},
|
|
286
292
|
},
|
|
287
293
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'
|
|
2
2
|
import { routeHmrStatement } from './route-hmr-statement'
|
|
3
|
-
import { debug } from './utils'
|
|
3
|
+
import { debug, normalizePath } from './utils'
|
|
4
4
|
import { getConfig } from './config'
|
|
5
5
|
import type { UnpluginFactory } from 'unplugin'
|
|
6
6
|
import type { Config } from './config'
|
|
@@ -34,18 +34,19 @@ export const unpluginRouterHmrFactory: UnpluginFactory<
|
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
36
|
handler(code, id) {
|
|
37
|
-
|
|
37
|
+
const normalizedId = normalizePath(id)
|
|
38
|
+
if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {
|
|
38
39
|
return null
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
if (debug) console.info('Adding HMR handling to route ',
|
|
42
|
+
if (debug) console.info('Adding HMR handling to route ', normalizedId)
|
|
42
43
|
|
|
43
44
|
const ast = parseAst({ code })
|
|
44
45
|
ast.program.body.push(routeHmrStatement)
|
|
45
46
|
const result = generateFromAst(ast, {
|
|
46
47
|
sourceMaps: true,
|
|
47
|
-
filename:
|
|
48
|
-
sourceFileName:
|
|
48
|
+
filename: normalizedId,
|
|
49
|
+
sourceFileName: normalizedId,
|
|
49
50
|
})
|
|
50
51
|
if (debug) {
|
|
51
52
|
logDiff(code, result.code)
|
package/src/core/utils.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
export const debug =
|
|
2
2
|
process.env.TSR_VITE_DEBUG &&
|
|
3
3
|
['true', 'router-plugin'].includes(process.env.TSR_VITE_DEBUG)
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Normalizes a file path by converting Windows backslashes to forward slashes.
|
|
7
|
+
* This ensures consistent path handling across different bundlers and operating systems.
|
|
8
|
+
*
|
|
9
|
+
* The route generator stores paths with forward slashes, but rspack/webpack on Windows
|
|
10
|
+
* pass native paths with backslashes to transform handlers.
|
|
11
|
+
*/
|
|
12
|
+
export function normalizePath(path: string): string {
|
|
13
|
+
return path.replace(/\\/g, '/')
|
|
14
|
+
}
|