@tanstack/router-plugin 1.168.22 → 1.168.23
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/code-splitter/compilers.cjs +39 -32
- package/dist/cjs/core/code-splitter/compilers.cjs.map +1 -1
- package/dist/cjs/core/code-splitter/compilers.d.cts +3 -2
- package/dist/cjs/core/code-splitter/plugins/framework-plugins.cjs +10 -12
- package/dist/cjs/core/code-splitter/plugins/framework-plugins.cjs.map +1 -1
- package/dist/cjs/core/code-splitter/plugins/framework-plugins.d.cts +3 -4
- package/dist/cjs/core/code-splitter/plugins/react-refresh-route-components.cjs +34 -16
- package/dist/cjs/core/code-splitter/plugins/react-refresh-route-components.cjs.map +1 -1
- package/dist/cjs/core/code-splitter/plugins.d.cts +8 -1
- package/dist/cjs/core/config.cjs.map +1 -1
- package/dist/cjs/core/router-code-splitter-plugin.cjs +20 -11
- package/dist/cjs/core/router-code-splitter-plugin.cjs.map +1 -1
- package/dist/cjs/core/router-hmr-plugin.cjs +1 -2
- package/dist/cjs/core/router-hmr-plugin.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/esm/core/code-splitter/compilers.d.ts +3 -2
- package/dist/esm/core/code-splitter/compilers.js +39 -32
- package/dist/esm/core/code-splitter/compilers.js.map +1 -1
- package/dist/esm/core/code-splitter/plugins/framework-plugins.d.ts +3 -4
- package/dist/esm/core/code-splitter/plugins/framework-plugins.js +10 -12
- package/dist/esm/core/code-splitter/plugins/framework-plugins.js.map +1 -1
- package/dist/esm/core/code-splitter/plugins/react-refresh-route-components.js +34 -16
- package/dist/esm/core/code-splitter/plugins/react-refresh-route-components.js.map +1 -1
- package/dist/esm/core/code-splitter/plugins.d.ts +8 -1
- package/dist/esm/core/config.js.map +1 -1
- package/dist/esm/core/router-code-splitter-plugin.js +21 -12
- package/dist/esm/core/router-code-splitter-plugin.js.map +1 -1
- package/dist/esm/core/router-hmr-plugin.js +2 -3
- package/dist/esm/core/router-hmr-plugin.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/package.json +3 -3
- package/src/core/code-splitter/compilers.ts +12 -2
- package/src/core/code-splitter/plugins/framework-plugins.ts +11 -15
- package/src/core/code-splitter/plugins/react-refresh-route-components.ts +75 -25
- package/src/core/code-splitter/plugins.ts +12 -1
- package/src/core/config.ts +2 -2
- package/src/core/router-code-splitter-plugin.ts +31 -17
- package/src/core/router-hmr-plugin.ts +2 -3
- package/src/index.ts +2 -0
|
@@ -10,20 +10,38 @@ var REACT_REFRESH_ROUTE_COMPONENT_IDENTS = new Set([
|
|
|
10
10
|
"errorComponent",
|
|
11
11
|
"notFoundComponent"
|
|
12
12
|
]);
|
|
13
|
-
function
|
|
13
|
+
function isReactComponentName(name) {
|
|
14
|
+
const firstCharacter = name[0];
|
|
15
|
+
return firstCharacter !== void 0 && firstCharacter >= "A" && firstCharacter <= "Z";
|
|
16
|
+
}
|
|
17
|
+
function getRouteComponentKey(prop) {
|
|
18
|
+
const key = require_utils.getObjectPropertyKeyName(prop);
|
|
19
|
+
return key && REACT_REFRESH_ROUTE_COMPONENT_IDENTS.has(key) ? key : void 0;
|
|
20
|
+
}
|
|
21
|
+
function prepareRouteComponentsForReactRefresh(ctx) {
|
|
14
22
|
const hoistedDeclarations = [];
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (!
|
|
23
|
+
let modified = false;
|
|
24
|
+
for (const prop of ctx.routeOptions.properties) {
|
|
25
|
+
if (!_babel_types.isObjectProperty(prop)) continue;
|
|
26
|
+
const key = getRouteComponentKey(prop);
|
|
27
|
+
if (!key) continue;
|
|
28
|
+
if (_babel_types.isIdentifier(prop.value)) {
|
|
29
|
+
if (isReactComponentName(prop.value.name)) continue;
|
|
30
|
+
const bindingNode = ctx.programPath.scope.getBinding(prop.value.name)?.path.node;
|
|
31
|
+
if (!(_babel_types.isFunctionDeclaration(bindingNode) || _babel_types.isClassDeclaration(bindingNode) || _babel_types.isVariableDeclarator(bindingNode))) continue;
|
|
32
|
+
const componentIdentifier = require_utils.getUniqueProgramIdentifier(ctx.programPath, `TSR${key[0].toUpperCase()}${key.slice(1)}`);
|
|
33
|
+
ctx.programPath.scope.rename(prop.value.name, componentIdentifier.name);
|
|
34
|
+
modified = true;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (!_babel_types.isArrowFunctionExpression(prop.value) && !_babel_types.isFunctionExpression(prop.value)) continue;
|
|
20
38
|
const hoistedIdentifier = require_utils.getUniqueProgramIdentifier(ctx.programPath, `TSR${key[0].toUpperCase()}${key.slice(1)}`);
|
|
21
39
|
hoistedDeclarations.push(_babel_types.variableDeclaration("const", [_babel_types.variableDeclarator(hoistedIdentifier, _babel_types.cloneNode(prop.value, true))]));
|
|
22
40
|
prop.value = _babel_types.cloneNode(hoistedIdentifier);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
ctx.insertionPath.insertBefore(hoistedDeclarations);
|
|
26
|
-
return
|
|
41
|
+
modified = true;
|
|
42
|
+
}
|
|
43
|
+
if (hoistedDeclarations.length > 0) ctx.insertionPath.insertBefore(hoistedDeclarations);
|
|
44
|
+
return modified;
|
|
27
45
|
}
|
|
28
46
|
function createReactRefreshRouteComponentsPlugin() {
|
|
29
47
|
return {
|
|
@@ -31,13 +49,13 @@ function createReactRefreshRouteComponentsPlugin() {
|
|
|
31
49
|
getStableRouteOptionKeys() {
|
|
32
50
|
return [...REACT_REFRESH_ROUTE_COMPONENT_IDENTS];
|
|
33
51
|
},
|
|
34
|
-
onUnsplittableRoute(ctx) {
|
|
35
|
-
if (!ctx.opts.addHmr) return;
|
|
36
|
-
if (hoistInlineRouteComponents(ctx)) return { modified: true };
|
|
37
|
-
},
|
|
38
52
|
onAddHmr(ctx) {
|
|
39
|
-
if (
|
|
40
|
-
|
|
53
|
+
if (prepareRouteComponentsForReactRefresh(ctx)) return { modified: true };
|
|
54
|
+
},
|
|
55
|
+
onVirtualRouteSplitNode(ctx) {
|
|
56
|
+
if (ctx.splitNodeMeta.splitStrategy !== "lazyRouteComponent" || !_babel_types.isFunctionDeclaration(ctx.splitNode) || !ctx.splitNode.id || isReactComponentName(ctx.splitNode.id.name)) return;
|
|
57
|
+
const componentIdentifier = require_utils.getUniqueProgramIdentifier(ctx.programPath, ctx.splitNodeMeta.localExporterIdent);
|
|
58
|
+
ctx.programPath.scope.rename(ctx.splitNode.id.name, componentIdentifier.name);
|
|
41
59
|
}
|
|
42
60
|
};
|
|
43
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-refresh-route-components.cjs","names":[],"sources":["../../../../../src/core/code-splitter/plugins/react-refresh-route-components.ts"],"sourcesContent":["import * as t from '@babel/types'\nimport {\n getObjectPropertyKeyName,\n getUniqueProgramIdentifier,\n} from '../../utils'\nimport type { ReferenceRouteCompilerPlugin } from '../plugins'\n\nconst REACT_REFRESH_ROUTE_COMPONENT_IDENTS = new Set([\n 'component',\n 'shellComponent',\n 'pendingComponent',\n 'errorComponent',\n 'notFoundComponent',\n])\n\
|
|
1
|
+
{"version":3,"file":"react-refresh-route-components.cjs","names":[],"sources":["../../../../../src/core/code-splitter/plugins/react-refresh-route-components.ts"],"sourcesContent":["import * as t from '@babel/types'\nimport {\n getObjectPropertyKeyName,\n getUniqueProgramIdentifier,\n} from '../../utils'\nimport type { ReferenceRouteCompilerPlugin } from '../plugins'\n\nconst REACT_REFRESH_ROUTE_COMPONENT_IDENTS = new Set([\n 'component',\n 'shellComponent',\n 'pendingComponent',\n 'errorComponent',\n 'notFoundComponent',\n])\n\ntype RouteComponentContext = {\n programPath: Parameters<typeof getUniqueProgramIdentifier>[0]\n insertionPath: { insertBefore: (nodes: Array<t.VariableDeclaration>) => void }\n routeOptions: t.ObjectExpression\n}\n\nfunction isReactComponentName(name: string) {\n const firstCharacter = name[0]\n\n return (\n firstCharacter !== undefined &&\n firstCharacter >= 'A' &&\n firstCharacter <= 'Z'\n )\n}\n\nfunction getRouteComponentKey(prop: t.ObjectProperty) {\n const key = getObjectPropertyKeyName(prop)\n\n return key && REACT_REFRESH_ROUTE_COMPONENT_IDENTS.has(key) ? key : undefined\n}\n\nfunction prepareRouteComponentsForReactRefresh(ctx: RouteComponentContext) {\n const hoistedDeclarations: Array<t.VariableDeclaration> = []\n let modified = false\n\n for (const prop of ctx.routeOptions.properties) {\n if (!t.isObjectProperty(prop)) {\n continue\n }\n\n const key = getRouteComponentKey(prop)\n\n if (!key) {\n continue\n }\n\n if (t.isIdentifier(prop.value)) {\n if (isReactComponentName(prop.value.name)) {\n continue\n }\n\n const bindingNode = ctx.programPath.scope.getBinding(prop.value.name)\n ?.path.node\n const isLocalComponentBinding =\n t.isFunctionDeclaration(bindingNode) ||\n t.isClassDeclaration(bindingNode) ||\n t.isVariableDeclarator(bindingNode)\n\n if (!isLocalComponentBinding) {\n continue\n }\n\n const componentIdentifier = getUniqueProgramIdentifier(\n ctx.programPath,\n `TSR${key[0]!.toUpperCase()}${key.slice(1)}`,\n )\n\n ctx.programPath.scope.rename(prop.value.name, componentIdentifier.name)\n modified = true\n continue\n }\n\n if (\n !t.isArrowFunctionExpression(prop.value) &&\n !t.isFunctionExpression(prop.value)\n ) {\n continue\n }\n\n const hoistedIdentifier = getUniqueProgramIdentifier(\n ctx.programPath,\n `TSR${key[0]!.toUpperCase()}${key.slice(1)}`,\n )\n\n hoistedDeclarations.push(\n t.variableDeclaration('const', [\n t.variableDeclarator(hoistedIdentifier, t.cloneNode(prop.value, true)),\n ]),\n )\n\n prop.value = t.cloneNode(hoistedIdentifier)\n modified = true\n }\n\n if (hoistedDeclarations.length > 0) {\n ctx.insertionPath.insertBefore(hoistedDeclarations)\n }\n\n return modified\n}\n\nexport function createReactRefreshRouteComponentsPlugin(): ReferenceRouteCompilerPlugin {\n return {\n name: 'react-refresh-route-components',\n getStableRouteOptionKeys() {\n return [...REACT_REFRESH_ROUTE_COMPONENT_IDENTS]\n },\n onAddHmr(ctx) {\n if (prepareRouteComponentsForReactRefresh(ctx)) {\n return { modified: true }\n }\n\n return\n },\n onVirtualRouteSplitNode(ctx) {\n if (\n ctx.splitNodeMeta.splitStrategy !== 'lazyRouteComponent' ||\n !t.isFunctionDeclaration(ctx.splitNode) ||\n !ctx.splitNode.id ||\n isReactComponentName(ctx.splitNode.id.name)\n ) {\n return\n }\n\n const componentIdentifier = getUniqueProgramIdentifier(\n ctx.programPath,\n ctx.splitNodeMeta.localExporterIdent,\n )\n\n ctx.programPath.scope.rename(\n ctx.splitNode.id.name,\n componentIdentifier.name,\n )\n },\n }\n}\n"],"mappings":";;;;;AAOA,IAAM,uCAAuC,IAAI,IAAI;CACnD;CACA;CACA;CACA;CACA;AACF,CAAC;AAQD,SAAS,qBAAqB,MAAc;CAC1C,MAAM,iBAAiB,KAAK;CAE5B,OACE,mBAAmB,KAAA,KACnB,kBAAkB,OAClB,kBAAkB;AAEtB;AAEA,SAAS,qBAAqB,MAAwB;CACpD,MAAM,MAAM,cAAA,yBAAyB,IAAI;CAEzC,OAAO,OAAO,qCAAqC,IAAI,GAAG,IAAI,MAAM,KAAA;AACtE;AAEA,SAAS,sCAAsC,KAA4B;CACzE,MAAM,sBAAoD,CAAC;CAC3D,IAAI,WAAW;CAEf,KAAK,MAAM,QAAQ,IAAI,aAAa,YAAY;EAC9C,IAAI,CAAC,aAAE,iBAAiB,IAAI,GAC1B;EAGF,MAAM,MAAM,qBAAqB,IAAI;EAErC,IAAI,CAAC,KACH;EAGF,IAAI,aAAE,aAAa,KAAK,KAAK,GAAG;GAC9B,IAAI,qBAAqB,KAAK,MAAM,IAAI,GACtC;GAGF,MAAM,cAAc,IAAI,YAAY,MAAM,WAAW,KAAK,MAAM,IAAI,GAChE,KAAK;GAMT,IAAI,EAJF,aAAE,sBAAsB,WAAW,KACnC,aAAE,mBAAmB,WAAW,KAChC,aAAE,qBAAqB,WAAW,IAGlC;GAGF,MAAM,sBAAsB,cAAA,2BAC1B,IAAI,aACJ,MAAM,IAAI,GAAI,YAAY,IAAI,IAAI,MAAM,CAAC,GAC3C;GAEA,IAAI,YAAY,MAAM,OAAO,KAAK,MAAM,MAAM,oBAAoB,IAAI;GACtE,WAAW;GACX;EACF;EAEA,IACE,CAAC,aAAE,0BAA0B,KAAK,KAAK,KACvC,CAAC,aAAE,qBAAqB,KAAK,KAAK,GAElC;EAGF,MAAM,oBAAoB,cAAA,2BACxB,IAAI,aACJ,MAAM,IAAI,GAAI,YAAY,IAAI,IAAI,MAAM,CAAC,GAC3C;EAEA,oBAAoB,KAClB,aAAE,oBAAoB,SAAS,CAC7B,aAAE,mBAAmB,mBAAmB,aAAE,UAAU,KAAK,OAAO,IAAI,CAAC,CACvE,CAAC,CACH;EAEA,KAAK,QAAQ,aAAE,UAAU,iBAAiB;EAC1C,WAAW;CACb;CAEA,IAAI,oBAAoB,SAAS,GAC/B,IAAI,cAAc,aAAa,mBAAmB;CAGpD,OAAO;AACT;AAEA,SAAgB,0CAAwE;CACtF,OAAO;EACL,MAAM;EACN,2BAA2B;GACzB,OAAO,CAAC,GAAG,oCAAoC;EACjD;EACA,SAAS,KAAK;GACZ,IAAI,sCAAsC,GAAG,GAC3C,OAAO,EAAE,UAAU,KAAK;EAI5B;EACA,wBAAwB,KAAK;GAC3B,IACE,IAAI,cAAc,kBAAkB,wBACpC,CAAC,aAAE,sBAAsB,IAAI,SAAS,KACtC,CAAC,IAAI,UAAU,MACf,qBAAqB,IAAI,UAAU,GAAG,IAAI,GAE1C;GAGF,MAAM,sBAAsB,cAAA,2BAC1B,IAAI,aACJ,IAAI,cAAc,kBACpB;GAEA,IAAI,YAAY,MAAM,OACpB,IAAI,UAAU,GAAG,MACjB,oBAAoB,IACtB;EACF;CACF;AACF"}
|
|
@@ -35,11 +35,18 @@ export type ReferenceRouteSplitPropertyCompilerPluginContext = {
|
|
|
35
35
|
export type ReferenceRouteCompilerPluginResult = {
|
|
36
36
|
modified?: boolean;
|
|
37
37
|
};
|
|
38
|
-
export type
|
|
38
|
+
export type VirtualRouteSplitNodeCompilerPluginContext = {
|
|
39
|
+
programPath: babel.NodePath<t.Program>;
|
|
40
|
+
splitNode: t.Node;
|
|
41
|
+
splitNodeMeta: SplitNodeMeta;
|
|
42
|
+
};
|
|
43
|
+
export type CodeSplitCompilerPlugin = {
|
|
39
44
|
name: string;
|
|
40
45
|
getStableRouteOptionKeys?: () => Array<string>;
|
|
41
46
|
onRouteOptions?: (ctx: ReferenceRouteCompilerPluginContext) => void | ReferenceRouteCompilerPluginResult;
|
|
42
47
|
onAddHmr?: (ctx: ReferenceRouteCompilerPluginContext) => void | ReferenceRouteCompilerPluginResult;
|
|
43
48
|
onUnsplittableRoute?: (ctx: ReferenceRouteCompilerPluginContext) => void | ReferenceRouteCompilerPluginResult;
|
|
44
49
|
onSplitRouteProperty?: (ctx: ReferenceRouteSplitPropertyCompilerPluginContext) => void | t.Expression;
|
|
50
|
+
onVirtualRouteSplitNode?: (ctx: VirtualRouteSplitNodeCompilerPluginContext) => void;
|
|
45
51
|
};
|
|
52
|
+
export type ReferenceRouteCompilerPlugin = CodeSplitCompilerPlugin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.cjs","names":[],"sources":["../../../src/core/config.ts"],"sourcesContent":["import { z } from 'zod'\nimport {\n configSchema as generatorConfigSchema,\n getConfig as getGeneratorConfig,\n} from '@tanstack/router-generator'\nimport type {\n CreateFileRoute,\n RegisteredRouter,\n RouteIds,\n} from '@tanstack/router-core'\nimport type { CodeSplitGroupings } from './constants'\nimport type {
|
|
1
|
+
{"version":3,"file":"config.cjs","names":[],"sources":["../../../src/core/config.ts"],"sourcesContent":["import { z } from 'zod'\nimport {\n configSchema as generatorConfigSchema,\n getConfig as getGeneratorConfig,\n} from '@tanstack/router-generator'\nimport type {\n CreateFileRoute,\n RegisteredRouter,\n RouteIds,\n} from '@tanstack/router-core'\nimport type { CodeSplitGroupings } from './constants'\nimport type { CodeSplitCompilerPlugin } from './code-splitter/plugins'\n\nexport const splitGroupingsSchema = z\n .array(\n z.array(\n z.union([\n z.literal('loader'),\n z.literal('component'),\n z.literal('pendingComponent'),\n z.literal('errorComponent'),\n z.literal('notFoundComponent'),\n ]),\n ),\n {\n message:\n \" Must be an Array of Arrays containing the split groupings. i.e. [['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']]\",\n },\n )\n .superRefine((val, ctx) => {\n const flattened = val.flat()\n const unique = [...new Set(flattened)]\n\n // Elements must be unique,\n // ie. this shouldn't be allows [['component'], ['component', 'loader']]\n if (unique.length !== flattened.length) {\n ctx.addIssue({\n code: 'custom',\n message:\n \" Split groupings must be unique and not repeated. i.e. i.e. [['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']].\" +\n `\\n You input was: ${JSON.stringify(val)}.`,\n })\n }\n })\n\nexport type CodeSplittingOptions = {\n /**\n * Use this function to programmatically control the code splitting behavior\n * based on the `routeId` for each route.\n *\n * If you just need to change the default behavior, you can use the `defaultBehavior` option.\n * @param params\n */\n splitBehavior?: (params: {\n routeId: RouteIds<RegisteredRouter['routeTree']>\n }) => CodeSplitGroupings | undefined | void\n\n /**\n * The default/global configuration to control your code splitting behavior per route.\n * @default [['component'],['pendingComponent'],['errorComponent'],['notFoundComponent']]\n */\n defaultBehavior?: CodeSplitGroupings\n\n /**\n * The nodes that shall be deleted from the route.\n * @default undefined\n */\n deleteNodes?: Array<DeletableNodes>\n\n /**\n * @default true\n */\n addHmr?: boolean\n\n /**\n * Internal compiler plugins used by framework integrations.\n * @internal\n */\n compilerPlugins?: Array<CodeSplitCompilerPlugin>\n}\n\nexport type HmrStyle = 'vite' | 'webpack'\n\nexport type HmrOptions = {\n /**\n * Selects the HMR runtime style to emit code for.\n * - `'vite'` (default): ESM `import.meta.hot` with Vite accept-callback semantics.\n * - `'webpack'`: `import.meta.webpackHot` with webpack / Rspack `module.hot` re-execution semantics.\n *\n * Bundler-specific plugin entries (e.g. `rspack.ts`, `webpack.ts`) set this explicitly.\n */\n style?: HmrStyle\n}\n\nconst codeSplittingOptionsSchema = z.object({\n splitBehavior: z\n .custom<\n CodeSplittingOptions['splitBehavior']\n >((value) => typeof value === 'function')\n .optional(),\n defaultBehavior: splitGroupingsSchema.optional(),\n deleteNodes: z.array(z.string()).optional(),\n addHmr: z.boolean().optional().default(true),\n})\n\ntype FileRouteKeys = keyof (Parameters<\n CreateFileRoute<any, any, any, any, any>\n>[0] & {})\nexport type DeletableNodes = FileRouteKeys | (string & {})\n\nexport const configSchema = generatorConfigSchema.extend({\n enableRouteGeneration: z.boolean().optional(),\n codeSplittingOptions: z\n .custom<CodeSplittingOptions>((v) => {\n return codeSplittingOptionsSchema.parse(v)\n })\n .optional(),\n plugin: z\n .object({\n hmr: z\n .object({\n style: z.enum(['vite', 'webpack']).optional(),\n })\n .optional(),\n vite: z\n .object({\n environmentName: z.string().optional(),\n })\n .optional(),\n })\n .optional(),\n})\n\nexport const getConfig = (inlineConfig: Partial<Config>, root: string) => {\n const config = getGeneratorConfig(inlineConfig, root)\n\n return configSchema.parse({ ...inlineConfig, ...config })\n}\n\nexport type Config = z.infer<typeof configSchema>\nexport type ConfigInput = z.input<typeof configSchema>\nexport type ConfigOutput = z.output<typeof configSchema>\n"],"mappings":";;;AAaA,IAAa,uBAAuB,IAAA,EACjC,MACC,IAAA,EAAE,MACA,IAAA,EAAE,MAAM;CACN,IAAA,EAAE,QAAQ,QAAQ;CAClB,IAAA,EAAE,QAAQ,WAAW;CACrB,IAAA,EAAE,QAAQ,kBAAkB;CAC5B,IAAA,EAAE,QAAQ,gBAAgB;CAC1B,IAAA,EAAE,QAAQ,mBAAmB;AAC/B,CAAC,CACH,GACA,EACE,SACE,mJACJ,CACF,EACC,aAAa,KAAK,QAAQ;CACzB,MAAM,YAAY,IAAI,KAAK;CAK3B,IAAI,CAJY,GAAG,IAAI,IAAI,SAAS,CAIhC,EAAO,WAAW,UAAU,QAC9B,IAAI,SAAS;EACX,MAAM;EACN,SACE,kKACsB,KAAK,UAAU,GAAG,EAAE;CAC9C,CAAC;AAEL,CAAC;AAmDH,IAAM,6BAA6B,IAAA,EAAE,OAAO;CAC1C,eAAe,IAAA,EACZ,QAEE,UAAU,OAAO,UAAU,UAAU,EACvC,SAAS;CACZ,iBAAiB,qBAAqB,SAAS;CAC/C,aAAa,IAAA,EAAE,MAAM,IAAA,EAAE,OAAO,CAAC,EAAE,SAAS;CAC1C,QAAQ,IAAA,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI;AAC7C,CAAC;AAOD,IAAa,eAAe,2BAAA,aAAsB,OAAO;CACvD,uBAAuB,IAAA,EAAE,QAAQ,EAAE,SAAS;CAC5C,sBAAsB,IAAA,EACnB,QAA8B,MAAM;EACnC,OAAO,2BAA2B,MAAM,CAAC;CAC3C,CAAC,EACA,SAAS;CACZ,QAAQ,IAAA,EACL,OAAO;EACN,KAAK,IAAA,EACF,OAAO,EACN,OAAO,IAAA,EAAE,KAAK,CAAC,QAAQ,SAAS,CAAC,EAAE,SAAS,EAC9C,CAAC,EACA,SAAS;EACZ,MAAM,IAAA,EACH,OAAO,EACN,iBAAiB,IAAA,EAAE,OAAO,EAAE,SAAS,EACvC,CAAC,EACA,SAAS;CACd,CAAC,EACA,SAAS;AACd,CAAC;AAED,IAAa,aAAa,cAA+B,SAAiB;CACxE,MAAM,UAAA,GAAA,2BAAA,WAA4B,cAAc,IAAI;CAEpD,OAAO,aAAa,MAAM;EAAE,GAAG;EAAc,GAAG;CAAO,CAAC;AAC1D"}
|
|
@@ -43,11 +43,22 @@ var TRANSFORMATION_PLUGINS_BY_FRAMEWORK = {
|
|
|
43
43
|
function createRouterCodeSplitterPlugin(options = {}, routerPluginContext) {
|
|
44
44
|
let ROOT = process.cwd();
|
|
45
45
|
let userConfig;
|
|
46
|
+
let addHmr;
|
|
47
|
+
let hmrStyle;
|
|
48
|
+
let compilerPlugins;
|
|
49
|
+
let virtualRouteCompilerPlugins;
|
|
50
|
+
let isProduction = process.env.NODE_ENV === "production";
|
|
46
51
|
function initUserConfig() {
|
|
47
52
|
if (typeof options === "function") userConfig = options();
|
|
48
53
|
else userConfig = require_config.getConfig(options, ROOT);
|
|
54
|
+
addHmr = (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction;
|
|
55
|
+
hmrStyle = userConfig.plugin?.hmr?.style ?? "vite";
|
|
56
|
+
compilerPlugins = [...addHmr ? require_framework_plugins.getFrameworkHmrCompilerPlugins({
|
|
57
|
+
targetFramework: userConfig.target,
|
|
58
|
+
hmrStyle
|
|
59
|
+
}) ?? [] : [], ...userConfig.codeSplittingOptions?.compilerPlugins ?? []];
|
|
60
|
+
virtualRouteCompilerPlugins = compilerPlugins.filter((plugin) => plugin.onVirtualRouteSplitNode);
|
|
49
61
|
}
|
|
50
|
-
const isProduction = process.env.NODE_ENV === "production";
|
|
51
62
|
const sharedBindingsMap = /* @__PURE__ */ new Map();
|
|
52
63
|
const getGlobalCodeSplitGroupings = () => {
|
|
53
64
|
return userConfig.codeSplittingOptions?.defaultBehavior || require_constants.defaultCodeSplitGroupings;
|
|
@@ -84,8 +95,6 @@ function createRouterCodeSplitterPlugin(options = {}, routerPluginContext) {
|
|
|
84
95
|
});
|
|
85
96
|
if (sharedBindings.size > 0) sharedBindingsMap.set(id, sharedBindings);
|
|
86
97
|
else sharedBindingsMap.delete(id);
|
|
87
|
-
const addHmr = (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction;
|
|
88
|
-
const hmrStyle = userConfig.plugin?.hmr?.style ?? "vite";
|
|
89
98
|
const compiledReferenceRoute = require_compilers.compileCodeSplitReferenceRoute({
|
|
90
99
|
code,
|
|
91
100
|
codeSplitGroupings: splitGroupings,
|
|
@@ -97,11 +106,7 @@ function createRouterCodeSplitterPlugin(options = {}, routerPluginContext) {
|
|
|
97
106
|
hmrStyle,
|
|
98
107
|
hmrRouteId: generatorNodeInfo.routeId,
|
|
99
108
|
sharedBindings: sharedBindings.size > 0 ? sharedBindings : void 0,
|
|
100
|
-
compilerPlugins
|
|
101
|
-
targetFramework: userConfig.target,
|
|
102
|
-
addHmr,
|
|
103
|
-
hmrStyle
|
|
104
|
-
}) ?? [], ...userConfig.codeSplittingOptions?.compilerPlugins ?? []]
|
|
109
|
+
compilerPlugins
|
|
105
110
|
});
|
|
106
111
|
if (compiledReferenceRoute === null) {
|
|
107
112
|
if (require_utils.debug) console.info(`No changes made to route "${id}", skipping code-splitting.`);
|
|
@@ -125,7 +130,8 @@ function createRouterCodeSplitterPlugin(options = {}, routerPluginContext) {
|
|
|
125
130
|
code,
|
|
126
131
|
filename: id,
|
|
127
132
|
splitTargets: grouping,
|
|
128
|
-
sharedBindings: sharedBindingsMap.get(baseId)
|
|
133
|
+
sharedBindings: sharedBindingsMap.get(baseId),
|
|
134
|
+
compilerPlugins: virtualRouteCompilerPlugins
|
|
129
135
|
});
|
|
130
136
|
if (require_utils.debug) {
|
|
131
137
|
(0, _tanstack_router_utils.logDiff)(code, result.code);
|
|
@@ -154,6 +160,7 @@ function createRouterCodeSplitterPlugin(options = {}, routerPluginContext) {
|
|
|
154
160
|
},
|
|
155
161
|
vite: {
|
|
156
162
|
configResolved(config) {
|
|
163
|
+
isProduction = config.command === "build";
|
|
157
164
|
ROOT = config.root;
|
|
158
165
|
initUserConfig();
|
|
159
166
|
const routerPluginIndex = config.plugins.findIndex((p) => p.name === CODE_SPLITTER_PLUGIN_NAME);
|
|
@@ -170,11 +177,13 @@ function createRouterCodeSplitterPlugin(options = {}, routerPluginContext) {
|
|
|
170
177
|
return true;
|
|
171
178
|
}
|
|
172
179
|
},
|
|
173
|
-
rspack() {
|
|
180
|
+
rspack(compiler) {
|
|
181
|
+
isProduction = compiler.options.mode === "production";
|
|
174
182
|
ROOT = process.cwd();
|
|
175
183
|
initUserConfig();
|
|
176
184
|
},
|
|
177
|
-
webpack() {
|
|
185
|
+
webpack(compiler) {
|
|
186
|
+
isProduction = compiler.options.mode === "production";
|
|
178
187
|
ROOT = process.cwd();
|
|
179
188
|
initUserConfig();
|
|
180
189
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-code-splitter-plugin.cjs","names":[],"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 { decodeIdentifier, logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport {\n compileCodeSplitReferenceRoute,\n compileCodeSplitSharedRoute,\n compileCodeSplitVirtualRoute,\n computeSharedBindings,\n detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport { getReferenceRouteCompilerPlugins } from './code-splitter/plugins/framework-plugins'\nimport {\n defaultCodeSplitGroupings,\n splitRouteIdentNodes,\n tsrShared,\n tsrSplit,\n} from './constants'\nimport { debug, normalizePath, routeFactoryCallCodeFilter } from './utils'\nimport { createRouterPluginContext } from './router-plugin-context'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type { RouterPluginContext } from './router-plugin-context'\nimport type {\n UnpluginFactory,\n TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\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 function createRouterCodeSplitterPlugin(\n options: Partial<Config | (() => Config)> | undefined = {},\n routerPluginContext: RouterPluginContext,\n): ReturnType<UnpluginFactory<Partial<Config | (() => Config)> | undefined>> {\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 // Map from normalized route file path → set of shared binding names.\n // Populated by the reference compiler, consumed by virtual and shared compilers.\n const sharedBindingsMap = new Map<string, Set<string>>()\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 filename: id,\n })\n\n if (fromCode.groupings !== undefined) {\n const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n if (!res.success) {\n const message = res.error.issues.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.routeId,\n }) as CodeSplitGroupings | undefined\n\n if (pluginSplitBehavior) {\n const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n if (!res.success) {\n const message = res.error.issues.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 // Compute shared bindings before compiling the reference route\n const sharedBindings = computeSharedBindings({\n code,\n filename: id,\n codeSplitGroupings: splitGroupings,\n })\n if (sharedBindings.size > 0) {\n sharedBindingsMap.set(id, sharedBindings)\n } else {\n sharedBindingsMap.delete(id)\n }\n\n const addHmr =\n (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction\n const hmrStyle = userConfig.plugin?.hmr?.style ?? 'vite'\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 hmrStyle,\n hmrRouteId: generatorNodeInfo.routeId,\n sharedBindings: sharedBindings.size > 0 ? sharedBindings : undefined,\n compilerPlugins: [\n ...(getReferenceRouteCompilerPlugins({\n targetFramework: userConfig.target,\n addHmr,\n hmrStyle,\n }) ?? []),\n ...(userConfig.codeSplittingOptions?.compilerPlugins ?? []),\n ],\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 baseId = id.split('?')[0]!\n const resolvedSharedBindings = sharedBindingsMap.get(baseId)\n\n const result = compileCodeSplitVirtualRoute({\n code,\n filename: id,\n splitTargets: grouping,\n sharedBindings: resolvedSharedBindings,\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 return [\n {\n name: 'tanstack-router:code-splitter:compile-reference-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: {\n exclude: [tsrSplit, tsrShared],\n // this is necessary for webpack / rspack to avoid matching .html files\n include: /\\.(m|c)?(j|t)sx?$/,\n },\n code: {\n include: routeFactoryCallCodeFilter,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const generatorFileInfo =\n routerPluginContext.routesByFile.get(normalizedId)\n if (generatorFileInfo) {\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() {\n ROOT = process.cwd()\n initUserConfig()\n },\n\n webpack() {\n ROOT = process.cwd()\n initUserConfig()\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 vite: {\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 name: 'tanstack-router:code-splitter:compile-shared-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-shared/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n const [baseId] = normalizedId.split('?')\n\n if (!baseId) return null\n\n const sharedBindings = sharedBindingsMap.get(baseId)\n if (!sharedBindings || sharedBindings.size === 0) return null\n\n if (debug) console.info('Compiling Shared Module: ', id)\n\n const result = compileCodeSplitSharedRoute({\n code,\n sharedBindings,\n filename: normalizedId,\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\n vite: {\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}\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}) => {\n return createRouterCodeSplitterPlugin(options, createRouterPluginContext())\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"router-code-splitter-plugin.cjs","names":[],"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 { decodeIdentifier, logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport {\n compileCodeSplitReferenceRoute,\n compileCodeSplitSharedRoute,\n compileCodeSplitVirtualRoute,\n computeSharedBindings,\n detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport { getFrameworkHmrCompilerPlugins } from './code-splitter/plugins/framework-plugins'\nimport {\n defaultCodeSplitGroupings,\n splitRouteIdentNodes,\n tsrShared,\n tsrSplit,\n} from './constants'\nimport { debug, normalizePath, routeFactoryCallCodeFilter } from './utils'\nimport { createRouterPluginContext } from './router-plugin-context'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { CodeSplitCompilerPlugin } from './code-splitter/plugins'\nimport type { Config, HmrStyle } from './config'\nimport type { RouterPluginContext } from './router-plugin-context'\nimport type {\n UnpluginFactory,\n TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\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 function createRouterCodeSplitterPlugin(\n options: Partial<Config | (() => Config)> | undefined = {},\n routerPluginContext: RouterPluginContext,\n): ReturnType<UnpluginFactory<Partial<Config | (() => Config)> | undefined>> {\n let ROOT: string = process.cwd()\n let userConfig: Config\n let addHmr: boolean\n let hmrStyle: HmrStyle\n let compilerPlugins: Array<CodeSplitCompilerPlugin>\n let virtualRouteCompilerPlugins: Array<CodeSplitCompilerPlugin>\n\n let isProduction = process.env.NODE_ENV === 'production'\n\n function initUserConfig() {\n if (typeof options === 'function') {\n userConfig = options()\n } else {\n userConfig = getConfig(options, ROOT)\n }\n\n addHmr = (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction\n hmrStyle = userConfig.plugin?.hmr?.style ?? 'vite'\n compilerPlugins = [\n ...(addHmr\n ? (getFrameworkHmrCompilerPlugins({\n targetFramework: userConfig.target,\n hmrStyle,\n }) ?? [])\n : []),\n ...(userConfig.codeSplittingOptions?.compilerPlugins ?? []),\n ]\n virtualRouteCompilerPlugins = compilerPlugins.filter(\n (plugin) => plugin.onVirtualRouteSplitNode,\n )\n }\n // Map from normalized route file path → set of shared binding names.\n // Populated by the reference compiler, consumed by virtual and shared compilers.\n const sharedBindingsMap = new Map<string, Set<string>>()\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 filename: id,\n })\n\n if (fromCode.groupings !== undefined) {\n const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n if (!res.success) {\n const message = res.error.issues.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.routeId,\n }) as CodeSplitGroupings | undefined\n\n if (pluginSplitBehavior) {\n const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n if (!res.success) {\n const message = res.error.issues.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 // Compute shared bindings before compiling the reference route\n const sharedBindings = computeSharedBindings({\n code,\n filename: id,\n codeSplitGroupings: splitGroupings,\n })\n if (sharedBindings.size > 0) {\n sharedBindingsMap.set(id, sharedBindings)\n } else {\n sharedBindingsMap.delete(id)\n }\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 hmrStyle,\n hmrRouteId: generatorNodeInfo.routeId,\n sharedBindings: sharedBindings.size > 0 ? sharedBindings : undefined,\n compilerPlugins,\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 baseId = id.split('?')[0]!\n const resolvedSharedBindings = sharedBindingsMap.get(baseId)\n\n const result = compileCodeSplitVirtualRoute({\n code,\n filename: id,\n splitTargets: grouping,\n sharedBindings: resolvedSharedBindings,\n compilerPlugins: virtualRouteCompilerPlugins,\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 return [\n {\n name: 'tanstack-router:code-splitter:compile-reference-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: {\n exclude: [tsrSplit, tsrShared],\n // this is necessary for webpack / rspack to avoid matching .html files\n include: /\\.(m|c)?(j|t)sx?$/,\n },\n code: {\n include: routeFactoryCallCodeFilter,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const generatorFileInfo =\n routerPluginContext.routesByFile.get(normalizedId)\n if (generatorFileInfo) {\n return handleCompilingReferenceFile(\n code,\n normalizedId,\n generatorFileInfo,\n )\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n isProduction = config.command === 'build'\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 isProduction = compiler.options.mode === 'production'\n ROOT = process.cwd()\n initUserConfig()\n },\n\n webpack(compiler) {\n isProduction = compiler.options.mode === 'production'\n ROOT = process.cwd()\n initUserConfig()\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 vite: {\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 name: 'tanstack-router:code-splitter:compile-shared-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-shared/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n const [baseId] = normalizedId.split('?')\n\n if (!baseId) return null\n\n const sharedBindings = sharedBindingsMap.get(baseId)\n if (!sharedBindings || sharedBindings.size === 0) return null\n\n if (debug) console.info('Compiling Shared Module: ', id)\n\n const result = compileCodeSplitSharedRoute({\n code,\n sharedBindings,\n filename: normalizedId,\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\n vite: {\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}\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}) => {\n return createRouterCodeSplitterPlugin(options, createRouterPluginContext())\n}\n"],"mappings":"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"}
|
|
@@ -31,9 +31,8 @@ function createRouterHmrPlugin(options = {}, routerPluginContext) {
|
|
|
31
31
|
if (require_utils.debug) console.info("Adding HMR handling to route ", normalizedId);
|
|
32
32
|
const hmrStyle = userConfig.plugin?.hmr?.style ?? "vite";
|
|
33
33
|
if (userConfig.target === "react") {
|
|
34
|
-
const compilerPlugins = require_framework_plugins.
|
|
34
|
+
const compilerPlugins = require_framework_plugins.getFrameworkHmrCompilerPlugins({
|
|
35
35
|
targetFramework: "react",
|
|
36
|
-
addHmr: true,
|
|
37
36
|
hmrStyle
|
|
38
37
|
});
|
|
39
38
|
const compiled = require_compilers.compileCodeSplitReferenceRoute({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-hmr-plugin.cjs","names":[],"sources":["../../../src/core/router-hmr-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport { compileCodeSplitReferenceRoute } from './code-splitter/compilers'\nimport {
|
|
1
|
+
{"version":3,"file":"router-hmr-plugin.cjs","names":[],"sources":["../../../src/core/router-hmr-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport { compileCodeSplitReferenceRoute } from './code-splitter/compilers'\nimport { getFrameworkHmrCompilerPlugins } from './code-splitter/plugins/framework-plugins'\nimport { createRouteHmrStatement } from './hmr'\nimport { debug, normalizePath, routeFactoryCallCodeFilter } from './utils'\nimport { getConfig } from './config'\nimport { createRouterPluginContext } from './router-plugin-context'\nimport type { UnpluginFactory } from 'unplugin'\nimport type { Config } from './config'\nimport type { RouterPluginContext } from './router-plugin-context'\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\nexport function createRouterHmrPlugin(\n options: Partial<Config | (() => Config)> | undefined = {},\n routerPluginContext: RouterPluginContext,\n): ReturnType<UnpluginFactory<Partial<Config> | undefined>> {\n let ROOT: string = process.cwd()\n\n const resolveUserConfig = () => {\n return getConfig(typeof options === 'function' ? options() : options, ROOT)\n }\n\n let userConfig = resolveUserConfig()\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: routeFactoryCallCodeFilter,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const routeEntry = routerPluginContext.routesByFile.get(normalizedId)\n if (!routeEntry) {\n return null\n }\n\n if (debug) console.info('Adding HMR handling to route ', normalizedId)\n\n const hmrStyle = userConfig.plugin?.hmr?.style ?? 'vite'\n\n if (userConfig.target === 'react') {\n const compilerPlugins = getFrameworkHmrCompilerPlugins({\n targetFramework: 'react',\n hmrStyle,\n })\n const compiled = compileCodeSplitReferenceRoute({\n code,\n filename: normalizedId,\n id: normalizedId,\n addHmr: true,\n hmrStyle,\n hmrRouteId: routeEntry.routeId,\n codeSplitGroupings: [],\n targetFramework: 'react',\n compilerPlugins,\n })\n\n if (compiled) {\n if (debug) {\n logDiff(code, compiled.code)\n console.log('Output:\\n', compiled.code + '\\n\\n')\n }\n\n return compiled\n }\n }\n\n const ast = parseAst({ code, filename: normalizedId })\n ast.program.body.push(\n ...createRouteHmrStatement([], {\n hmrStyle,\n targetFramework: userConfig.target,\n routeId: routeEntry.routeId,\n }),\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 vite: {\n configResolved(config) {\n ROOT = config.root\n userConfig = resolveUserConfig()\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\nexport const unpluginRouterHmrFactory: UnpluginFactory<\n Partial<Config> | undefined\n> = (options = {}) => {\n return createRouterHmrPlugin(options, createRouterPluginContext())\n}\n"],"mappings":";;;;;;;;;;;;AAiBA,SAAgB,sBACd,UAAwD,CAAC,GACzD,qBAC0D;CAC1D,IAAI,OAAe,QAAQ,IAAI;CAE/B,MAAM,0BAA0B;EAC9B,OAAO,eAAA,UAAU,OAAO,YAAY,aAAa,QAAQ,IAAI,SAAS,IAAI;CAC5E;CAEA,IAAI,aAAa,kBAAkB;CAEnC,OAAO;EACL,MAAM;EACN,SAAS;EACT,WAAW;GACT,QAAQ;IAEN,IAAI;IACJ,MAAM,EACJ,SAAS,cAAA,2BACX;GACF;GACA,QAAQ,MAAM,IAAI;IAChB,MAAM,eAAe,cAAA,cAAc,EAAE;IACrC,MAAM,aAAa,oBAAoB,aAAa,IAAI,YAAY;IACpE,IAAI,CAAC,YACH,OAAO;IAGT,IAAI,cAAA,OAAO,QAAQ,KAAK,iCAAiC,YAAY;IAErE,MAAM,WAAW,WAAW,QAAQ,KAAK,SAAS;IAElD,IAAI,WAAW,WAAW,SAAS;KACjC,MAAM,kBAAkB,0BAAA,+BAA+B;MACrD,iBAAiB;MACjB;KACF,CAAC;KACD,MAAM,WAAW,kBAAA,+BAA+B;MAC9C;MACA,UAAU;MACV,IAAI;MACJ,QAAQ;MACR;MACA,YAAY,WAAW;MACvB,oBAAoB,CAAC;MACrB,iBAAiB;MACjB;KACF,CAAC;KAED,IAAI,UAAU;MACZ,IAAI,cAAA,OAAO;OACT,CAAA,GAAA,uBAAA,SAAQ,MAAM,SAAS,IAAI;OAC3B,QAAQ,IAAI,aAAa,SAAS,OAAO,MAAM;MACjD;MAEA,OAAO;KACT;IACF;IAEA,MAAM,OAAA,GAAA,uBAAA,UAAe;KAAE;KAAM,UAAU;IAAa,CAAC;IACrD,IAAI,QAAQ,KAAK,KACf,GAAG,uBAAA,wBAAwB,CAAC,GAAG;KAC7B;KACA,iBAAiB,WAAW;KAC5B,SAAS,WAAW;IACtB,CAAC,CACH;IACA,MAAM,UAAA,GAAA,uBAAA,iBAAyB,KAAK;KAClC,YAAY;KACZ,UAAU;KACV,gBAAgB;IAClB,CAAC;IACD,IAAI,cAAA,OAAO;KACT,CAAA,GAAA,uBAAA,SAAQ,MAAM,OAAO,IAAI;KACzB,QAAQ,IAAI,aAAa,OAAO,OAAO,MAAM;IAC/C;IACA,OAAO;GACT;EACF;EACA,MAAM;GACJ,eAAe,QAAQ;IACrB,OAAO,OAAO;IACd,aAAa,kBAAkB;GACjC;GACA,mBAAmB,aAAa;IAC9B,IAAI,WAAW,QAAQ,MAAM,iBAC3B,OAAO,WAAW,OAAO,KAAK,oBAAoB,YAAY;IAEhE,OAAO;GACT;EACF;CACF;AACF"}
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -5,5 +5,5 @@ export { createRouterPluginContext } from './core/router-plugin-context.cjs';
|
|
|
5
5
|
export type { Config, ConfigInput, ConfigOutput, CodeSplittingOptions, DeletableNodes, HmrOptions, } from './core/config.cjs';
|
|
6
6
|
export type { RouterPluginContext } from './core/router-plugin-context.cjs';
|
|
7
7
|
export { getObjectPropertyKeyName } from './core/utils.cjs';
|
|
8
|
-
export type { ReferenceRouteCompilerPlugin, ReferenceRouteCompilerPluginContext, } from './core/code-splitter/plugins.cjs';
|
|
8
|
+
export type { CodeSplitCompilerPlugin, ReferenceRouteCompilerPlugin, ReferenceRouteCompilerPluginContext, VirtualRouteSplitNodeCompilerPluginContext, } from './core/code-splitter/plugins.cjs';
|
|
9
9
|
export { tsrSplit, splitRouteIdentNodes, defaultCodeSplitGroupings, } from './core/constants.cjs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CodeSplitCompilerPlugin, CompileCodeSplitReferenceRouteOptions } from './plugins.js';
|
|
2
2
|
import { GeneratorResult, ParseAstOptions } from '@tanstack/router-utils';
|
|
3
3
|
import { CodeSplitGroupings, SplitRouteIdentNodes } from '../constants.js';
|
|
4
4
|
export { buildDeclarationMap, buildDependencyGraph, collectIdentifiersFromNode, collectLocalBindingsFromStatement, collectModuleLevelRefsFromNode, expandDestructuredDeclarations, expandSharedDestructuredDeclarators, expandTransitively, removeBindingsTransitivelyDependingOn, } from '@tanstack/router-utils';
|
|
@@ -19,12 +19,13 @@ export declare function computeSharedBindings(opts: {
|
|
|
19
19
|
codeSplitGroupings: CodeSplitGroupings;
|
|
20
20
|
}): Set<string>;
|
|
21
21
|
export declare function compileCodeSplitReferenceRoute(opts: ParseAstOptions & CompileCodeSplitReferenceRouteOptions & {
|
|
22
|
-
compilerPlugins?: Array<
|
|
22
|
+
compilerPlugins?: Array<CodeSplitCompilerPlugin>;
|
|
23
23
|
}): GeneratorResult | null;
|
|
24
24
|
export declare function compileCodeSplitVirtualRoute(opts: ParseAstOptions & {
|
|
25
25
|
splitTargets: Array<SplitRouteIdentNodes>;
|
|
26
26
|
filename: string;
|
|
27
27
|
sharedBindings?: Set<string>;
|
|
28
|
+
compilerPlugins?: Array<CodeSplitCompilerPlugin>;
|
|
28
29
|
}): GeneratorResult;
|
|
29
30
|
/**
|
|
30
31
|
* Compile the shared virtual module (`?tsr-shared=1`).
|
|
@@ -453,38 +453,45 @@ function compileCodeSplitVirtualRoute(opts) {
|
|
|
453
453
|
let originalIdentName;
|
|
454
454
|
if (t.isIdentifier(splitNode)) originalIdentName = splitNode.name;
|
|
455
455
|
while (t.isIdentifier(splitNode)) splitNode = programPath.scope.getBinding(splitNode.name)?.path.node;
|
|
456
|
-
if (splitNode)
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
if (
|
|
467
|
-
splitMeta.
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
if (t.
|
|
476
|
-
const
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
456
|
+
if (splitNode) {
|
|
457
|
+
for (const plugin of opts.compilerPlugins ?? []) plugin.onVirtualRouteSplitNode?.({
|
|
458
|
+
programPath,
|
|
459
|
+
splitNode,
|
|
460
|
+
splitNodeMeta: splitMeta
|
|
461
|
+
});
|
|
462
|
+
if (t.isFunctionDeclaration(splitNode)) {
|
|
463
|
+
if (!splitNode.id) throw new Error(`Function declaration for "${SPLIT_TYPE}" must have an identifier.`);
|
|
464
|
+
splitMeta.shouldRemoveNode = false;
|
|
465
|
+
splitMeta.localExporterIdent = splitNode.id.name;
|
|
466
|
+
} else if (t.isFunctionExpression(splitNode) || t.isArrowFunctionExpression(splitNode)) programPath.pushContainer("body", t.variableDeclaration("const", [t.variableDeclarator(t.identifier(splitMeta.localExporterIdent), splitNode)]));
|
|
467
|
+
else if (t.isImportSpecifier(splitNode) || t.isImportDefaultSpecifier(splitNode)) programPath.pushContainer("body", t.variableDeclaration("const", [t.variableDeclarator(t.identifier(splitMeta.localExporterIdent), splitNode.local)]));
|
|
468
|
+
else if (t.isVariableDeclarator(splitNode)) if (t.isIdentifier(splitNode.id)) {
|
|
469
|
+
splitMeta.localExporterIdent = splitNode.id.name;
|
|
470
|
+
splitMeta.shouldRemoveNode = false;
|
|
471
|
+
} else if (t.isObjectPattern(splitNode.id)) {
|
|
472
|
+
if (originalIdentName) splitMeta.localExporterIdent = originalIdentName;
|
|
473
|
+
splitMeta.shouldRemoveNode = false;
|
|
474
|
+
} else throw new Error(`Unexpected splitNode type ☝️: ${splitNode.type}`);
|
|
475
|
+
else if (t.isCallExpression(splitNode)) {
|
|
476
|
+
const outputSplitNodeCode = generateFromAst(splitNode).code;
|
|
477
|
+
const splitNodeAst = babel.parse(outputSplitNodeCode);
|
|
478
|
+
if (!splitNodeAst) throw new Error(`Failed to parse the generated code for "${SPLIT_TYPE}" in the node type "${splitNode.type}"`);
|
|
479
|
+
const statement = splitNodeAst.program.body[0];
|
|
480
|
+
if (!statement) throw new Error(`Failed to parse the generated code for "${SPLIT_TYPE}" in the node type "${splitNode.type}" as no statement was found in the program body`);
|
|
481
|
+
if (t.isExpressionStatement(statement)) {
|
|
482
|
+
const expression = statement.expression;
|
|
483
|
+
programPath.pushContainer("body", t.variableDeclaration("const", [t.variableDeclarator(t.identifier(splitMeta.localExporterIdent), expression)]));
|
|
484
|
+
} else throw new Error(`Unexpected expression type encounter for "${SPLIT_TYPE}" in the node type "${splitNode.type}"`);
|
|
485
|
+
} else if (t.isConditionalExpression(splitNode)) programPath.pushContainer("body", t.variableDeclaration("const", [t.variableDeclarator(t.identifier(splitMeta.localExporterIdent), splitNode)]));
|
|
486
|
+
else if (t.isTSAsExpression(splitNode)) {
|
|
487
|
+
splitNode = splitNode.expression;
|
|
488
|
+
programPath.pushContainer("body", t.variableDeclaration("const", [t.variableDeclarator(t.identifier(splitMeta.localExporterIdent), splitNode)]));
|
|
489
|
+
} else if (t.isBooleanLiteral(splitNode)) return;
|
|
490
|
+
else if (t.isNullLiteral(splitNode)) return;
|
|
491
|
+
else {
|
|
492
|
+
console.info("Unexpected splitNode type:", splitNode);
|
|
493
|
+
throw new Error(`Unexpected splitNode type ☝️: ${splitNode.type}`);
|
|
494
|
+
}
|
|
488
495
|
}
|
|
489
496
|
if (splitMeta.shouldRemoveNode) programPath.node.body = programPath.node.body.filter((node) => {
|
|
490
497
|
return node !== splitNode;
|