@tanstack/router-vite-plugin 1.23.0 → 1.25.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.
Files changed (47) hide show
  1. package/dist/cjs/compilers.cjs +335 -0
  2. package/dist/cjs/compilers.cjs.map +1 -0
  3. package/dist/cjs/compilers.d.cts +38 -0
  4. package/dist/cjs/constants.cjs +5 -0
  5. package/dist/cjs/constants.cjs.map +1 -0
  6. package/dist/cjs/constants.d.cts +1 -0
  7. package/dist/cjs/eliminateUnreferencedIdentifiers.cjs +144 -0
  8. package/dist/cjs/eliminateUnreferencedIdentifiers.cjs.map +1 -0
  9. package/dist/cjs/eliminateUnreferencedIdentifiers.d.cts +8 -0
  10. package/dist/cjs/index.cjs +141 -13
  11. package/dist/cjs/index.cjs.map +1 -1
  12. package/dist/cjs/index.d.cts +55 -2
  13. package/dist/cjs/tests/index.test.d.cts +1 -0
  14. package/dist/cjs/tests/shared/imported.d.cts +5 -0
  15. package/dist/esm/compilers.d.ts +38 -0
  16. package/dist/esm/compilers.js +316 -0
  17. package/dist/esm/compilers.js.map +1 -0
  18. package/dist/esm/constants.d.ts +1 -0
  19. package/dist/esm/constants.js +5 -0
  20. package/dist/esm/constants.js.map +1 -0
  21. package/dist/esm/eliminateUnreferencedIdentifiers.d.ts +8 -0
  22. package/dist/esm/eliminateUnreferencedIdentifiers.js +127 -0
  23. package/dist/esm/eliminateUnreferencedIdentifiers.js.map +1 -0
  24. package/dist/esm/index.d.ts +55 -2
  25. package/dist/esm/index.js +142 -14
  26. package/dist/esm/index.js.map +1 -1
  27. package/dist/esm/tests/index.test.d.ts +1 -0
  28. package/dist/esm/tests/shared/imported.d.ts +5 -0
  29. package/package.json +18 -1
  30. package/src/compilers.ts +420 -0
  31. package/src/constants.ts +1 -0
  32. package/src/eliminateUnreferencedIdentifiers.ts +287 -0
  33. package/src/index.ts +181 -16
  34. package/src/tests/index.test.ts +60 -0
  35. package/src/tests/shared/imported.tsx +11 -0
  36. package/src/tests/snapshots/function-declaration.tsx +10 -0
  37. package/src/tests/snapshots/function-declaration?split.tsx +29 -0
  38. package/src/tests/snapshots/imported.tsx +10 -0
  39. package/src/tests/snapshots/imported?split.tsx +5 -0
  40. package/src/tests/snapshots/inline.tsx +8 -0
  41. package/src/tests/snapshots/inline?split.tsx +18 -0
  42. package/src/tests/snapshots/random-number.tsx +11 -0
  43. package/src/tests/snapshots/random-number?split.tsx +27 -0
  44. package/src/tests/test-files/function-declaration.tsx +39 -0
  45. package/src/tests/test-files/imported.tsx +8 -0
  46. package/src/tests/test-files/inline.tsx +25 -0
  47. package/src/tests/test-files/random-number.tsx +83 -0
@@ -1,10 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const path = require("path");
4
+ const url = require("url");
5
+ const zod = require("zod");
4
6
  const routerGenerator = require("@tanstack/router-generator");
7
+ const compilers = require("./compilers.cjs");
8
+ const constants = require("./constants.cjs");
9
+ const configSchema = routerGenerator.configSchema.extend({
10
+ enableRouteGeneration: zod.z.boolean().optional(),
11
+ experimental: zod.z.object({
12
+ enableCodeSplitting: zod.z.boolean().optional()
13
+ }).optional()
14
+ });
5
15
  const CONFIG_FILE_NAME = "tsr.config.json";
16
+ const getConfig = async (inlineConfig, root) => {
17
+ const config = await routerGenerator.getConfig(inlineConfig, root);
18
+ return configSchema.parse({ ...inlineConfig, ...config });
19
+ };
6
20
  function TanStackRouterVite(inlineConfig = {}) {
7
- const ROOT = process.cwd();
21
+ return [
22
+ TanStackRouterViteGenerator(inlineConfig),
23
+ TanStackRouterViteCodeSplitter(inlineConfig)
24
+ ];
25
+ }
26
+ function TanStackRouterViteGenerator(inlineConfig = {}) {
27
+ let ROOT = process.cwd();
8
28
  let userConfig;
9
29
  const generate = async () => {
10
30
  try {
@@ -14,24 +34,132 @@ function TanStackRouterVite(inlineConfig = {}) {
14
34
  console.info();
15
35
  }
16
36
  };
17
- return {
18
- name: "vite-plugin-tanstack-router",
19
- configResolved: async () => {
20
- userConfig = await routerGenerator.getConfig(inlineConfig, ROOT);
37
+ const handleFile = async (file) => {
38
+ const filePath = path.normalize(file);
39
+ if (filePath === path.join(ROOT, CONFIG_FILE_NAME)) {
40
+ userConfig = await getConfig(inlineConfig, ROOT);
41
+ return;
42
+ }
43
+ const routesDirectoryPath = path.isAbsolute(userConfig.routesDirectory) ? userConfig.routesDirectory : path.join(ROOT, userConfig.routesDirectory);
44
+ if (filePath.startsWith(routesDirectoryPath)) {
21
45
  await generate();
46
+ }
47
+ };
48
+ return {
49
+ name: "vite-plugin-tanstack-router-generator",
50
+ configResolved: async (config) => {
51
+ ROOT = config.root;
52
+ userConfig = await getConfig(inlineConfig, ROOT);
53
+ if (userConfig.enableRouteGeneration ?? true) {
54
+ await generate();
55
+ }
22
56
  },
23
- handleHotUpdate: async ({ file }) => {
24
- const filePath = path.normalize(file);
25
- if (filePath === path.join(ROOT, CONFIG_FILE_NAME)) {
26
- userConfig = await routerGenerator.getConfig(inlineConfig, ROOT);
27
- return;
57
+ watchChange: async (file, context) => {
58
+ if (userConfig.enableRouteGeneration ?? true) {
59
+ if (["create", "update", "delete"].includes(context.event)) {
60
+ await handleFile(file);
61
+ }
28
62
  }
29
- const routesDirectoryPath = path.isAbsolute(userConfig.routesDirectory) ? userConfig.routesDirectory : path.join(ROOT, userConfig.routesDirectory);
30
- if (filePath.startsWith(routesDirectoryPath)) {
31
- await generate();
63
+ }
64
+ };
65
+ }
66
+ function fileIsInRoutesDirectory(filePath, routesDirectory) {
67
+ const routesDirectoryPath = path.isAbsolute(routesDirectory) ? routesDirectory : path.join(process.cwd(), routesDirectory);
68
+ return filePath.startsWith(routesDirectoryPath);
69
+ }
70
+ function TanStackRouterViteCodeSplitter(inlineConfig = {}) {
71
+ let ROOT = process.cwd();
72
+ let userConfig;
73
+ return {
74
+ name: "vite-plugin-tanstack-router-code-splitter",
75
+ enforce: "pre",
76
+ configResolved: async (config) => {
77
+ ROOT = config.root;
78
+ userConfig = await getConfig(inlineConfig, ROOT);
79
+ },
80
+ resolveId(source) {
81
+ var _a;
82
+ if (!((_a = userConfig.experimental) == null ? void 0 : _a.enableCodeSplitting)) {
83
+ return null;
84
+ }
85
+ if (source.startsWith(constants.splitPrefix + ":")) {
86
+ return source.replace(constants.splitPrefix + ":", "");
87
+ }
88
+ return null;
89
+ },
90
+ async transform(code, id, transformOptions) {
91
+ var _a;
92
+ if (!((_a = userConfig.experimental) == null ? void 0 : _a.enableCodeSplitting)) {
93
+ return null;
94
+ }
95
+ const url$1 = url.pathToFileURL(id);
96
+ url$1.searchParams.delete("v");
97
+ id = url.fileURLToPath(url$1).replace(/\\/g, "/");
98
+ const compile = compilers.makeCompile({
99
+ root: ROOT
100
+ });
101
+ if (id.includes(constants.splitPrefix)) {
102
+ console.info("Splitting route: ", id);
103
+ const compiled = await compilers.splitFile({
104
+ code,
105
+ compile,
106
+ filename: id
107
+ // ref,
108
+ });
109
+ console.info("");
110
+ console.info("Split Output");
111
+ console.info("");
112
+ console.info(compiled.code);
113
+ console.info("");
114
+ console.info("");
115
+ console.info("");
116
+ console.info("");
117
+ console.info("");
118
+ console.info("");
119
+ console.info("");
120
+ console.info("");
121
+ return compiled;
122
+ } else if (fileIsInRoutesDirectory(id, userConfig.routesDirectory) && (code.includes("createRoute(") || code.includes("createFileRoute("))) {
123
+ if (code.includes("@react-refresh")) {
124
+ throw new Error(
125
+ `We detected that the '@vitejs/plugin-react' was passed before '@tanstack/router-vite-plugin'. Please make sure that '@tanstack/router-vite-plugin' is passed before '@vitejs/plugin-react' and try again:
126
+ e.g.
127
+
128
+ plugins: [
129
+ TanStackRouterVite(), // Place this before viteReact()
130
+ viteReact(),
131
+ ]
132
+ `
133
+ );
134
+ }
135
+ console.info("Handling createRoute: ", id);
136
+ const compiled = await compilers.compileFile({
137
+ code,
138
+ compile,
139
+ filename: id
140
+ });
141
+ console.info("");
142
+ console.info("Compiled Output");
143
+ console.info("");
144
+ console.info(compiled.code);
145
+ console.info("");
146
+ console.info("");
147
+ console.info("");
148
+ console.info("");
149
+ console.info("");
150
+ console.info("");
151
+ console.info("");
152
+ console.info("");
153
+ console.info("");
154
+ console.info("");
155
+ return compiled;
32
156
  }
157
+ return null;
33
158
  }
34
159
  };
35
160
  }
36
161
  exports.TanStackRouterVite = TanStackRouterVite;
162
+ exports.TanStackRouterViteCodeSplitter = TanStackRouterViteCodeSplitter;
163
+ exports.TanStackRouterViteGenerator = TanStackRouterViteGenerator;
164
+ exports.configSchema = configSchema;
37
165
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import { isAbsolute, join, normalize } from 'path'\nimport { type Config, generator, getConfig } from '@tanstack/router-generator'\nimport type { Plugin } from 'vite'\n\nconst CONFIG_FILE_NAME = 'tsr.config.json'\n\nexport function TanStackRouterVite(inlineConfig: Partial<Config> = {}): Plugin {\n const ROOT: string = process.cwd()\n let userConfig: Config\n\n const generate = async () => {\n try {\n await generator(userConfig)\n } catch (err) {\n console.error(err)\n console.info()\n }\n }\n\n return {\n name: 'vite-plugin-tanstack-router',\n configResolved: async () => {\n userConfig = await getConfig(inlineConfig, ROOT)\n await generate()\n },\n handleHotUpdate: async ({ file }) => {\n const filePath = normalize(file)\n if (filePath === join(ROOT, CONFIG_FILE_NAME)) {\n userConfig = await getConfig(inlineConfig, ROOT)\n return\n }\n const routesDirectoryPath = isAbsolute(userConfig.routesDirectory)\n ? userConfig.routesDirectory\n : join(ROOT, userConfig.routesDirectory)\n if (filePath.startsWith(routesDirectoryPath)) {\n await generate()\n }\n },\n }\n}\n"],"names":["generator","getConfig","normalize","join","isAbsolute"],"mappings":";;;;AAIA,MAAM,mBAAmB;AAET,SAAA,mBAAmB,eAAgC,IAAY;AACvE,QAAA,OAAe,QAAQ;AACzB,MAAA;AAEJ,QAAM,WAAW,YAAY;AACvB,QAAA;AACF,YAAMA,gBAAAA,UAAU,UAAU;AAAA,aACnB,KAAK;AACZ,cAAQ,MAAM,GAAG;AACjB,cAAQ,KAAK;AAAA,IACf;AAAA,EAAA;AAGK,SAAA;AAAA,IACL,MAAM;AAAA,IACN,gBAAgB,YAAY;AACb,mBAAA,MAAMC,gBAAAA,UAAU,cAAc,IAAI;AAC/C,YAAM,SAAS;AAAA,IACjB;AAAA,IACA,iBAAiB,OAAO,EAAE,WAAW;AAC7B,YAAA,WAAWC,eAAU,IAAI;AAC/B,UAAI,aAAaC,KAAAA,KAAK,MAAM,gBAAgB,GAAG;AAChC,qBAAA,MAAMF,gBAAAA,UAAU,cAAc,IAAI;AAC/C;AAAA,MACF;AACM,YAAA,sBAAsBG,KAAAA,WAAW,WAAW,eAAe,IAC7D,WAAW,kBACXD,UAAK,MAAM,WAAW,eAAe;AACrC,UAAA,SAAS,WAAW,mBAAmB,GAAG;AAC5C,cAAM,SAAS;AAAA,MACjB;AAAA,IACF;AAAA,EAAA;AAEJ;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import { isAbsolute, join, normalize } from 'path'\nimport { fileURLToPath, pathToFileURL } from 'url'\nimport { z } from 'zod'\nimport {\n generator,\n configSchema as generatorConfigSchema,\n getConfig as getGeneratorConfig,\n} from '@tanstack/router-generator'\nimport { compileFile, makeCompile, splitFile } from './compilers'\nimport { splitPrefix } from './constants'\nimport type { Plugin } from 'vite'\n\nexport const configSchema = generatorConfigSchema.extend({\n enableRouteGeneration: z.boolean().optional(),\n experimental: z\n .object({\n enableCodeSplitting: z.boolean().optional(),\n })\n .optional(),\n})\n\nexport type Config = z.infer<typeof configSchema>\n\nconst CONFIG_FILE_NAME = 'tsr.config.json'\nconst debug = true as any\n\nconst getConfig = async (inlineConfig: Partial<Config>, root: string) => {\n const config = await getGeneratorConfig(inlineConfig, root)\n\n return configSchema.parse({ ...inlineConfig, ...config })\n}\n\nexport function TanStackRouterVite(\n inlineConfig: Partial<Config> = {},\n): Array<Plugin> {\n return [\n TanStackRouterViteGenerator(inlineConfig),\n TanStackRouterViteCodeSplitter(inlineConfig),\n ]\n}\n\nexport function TanStackRouterViteGenerator(\n inlineConfig: Partial<Config> = {},\n): Plugin {\n let ROOT: string = process.cwd()\n let userConfig: Config\n\n const generate = async () => {\n try {\n await generator(userConfig)\n } catch (err) {\n console.error(err)\n console.info()\n }\n }\n\n const handleFile = async (file: string) => {\n const filePath = normalize(file)\n if (filePath === join(ROOT, CONFIG_FILE_NAME)) {\n userConfig = await getConfig(inlineConfig, ROOT)\n return\n }\n const routesDirectoryPath = isAbsolute(userConfig.routesDirectory)\n ? userConfig.routesDirectory\n : join(ROOT, userConfig.routesDirectory)\n if (filePath.startsWith(routesDirectoryPath)) {\n await generate()\n }\n }\n\n return {\n name: 'vite-plugin-tanstack-router-generator',\n configResolved: async (config) => {\n ROOT = config.root\n userConfig = await getConfig(inlineConfig, ROOT)\n\n if (userConfig.enableRouteGeneration ?? true) {\n await generate()\n }\n },\n watchChange: async (file, context) => {\n if (userConfig.enableRouteGeneration ?? true) {\n if (['create', 'update', 'delete'].includes(context.event)) {\n await handleFile(file)\n }\n }\n },\n }\n}\n\nfunction fileIsInRoutesDirectory(filePath: string, routesDirectory: string) {\n const routesDirectoryPath = isAbsolute(routesDirectory)\n ? routesDirectory\n : join(process.cwd(), routesDirectory)\n\n return filePath.startsWith(routesDirectoryPath)\n}\n\nexport function TanStackRouterViteCodeSplitter(\n inlineConfig: Partial<Config> = {},\n): Plugin {\n let ROOT: string = process.cwd()\n let userConfig: Config\n\n return {\n name: 'vite-plugin-tanstack-router-code-splitter',\n enforce: 'pre',\n configResolved: async (config) => {\n ROOT = config.root\n userConfig = await getConfig(inlineConfig, ROOT)\n },\n resolveId(source) {\n if (!userConfig.experimental?.enableCodeSplitting) {\n return null\n }\n\n if (source.startsWith(splitPrefix + ':')) {\n return source.replace(splitPrefix + ':', '')\n }\n return null\n },\n async transform(code, id, transformOptions) {\n if (!userConfig.experimental?.enableCodeSplitting) {\n return null\n }\n\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n id = fileURLToPath(url).replace(/\\\\/g, '/')\n\n const compile = makeCompile({\n root: ROOT,\n })\n\n if (id.includes(splitPrefix)) {\n if (debug) console.info('Splitting route: ', id)\n // const ref = new URLSearchParams(id.split('?')[1]).get('ref') || ''\n\n const compiled = await splitFile({\n code,\n compile,\n filename: id,\n // ref,\n })\n\n if (debug) console.info('')\n if (debug) console.info('Split Output')\n if (debug) console.info('')\n if (debug) console.info(compiled.code)\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n\n return compiled\n } else if (\n fileIsInRoutesDirectory(id, userConfig.routesDirectory) &&\n (code.includes('createRoute(') || code.includes('createFileRoute('))\n ) {\n if (code.includes('@react-refresh')) {\n throw new Error(\n `We detected that the '@vitejs/plugin-react' was passed before '@tanstack/router-vite-plugin'. Please make sure that '@tanstack/router-vite-plugin' is passed before '@vitejs/plugin-react' and try again: \ne.g.\n\nplugins: [\n TanStackRouterVite(), // Place this before viteReact()\n viteReact(),\n]\n`,\n )\n }\n\n if (debug) console.info('Handling createRoute: ', id)\n const compiled = await compileFile({\n code,\n compile,\n filename: id,\n })\n\n if (debug) console.info('')\n if (debug) console.info('Compiled Output')\n if (debug) console.info('')\n if (debug) console.info(compiled.code)\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n if (debug) console.info('')\n\n return compiled\n }\n\n return null\n },\n }\n}\n"],"names":["generatorConfigSchema","z","getGeneratorConfig","generator","normalize","join","isAbsolute","splitPrefix","url","pathToFileURL","fileURLToPath","makeCompile","splitFile","compileFile"],"mappings":"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"}
@@ -1,3 +1,56 @@
1
- import { type Config } from '@tanstack/router-generator';
1
+ import { z } from 'zod';
2
2
  import type { Plugin } from 'vite';
3
- export declare function TanStackRouterVite(inlineConfig?: Partial<Config>): Plugin;
3
+ export declare const configSchema: z.ZodObject<{
4
+ routeFilePrefix: z.ZodOptional<z.ZodString>;
5
+ routeFileIgnorePrefix: z.ZodDefault<z.ZodOptional<z.ZodString>>;
6
+ routeFileIgnorePattern: z.ZodOptional<z.ZodString>;
7
+ routesDirectory: z.ZodDefault<z.ZodOptional<z.ZodString>>;
8
+ generatedRouteTree: z.ZodDefault<z.ZodOptional<z.ZodString>>;
9
+ quoteStyle: z.ZodDefault<z.ZodOptional<z.ZodEnum<["single", "double"]>>>;
10
+ semicolons: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
11
+ disableTypes: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
12
+ addExtensions: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
13
+ disableLogging: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
14
+ enableRouteGeneration: z.ZodOptional<z.ZodBoolean>;
15
+ experimental: z.ZodOptional<z.ZodObject<{
16
+ enableCodeSplitting: z.ZodOptional<z.ZodBoolean>;
17
+ }, "strip", z.ZodTypeAny, {
18
+ enableCodeSplitting?: boolean | undefined;
19
+ }, {
20
+ enableCodeSplitting?: boolean | undefined;
21
+ }>>;
22
+ }, "strip", z.ZodTypeAny, {
23
+ routeFileIgnorePrefix: string;
24
+ routesDirectory: string;
25
+ generatedRouteTree: string;
26
+ quoteStyle: "single" | "double";
27
+ semicolons: boolean;
28
+ disableTypes: boolean;
29
+ addExtensions: boolean;
30
+ disableLogging: boolean;
31
+ routeFilePrefix?: string | undefined;
32
+ routeFileIgnorePattern?: string | undefined;
33
+ enableRouteGeneration?: boolean | undefined;
34
+ experimental?: {
35
+ enableCodeSplitting?: boolean | undefined;
36
+ } | undefined;
37
+ }, {
38
+ routeFilePrefix?: string | undefined;
39
+ routeFileIgnorePrefix?: string | undefined;
40
+ routeFileIgnorePattern?: string | undefined;
41
+ routesDirectory?: string | undefined;
42
+ generatedRouteTree?: string | undefined;
43
+ quoteStyle?: "single" | "double" | undefined;
44
+ semicolons?: boolean | undefined;
45
+ disableTypes?: boolean | undefined;
46
+ addExtensions?: boolean | undefined;
47
+ disableLogging?: boolean | undefined;
48
+ enableRouteGeneration?: boolean | undefined;
49
+ experimental?: {
50
+ enableCodeSplitting?: boolean | undefined;
51
+ } | undefined;
52
+ }>;
53
+ export type Config = z.infer<typeof configSchema>;
54
+ export declare function TanStackRouterVite(inlineConfig?: Partial<Config>): Array<Plugin>;
55
+ export declare function TanStackRouterViteGenerator(inlineConfig?: Partial<Config>): Plugin;
56
+ export declare function TanStackRouterViteCodeSplitter(inlineConfig?: Partial<Config>): Plugin;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ export declare const importedComponent: () => React.JSX.Element;
3
+ export declare const importedLoader: () => {
4
+ randomNumber: number;
5
+ };
@@ -0,0 +1,38 @@
1
+ export type CompileFn = (compileOpts: {
2
+ code: string;
3
+ filename: string;
4
+ getBabelConfig: () => {
5
+ plugins: Array<any>;
6
+ };
7
+ }) => Promise<{
8
+ code: string;
9
+ map: any;
10
+ }>;
11
+ export declare function makeCompile(makeOpts: {
12
+ root: string;
13
+ }): (opts: {
14
+ code: string;
15
+ filename: string;
16
+ getBabelConfig: () => {
17
+ plugins: Array<any>;
18
+ };
19
+ }) => Promise<{
20
+ code: string;
21
+ map: any;
22
+ }>;
23
+ export declare function compileFile(opts: {
24
+ code: string;
25
+ compile: CompileFn;
26
+ filename: string;
27
+ }): Promise<{
28
+ code: string;
29
+ map: any;
30
+ }>;
31
+ export declare function splitFile(opts: {
32
+ code: string;
33
+ compile: CompileFn;
34
+ filename: string;
35
+ }): Promise<{
36
+ code: string;
37
+ map: any;
38
+ }>;
@@ -0,0 +1,316 @@
1
+ import * as t from "@babel/types";
2
+ import * as template from "@babel/template";
3
+ import * as babel from "@babel/core";
4
+ import { splitPrefix } from "./constants.js";
5
+ import { eliminateUnreferencedIdentifiers } from "./eliminateUnreferencedIdentifiers.js";
6
+ function makeCompile(makeOpts) {
7
+ return async (opts) => {
8
+ const res = await babel.transform(opts.code, {
9
+ plugins: [
10
+ ["@babel/plugin-syntax-jsx", {}],
11
+ [
12
+ "@babel/plugin-syntax-typescript",
13
+ {
14
+ isTSX: true
15
+ }
16
+ ],
17
+ ...opts.getBabelConfig().plugins
18
+ ],
19
+ root: makeOpts.root,
20
+ filename: opts.filename,
21
+ sourceMaps: true
22
+ });
23
+ if (res == null ? void 0 : res.code) {
24
+ return {
25
+ code: res.code,
26
+ map: res.map
27
+ };
28
+ }
29
+ return {
30
+ code: opts.code,
31
+ map: null
32
+ };
33
+ };
34
+ }
35
+ async function compileFile(opts) {
36
+ return await opts.compile({
37
+ code: opts.code,
38
+ filename: opts.filename,
39
+ getBabelConfig: () => ({
40
+ plugins: [
41
+ [
42
+ {
43
+ visitor: {
44
+ Program: {
45
+ enter(programPath, state) {
46
+ const splitUrl = `${splitPrefix}:${state.filename}?${splitPrefix}`;
47
+ programPath.traverse(
48
+ {
49
+ CallExpression: (path) => {
50
+ if (path.node.callee.type === "Identifier") {
51
+ if (path.node.callee.name === "createRoute" || path.node.callee.name === "createFileRoute") {
52
+ if (path.parentPath.node.type === "CallExpression") {
53
+ const options = resolveIdentifier(
54
+ path,
55
+ path.parentPath.node.arguments[0]
56
+ );
57
+ let found = false;
58
+ if (t.isObjectExpression(options)) {
59
+ options.properties.forEach((prop) => {
60
+ if (t.isObjectProperty(prop)) {
61
+ if (t.isIdentifier(prop.key)) {
62
+ if (prop.key.name === "component") {
63
+ const value = prop.value;
64
+ if (t.isIdentifier(value)) {
65
+ removeIdentifierLiteral(path, value);
66
+ }
67
+ programPath.unshiftContainer("body", [
68
+ template.smart(
69
+ `import { lazyRouteComponent } from '@tanstack/react-router'`
70
+ )(),
71
+ template.smart(
72
+ `const $$splitComponentImporter = () => import('${splitUrl}')`
73
+ )()
74
+ ]);
75
+ prop.value = template.expression(
76
+ `lazyRouteComponent($$splitComponentImporter, 'component')`
77
+ )();
78
+ programPath.pushContainer("body", [
79
+ template.smart(
80
+ `function DummyComponent() { return null }`
81
+ )()
82
+ ]);
83
+ found = true;
84
+ } else if (prop.key.name === "loader") {
85
+ const value = prop.value;
86
+ if (t.isIdentifier(value)) {
87
+ removeIdentifierLiteral(path, value);
88
+ }
89
+ programPath.unshiftContainer("body", [
90
+ template.smart(
91
+ `import { lazyFn } from '@tanstack/react-router'`
92
+ )(),
93
+ template.smart(
94
+ `const $$splitLoaderImporter = () => import('${splitUrl}')`
95
+ )()
96
+ ]);
97
+ prop.value = template.expression(
98
+ `lazyFn($$splitLoaderImporter, 'loader')`
99
+ )();
100
+ found = true;
101
+ }
102
+ }
103
+ }
104
+ });
105
+ }
106
+ if (found) {
107
+ programPath.pushContainer("body", [
108
+ template.smart(
109
+ `function TSR_Dummy_Component() {}`
110
+ )()
111
+ ]);
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
117
+ },
118
+ state
119
+ );
120
+ eliminateUnreferencedIdentifiers(programPath);
121
+ }
122
+ }
123
+ }
124
+ },
125
+ {
126
+ root: process.cwd(),
127
+ minify: process.env.NODE_ENV === "production"
128
+ }
129
+ ]
130
+ ].filter(Boolean)
131
+ })
132
+ });
133
+ }
134
+ function resolveIdentifier(path, node) {
135
+ if (t.isIdentifier(node)) {
136
+ const binding = path.scope.getBinding(node.name);
137
+ if (binding) {
138
+ const declarator = binding.path.node;
139
+ if (t.isObjectExpression(declarator.init)) {
140
+ return declarator.init;
141
+ } else if (t.isFunctionDeclaration(declarator.init)) {
142
+ return declarator.init;
143
+ }
144
+ }
145
+ return void 0;
146
+ }
147
+ return node;
148
+ }
149
+ function removeIdentifierLiteral(path, node) {
150
+ if (t.isIdentifier(node)) {
151
+ const binding = path.scope.getBinding(node.name);
152
+ if (binding) {
153
+ binding.path.remove();
154
+ }
155
+ }
156
+ }
157
+ const splitNodeTypes = ["component", "loader"];
158
+ async function splitFile(opts) {
159
+ return await opts.compile({
160
+ code: opts.code,
161
+ filename: opts.filename,
162
+ getBabelConfig: () => ({
163
+ plugins: [
164
+ [
165
+ {
166
+ visitor: {
167
+ Program: {
168
+ enter(programPath, state) {
169
+ const splitNodesByType = {
170
+ component: void 0,
171
+ loader: void 0
172
+ };
173
+ programPath.traverse(
174
+ {
175
+ CallExpression: (path) => {
176
+ if (path.node.callee.type === "Identifier") {
177
+ if (path.node.callee.name === "createFileRoute") {
178
+ if (path.parentPath.node.type === "CallExpression") {
179
+ const options = resolveIdentifier(
180
+ path,
181
+ path.parentPath.node.arguments[0]
182
+ );
183
+ if (t.isObjectExpression(options)) {
184
+ options.properties.forEach((prop) => {
185
+ if (t.isObjectProperty(prop)) {
186
+ splitNodeTypes.forEach((type) => {
187
+ if (t.isIdentifier(prop.key)) {
188
+ if (prop.key.name === type) {
189
+ splitNodesByType[type] = prop.value;
190
+ }
191
+ }
192
+ });
193
+ }
194
+ });
195
+ options.properties = [];
196
+ }
197
+ }
198
+ }
199
+ }
200
+ }
201
+ },
202
+ state
203
+ );
204
+ splitNodeTypes.forEach((splitType) => {
205
+ let splitNode = splitNodesByType[splitType];
206
+ if (!splitNode) {
207
+ return;
208
+ }
209
+ while (t.isIdentifier(splitNode)) {
210
+ const binding = programPath.scope.getBinding(
211
+ splitNode.name
212
+ );
213
+ splitNode = binding == null ? void 0 : binding.path.node;
214
+ }
215
+ if (splitNode) {
216
+ if (t.isFunctionDeclaration(splitNode)) {
217
+ programPath.pushContainer(
218
+ "body",
219
+ t.variableDeclaration("const", [
220
+ t.variableDeclarator(
221
+ t.identifier(splitType),
222
+ t.functionExpression(
223
+ splitNode.id || null,
224
+ // Anonymize the function expression
225
+ splitNode.params,
226
+ splitNode.body,
227
+ splitNode.generator,
228
+ splitNode.async
229
+ )
230
+ )
231
+ ])
232
+ );
233
+ } else if (t.isFunctionExpression(splitNode) || t.isArrowFunctionExpression(splitNode)) {
234
+ programPath.pushContainer(
235
+ "body",
236
+ t.variableDeclaration("const", [
237
+ t.variableDeclarator(
238
+ t.identifier(splitType),
239
+ splitNode
240
+ )
241
+ ])
242
+ );
243
+ } else if (t.isImportSpecifier(splitNode)) {
244
+ programPath.pushContainer(
245
+ "body",
246
+ t.variableDeclaration("const", [
247
+ t.variableDeclarator(
248
+ t.identifier(splitType),
249
+ splitNode.local
250
+ )
251
+ ])
252
+ );
253
+ } else {
254
+ console.log(splitNode);
255
+ throw new Error(
256
+ `Unexpected splitNode type: ${splitNode.type}`
257
+ );
258
+ }
259
+ }
260
+ programPath.node.body = programPath.node.body.filter(
261
+ (node) => {
262
+ return node !== splitNode;
263
+ }
264
+ );
265
+ programPath.pushContainer("body", [
266
+ t.exportNamedDeclaration(null, [
267
+ t.exportSpecifier(
268
+ t.identifier(splitType),
269
+ t.identifier(splitType)
270
+ )
271
+ ])
272
+ ]);
273
+ });
274
+ programPath.traverse({
275
+ ExportNamedDeclaration(path) {
276
+ if (path.node.declaration) {
277
+ if (t.isVariableDeclaration(path.node.declaration)) {
278
+ path.replaceWith(
279
+ t.importDeclaration(
280
+ path.node.declaration.declarations.map(
281
+ (decl) => t.importSpecifier(
282
+ t.identifier(decl.id.name),
283
+ t.identifier(decl.id.name)
284
+ )
285
+ ),
286
+ t.stringLiteral(
287
+ opts.filename.split(
288
+ `?${splitPrefix}`
289
+ )[0]
290
+ )
291
+ )
292
+ );
293
+ }
294
+ }
295
+ }
296
+ });
297
+ eliminateUnreferencedIdentifiers(programPath);
298
+ }
299
+ }
300
+ }
301
+ },
302
+ {
303
+ root: process.cwd(),
304
+ minify: process.env.NODE_ENV === "production"
305
+ }
306
+ ]
307
+ ].filter(Boolean)
308
+ })
309
+ });
310
+ }
311
+ export {
312
+ compileFile,
313
+ makeCompile,
314
+ splitFile
315
+ };
316
+ //# sourceMappingURL=compilers.js.map