@tanstack/router-plugin 1.40.3 → 1.41.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/ast.cjs CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const babel = require("@babel/core");
4
+ const _babelPluginJsx = require("@babel/plugin-syntax-jsx");
5
+ const _babelPluginTypeScript = require("@babel/plugin-syntax-typescript");
4
6
  function _interopNamespaceDefault(e) {
5
7
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
6
8
  if (e) {
@@ -18,13 +20,21 @@ function _interopNamespaceDefault(e) {
18
20
  return Object.freeze(n);
19
21
  }
20
22
  const babel__namespace = /* @__PURE__ */ _interopNamespaceDefault(babel);
23
+ let babelPluginJsx = _babelPluginJsx;
24
+ let babelPluginTypeScript = _babelPluginTypeScript;
25
+ if (babelPluginJsx.default) {
26
+ babelPluginJsx = babelPluginJsx.default;
27
+ }
28
+ if (babelPluginTypeScript.default) {
29
+ babelPluginTypeScript = babelPluginTypeScript.default;
30
+ }
21
31
  function compileAst(makeOpts) {
22
32
  return async (opts) => {
23
33
  const res = babel__namespace.transformSync(opts.code, {
24
34
  plugins: [
25
- ["@babel/plugin-syntax-jsx", {}],
35
+ babelPluginJsx,
26
36
  [
27
- "@babel/plugin-syntax-typescript",
37
+ babelPluginTypeScript,
28
38
  {
29
39
  isTSX: true
30
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ast.cjs","sources":["../../src/ast.ts"],"sourcesContent":["import * as babel from '@babel/core'\n\nexport type CompileAstFn = (compileOpts: {\n code: string\n filename: string\n getBabelConfig: () => { plugins: Array<any> }\n}) => Promise<{\n code: string\n map: any\n}>\n\nexport function compileAst(makeOpts: { root: string }) {\n return async (opts: {\n code: string\n filename: string\n getBabelConfig: () => { plugins: Array<any> }\n }): Promise<{\n code: string\n map: any\n }> => {\n const res = babel.transformSync(opts.code, {\n plugins: [\n ['@babel/plugin-syntax-jsx', {}],\n [\n '@babel/plugin-syntax-typescript',\n {\n isTSX: true,\n },\n ],\n ...opts.getBabelConfig().plugins,\n ],\n root: makeOpts.root,\n filename: opts.filename,\n sourceMaps: true,\n })\n\n if (res?.code) {\n return {\n code: res.code,\n map: res.map,\n }\n }\n\n return {\n code: opts.code,\n map: null,\n }\n }\n}\n"],"names":["babel"],"mappings":";;;;;;;;;;;;;;;;;;;;AAWO,SAAS,WAAW,UAA4B;AACrD,SAAO,OAAO,SAOR;AACJ,UAAM,MAAMA,iBAAM,cAAc,KAAK,MAAM;AAAA,MACzC,SAAS;AAAA,QACP,CAAC,4BAA4B,CAAA,CAAE;AAAA,QAC/B;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA,GAAG,KAAK,eAAA,EAAiB;AAAA,MAC3B;AAAA,MACA,MAAM,SAAS;AAAA,MACf,UAAU,KAAK;AAAA,MACf,YAAY;AAAA,IAAA,CACb;AAED,QAAI,2BAAK,MAAM;AACN,aAAA;AAAA,QACL,MAAM,IAAI;AAAA,QACV,KAAK,IAAI;AAAA,MAAA;AAAA,IAEb;AAEO,WAAA;AAAA,MACL,MAAM,KAAK;AAAA,MACX,KAAK;AAAA,IAAA;AAAA,EACP;AAEJ;;"}
1
+ {"version":3,"file":"ast.cjs","sources":["../../src/ast.ts"],"sourcesContent":["import * as babel from '@babel/core'\n// @ts-expect-error\nimport _babelPluginJsx from '@babel/plugin-syntax-jsx'\n// @ts-expect-error\nimport _babelPluginTypeScript from '@babel/plugin-syntax-typescript'\n\nlet babelPluginJsx = _babelPluginJsx\nlet babelPluginTypeScript = _babelPluginTypeScript\n\nif (babelPluginJsx.default) {\n babelPluginJsx = babelPluginJsx.default\n}\n\nif (babelPluginTypeScript.default) {\n babelPluginTypeScript = babelPluginTypeScript.default\n}\n\nexport type CompileAstFn = (compileOpts: {\n code: string\n filename: string\n getBabelConfig: () => { plugins: Array<any> }\n}) => Promise<{\n code: string\n map: any\n}>\n\nexport function compileAst(makeOpts: { root: string }) {\n return async (opts: {\n code: string\n filename: string\n getBabelConfig: () => { plugins: Array<any> }\n }): Promise<{\n code: string\n map: any\n }> => {\n const res = babel.transformSync(opts.code, {\n plugins: [\n babelPluginJsx,\n [\n babelPluginTypeScript,\n {\n isTSX: true,\n },\n ],\n ...opts.getBabelConfig().plugins,\n ],\n root: makeOpts.root,\n filename: opts.filename,\n sourceMaps: true,\n })\n\n if (res?.code) {\n return {\n code: res.code,\n map: res.map,\n }\n }\n\n return {\n code: opts.code,\n map: null,\n }\n }\n}\n"],"names":["babel"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAMA,IAAI,iBAAiB;AACrB,IAAI,wBAAwB;AAE5B,IAAI,eAAe,SAAS;AAC1B,mBAAiB,eAAe;AAClC;AAEA,IAAI,sBAAsB,SAAS;AACjC,0BAAwB,sBAAsB;AAChD;AAWO,SAAS,WAAW,UAA4B;AACrD,SAAO,OAAO,SAOR;AACJ,UAAM,MAAMA,iBAAM,cAAc,KAAK,MAAM;AAAA,MACzC,SAAS;AAAA,QACP;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA,GAAG,KAAK,eAAA,EAAiB;AAAA,MAC3B;AAAA,MACA,MAAM,SAAS;AAAA,MACf,UAAU,KAAK;AAAA,MACf,YAAY;AAAA,IAAA,CACb;AAED,QAAI,2BAAK,MAAM;AACN,aAAA;AAAA,QACL,MAAM,IAAI;AAAA,QACV,KAAK,IAAI;AAAA,MAAA;AAAA,IAEb;AAEO,WAAA;AAAA,MACL,MAAM,KAAK;AAAA,MACX,KAAK;AAAA,IAAA;AAAA,EACP;AAEJ;;"}
@@ -40,78 +40,50 @@ const unpluginRouterCodeSplitterFactory = (options = {}, { framework }) => {
40
40
  const compiledAst = ast.compileAst({
41
41
  root: ROOT
42
42
  });
43
- if (debug)
44
- console.info("Splitting route: ", id);
43
+ if (debug) console.info("Splitting route: ", id);
45
44
  const compiled = await compilers.splitFile({
46
45
  code,
47
46
  compileAst: compiledAst,
48
47
  filename: id
49
48
  });
50
- if (debug)
51
- console.info("");
52
- if (debug)
53
- console.info("Split Output");
54
- if (debug)
55
- console.info("");
56
- if (debug)
57
- console.info(compiled.code);
58
- if (debug)
59
- console.info("");
60
- if (debug)
61
- console.info("");
62
- if (debug)
63
- console.info("");
64
- if (debug)
65
- console.info("");
66
- if (debug)
67
- console.info("");
68
- if (debug)
69
- console.info("");
70
- if (debug)
71
- console.info("");
72
- if (debug)
73
- console.info("");
49
+ if (debug) console.info("");
50
+ if (debug) console.info("Split Output");
51
+ if (debug) console.info("");
52
+ if (debug) console.info(compiled.code);
53
+ if (debug) console.info("");
54
+ if (debug) console.info("");
55
+ if (debug) console.info("");
56
+ if (debug) console.info("");
57
+ if (debug) console.info("");
58
+ if (debug) console.info("");
59
+ if (debug) console.info("");
60
+ if (debug) console.info("");
74
61
  return compiled;
75
62
  };
76
63
  const handleCompilingFile = async (code, id) => {
77
64
  const compiledAst = ast.compileAst({
78
65
  root: ROOT
79
66
  });
80
- if (debug)
81
- console.info("Handling createRoute: ", id);
67
+ if (debug) console.info("Handling createRoute: ", id);
82
68
  const compiled = await compilers.compileFile({
83
69
  code,
84
70
  compileAst: compiledAst,
85
71
  filename: id
86
72
  });
87
- if (debug)
88
- console.info("");
89
- if (debug)
90
- console.info("Compiled Output");
91
- if (debug)
92
- console.info("");
93
- if (debug)
94
- console.info(compiled.code);
95
- if (debug)
96
- console.info("");
97
- if (debug)
98
- console.info("");
99
- if (debug)
100
- console.info("");
101
- if (debug)
102
- console.info("");
103
- if (debug)
104
- console.info("");
105
- if (debug)
106
- console.info("");
107
- if (debug)
108
- console.info("");
109
- if (debug)
110
- console.info("");
111
- if (debug)
112
- console.info("");
113
- if (debug)
114
- console.info("");
73
+ if (debug) console.info("");
74
+ if (debug) console.info("Compiled Output");
75
+ if (debug) console.info("");
76
+ if (debug) console.info(compiled.code);
77
+ if (debug) console.info("");
78
+ if (debug) console.info("");
79
+ if (debug) console.info("");
80
+ if (debug) console.info("");
81
+ if (debug) console.info("");
82
+ if (debug) console.info("");
83
+ if (debug) console.info("");
84
+ if (debug) console.info("");
85
+ if (debug) console.info("");
86
+ if (debug) console.info("");
115
87
  return compiled;
116
88
  };
117
89
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"code-splitter.cjs","sources":["../../src/code-splitter.ts"],"sourcesContent":["import { isAbsolute, join } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\n\nimport { compileAst } from './ast'\nimport { compileFile, splitFile } from './compilers'\nimport { getConfig } from './config'\nimport { splitPrefix } from './constants'\n\nimport type { Config } from './config'\nimport type { UnpluginContextMeta, UnpluginFactory } from 'unplugin'\n\nfunction capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1)\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\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(externalPlugin: BannedBeforeExternalPlugin, framework: string) {\n super(`We detected that the '${externalPlugin.pkg}' was passed before '@tanstack/router-plugin'. Please make sure that '@tanstack/router-plugin' is passed before '${externalPlugin.pkg}' and try again: \ne.g.\nplugins: [\n TanStackRouter${capitalizeFirst(framework)}(), // 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> | undefined\n> = (options = {}, { framework }) => {\n const debug = Boolean(process.env.TSR_VITE_DEBUG)\n\n let ROOT: string = process.cwd()\n let userConfig = options as Config\n\n const handleSplittingFile = async (code: string, id: string) => {\n const compiledAst = compileAst({\n root: ROOT,\n })\n\n if (debug) console.info('Splitting route: ', id)\n\n const compiled = await splitFile({\n code,\n compileAst: compiledAst,\n filename: id,\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 }\n\n const handleCompilingFile = async (code: string, id: string) => {\n const compiledAst = compileAst({\n root: ROOT,\n })\n\n if (debug) console.info('Handling createRoute: ', id)\n\n const compiled = await compileFile({\n code,\n compileAst: compiledAst,\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 {\n name: 'router-code-splitter-plugin',\n enforce: 'pre',\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\n async transform(code, id) {\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 if (id.includes(splitPrefix)) {\n return await handleSplittingFile(code, id)\n } else if (\n fileIsInRoutesDirectory(id, userConfig.routesDirectory) &&\n (code.includes('createRoute(') || code.includes('createFileRoute('))\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 await handleCompilingFile(code, id)\n }\n\n return null\n },\n\n vite: {\n async configResolved(config) {\n ROOT = config.root\n userConfig = await getConfig(options, ROOT)\n },\n },\n\n async rspack(compiler) {\n userConfig = await getConfig(options, ROOT)\n },\n }\n}\n"],"names":["isAbsolute","join","compileAst","splitFile","compileFile","splitPrefix","pathToFileURL","fileURLToPath","config","getConfig"],"mappings":"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"}
1
+ {"version":3,"file":"code-splitter.cjs","sources":["../../src/code-splitter.ts"],"sourcesContent":["import { isAbsolute, join } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\n\nimport { compileAst } from './ast'\nimport { compileFile, splitFile } from './compilers'\nimport { getConfig } from './config'\nimport { splitPrefix } from './constants'\n\nimport type { Config } from './config'\nimport type { UnpluginContextMeta, UnpluginFactory } from 'unplugin'\n\nfunction capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1)\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\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(externalPlugin: BannedBeforeExternalPlugin, framework: string) {\n super(`We detected that the '${externalPlugin.pkg}' was passed before '@tanstack/router-plugin'. Please make sure that '@tanstack/router-plugin' is passed before '${externalPlugin.pkg}' and try again: \ne.g.\nplugins: [\n TanStackRouter${capitalizeFirst(framework)}(), // 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> | undefined\n> = (options = {}, { framework }) => {\n const debug = Boolean(process.env.TSR_VITE_DEBUG)\n\n let ROOT: string = process.cwd()\n let userConfig = options as Config\n\n const handleSplittingFile = async (code: string, id: string) => {\n const compiledAst = compileAst({\n root: ROOT,\n })\n\n if (debug) console.info('Splitting route: ', id)\n\n const compiled = await splitFile({\n code,\n compileAst: compiledAst,\n filename: id,\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 }\n\n const handleCompilingFile = async (code: string, id: string) => {\n const compiledAst = compileAst({\n root: ROOT,\n })\n\n if (debug) console.info('Handling createRoute: ', id)\n\n const compiled = await compileFile({\n code,\n compileAst: compiledAst,\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 {\n name: 'router-code-splitter-plugin',\n enforce: 'pre',\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\n async transform(code, id) {\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 if (id.includes(splitPrefix)) {\n return await handleSplittingFile(code, id)\n } else if (\n fileIsInRoutesDirectory(id, userConfig.routesDirectory) &&\n (code.includes('createRoute(') || code.includes('createFileRoute('))\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 await handleCompilingFile(code, id)\n }\n\n return null\n },\n\n vite: {\n async configResolved(config) {\n ROOT = config.root\n userConfig = await getConfig(options, ROOT)\n },\n },\n\n async rspack(compiler) {\n userConfig = await getConfig(options, ROOT)\n },\n }\n}\n"],"names":["isAbsolute","join","compileAst","splitFile","compileFile","splitPrefix","pathToFileURL","fileURLToPath","config","getConfig"],"mappings":"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"}
@@ -147,8 +147,7 @@ async function compileFile(opts) {
147
147
  if (existingCompImportPath || existingLoaderImportPath) {
148
148
  programPath.traverse({
149
149
  ImportDeclaration(path) {
150
- if (path.node.specifiers.length > 0)
151
- return;
150
+ if (path.node.specifiers.length > 0) return;
152
151
  if (path.node.source.value === existingCompImportPath || path.node.source.value === existingLoaderImportPath) {
153
152
  path.remove();
154
153
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compilers.cjs","sources":["../../src/compilers.ts"],"sourcesContent":["import * as t from '@babel/types'\nimport babel from '@babel/core'\nimport generate from '@babel/generator'\nimport * as template from '@babel/template'\nimport { splitPrefix } from './constants'\nimport { eliminateUnreferencedIdentifiers } from './eliminateUnreferencedIdentifiers'\nimport type { CompileAstFn } from './ast'\n\ntype SplitModulesById = Record<\n string,\n { id: string; node: t.FunctionExpression }\n>\n\ninterface State {\n filename: string\n opts: {\n minify: boolean\n root: string\n }\n imported: Record<string, boolean>\n refs: Set<any>\n serverIndex: number\n splitIndex: number\n splitModulesById: SplitModulesById\n}\n\nexport async function compileFile(opts: {\n code: string\n compileAst: CompileAstFn\n filename: string\n}) {\n return await opts.compileAst({\n code: opts.code,\n filename: opts.filename,\n getBabelConfig: () => ({\n plugins: [\n [\n {\n visitor: {\n Program: {\n enter(programPath: babel.NodePath<t.Program>, state: State) {\n const splitUrl = `${splitPrefix}:${opts.filename}?${splitPrefix}`\n\n /**\n * If the component for the route is being imported from\n * another file, this is to track the path to that file\n * the path itself doesn't matter, we just need to keep\n * track of it so that we can remove it from the imports\n * list if it's not being used like:\n *\n * `import '../shared/imported'`\n */\n let existingCompImportPath: string | null = null\n let existingLoaderImportPath: string | null = null\n\n programPath.traverse(\n {\n CallExpression: (path) => {\n if (!t.isIdentifier(path.node.callee)) {\n return\n }\n\n if (\n !(\n path.node.callee.name === 'createRoute' ||\n path.node.callee.name === 'createFileRoute'\n )\n ) {\n return\n }\n\n if (t.isCallExpression(path.parentPath.node)) {\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n let found = false\n\n const hasImportedOrDefinedIdentifier = (\n name: string,\n ) => {\n return programPath.scope.hasBinding(name)\n }\n\n if (t.isObjectExpression(options)) {\n options.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n if (t.isIdentifier(prop.key)) {\n if (prop.key.name === 'component') {\n const value = prop.value\n\n if (t.isIdentifier(value)) {\n existingCompImportPath =\n getImportSpecifierAndPathFromLocalName(\n programPath,\n value.name,\n ).path\n\n removeIdentifierLiteral(path, value)\n }\n\n // Prepend the import statement to the program along with the importer function\n // Check to see if lazyRouteComponent is already imported before attempting\n // to import it again\n\n if (\n !hasImportedOrDefinedIdentifier(\n 'lazyRouteComponent',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `import { lazyRouteComponent } from '@tanstack/react-router'`,\n )(),\n ])\n }\n\n if (\n !hasImportedOrDefinedIdentifier(\n '$$splitComponentImporter',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `const $$splitComponentImporter = () => import('${splitUrl}')`,\n )(),\n ])\n }\n\n prop.value = template.expression(\n `lazyRouteComponent($$splitComponentImporter, 'component')`,\n )()\n\n programPath.pushContainer('body', [\n template.statement(\n `function DummyComponent() { return null }`,\n )(),\n ])\n\n found = true\n } else if (prop.key.name === 'loader') {\n const value = prop.value\n\n if (t.isIdentifier(value)) {\n existingLoaderImportPath =\n getImportSpecifierAndPathFromLocalName(\n programPath,\n value.name,\n ).path\n\n removeIdentifierLiteral(path, value)\n }\n\n // Prepend the import statement to the program along with the importer function\n\n if (\n !hasImportedOrDefinedIdentifier('lazyFn')\n ) {\n programPath.unshiftContainer('body', [\n template.smart(\n `import { lazyFn } from '@tanstack/react-router'`,\n )() as t.Statement,\n ])\n }\n\n if (\n !hasImportedOrDefinedIdentifier(\n '$$splitLoaderImporter',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `const $$splitLoaderImporter = () => import('${splitUrl}')`,\n )(),\n ])\n }\n\n prop.value = template.expression(\n `lazyFn($$splitLoaderImporter, 'loader')`,\n )()\n\n found = true\n }\n }\n }\n\n programPath.scope.crawl()\n })\n }\n\n if (found as boolean) {\n programPath.pushContainer('body', [\n template.statement(\n `function TSR_Dummy_Component() {}`,\n )(),\n ])\n }\n }\n },\n },\n state,\n )\n\n eliminateUnreferencedIdentifiers(programPath)\n\n /**\n * If the component for the route is being imported,\n * and it's not being used, remove the import statement\n * from the program, by checking that the import has no\n * specifiers\n */\n if (\n (existingCompImportPath as string | null) ||\n (existingLoaderImportPath as string | null)\n ) {\n programPath.traverse({\n ImportDeclaration(path) {\n if (path.node.specifiers.length > 0) return\n if (\n path.node.source.value === existingCompImportPath ||\n path.node.source.value === existingLoaderImportPath\n ) {\n path.remove()\n }\n },\n })\n }\n },\n },\n },\n },\n {\n root: process.cwd(),\n minify: process.env.NODE_ENV === 'production',\n },\n ],\n ].filter(Boolean),\n }),\n })\n}\n\nfunction getImportSpecifierAndPathFromLocalName(\n programPath: babel.NodePath<t.Program>,\n name: string,\n): {\n specifier:\n | t.ImportSpecifier\n | t.ImportDefaultSpecifier\n | t.ImportNamespaceSpecifier\n | null\n path: string | null\n} {\n let specifier:\n | t.ImportSpecifier\n | t.ImportDefaultSpecifier\n | t.ImportNamespaceSpecifier\n | null = null\n let path: string | null = null\n\n programPath.traverse({\n ImportDeclaration(importPath) {\n const found = importPath.node.specifiers.find(\n (targetSpecifier) => targetSpecifier.local.name === name,\n )\n if (found) {\n specifier = found\n path = importPath.node.source.value\n }\n },\n })\n\n return { specifier, path }\n}\n\n// Reusable function to get literal value or resolve variable to literal\nfunction resolveIdentifier(path: any, node: any) {\n if (t.isIdentifier(node)) {\n const binding = path.scope.getBinding(node.name)\n if (\n binding\n // && binding.kind === 'const'\n ) {\n const declarator = binding.path.node\n if (t.isObjectExpression(declarator.init)) {\n return declarator.init\n } else if (t.isFunctionDeclaration(declarator.init)) {\n return declarator.init\n }\n }\n return undefined\n }\n\n return node\n}\n\nfunction removeIdentifierLiteral(path: any, node: any) {\n if (t.isIdentifier(node)) {\n const binding = path.scope.getBinding(node.name)\n if (binding) {\n binding.path.remove()\n }\n }\n}\n\nconst splitNodeTypes = ['component', 'loader'] as const\ntype SplitNodeType = (typeof splitNodeTypes)[number]\n\nexport async function splitFile(opts: {\n code: string\n compileAst: CompileAstFn\n filename: string\n}) {\n return await opts.compileAst({\n code: opts.code,\n filename: opts.filename,\n getBabelConfig: () => ({\n plugins: [\n [\n {\n visitor: {\n Program: {\n enter(programPath: babel.NodePath<t.Program>, state: State) {\n const splitNodesByType: Record<\n SplitNodeType,\n t.Node | undefined\n > = {\n component: undefined,\n loader: undefined,\n }\n\n // Find the node\n programPath.traverse(\n {\n CallExpression: (path) => {\n if (!t.isIdentifier(path.node.callee)) {\n return\n }\n\n if (\n !(\n path.node.callee.name === 'createRoute' ||\n path.node.callee.name === 'createFileRoute'\n )\n ) {\n return\n }\n\n if (t.isCallExpression(path.parentPath.node)) {\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n if (t.isObjectExpression(options)) {\n options.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n splitNodeTypes.forEach((type) => {\n if (t.isIdentifier(prop.key)) {\n if (prop.key.name === type) {\n splitNodesByType[type] = prop.value\n }\n }\n })\n }\n })\n\n // Remove all of the options\n options.properties = []\n }\n }\n },\n },\n state,\n )\n\n splitNodeTypes.forEach((splitType) => {\n let splitNode = splitNodesByType[splitType]\n\n if (!splitNode) {\n return\n }\n\n while (t.isIdentifier(splitNode)) {\n const binding = programPath.scope.getBinding(\n splitNode.name,\n )\n splitNode = binding?.path.node\n }\n\n // Add the node to the program\n if (splitNode) {\n if (t.isFunctionDeclaration(splitNode)) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n t.functionExpression(\n splitNode.id || null, // Anonymize the function expression\n splitNode.params,\n splitNode.body,\n splitNode.generator,\n splitNode.async,\n ),\n ),\n ]),\n )\n } else if (\n t.isFunctionExpression(splitNode) ||\n t.isArrowFunctionExpression(splitNode)\n ) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n splitNode as any,\n ),\n ]),\n )\n } else if (\n t.isImportSpecifier(splitNode) ||\n t.isImportDefaultSpecifier(splitNode)\n ) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n splitNode.local,\n ),\n ]),\n )\n } else if (t.isCallExpression(splitNode)) {\n const outputSplitNodeCode = generate(splitNode).code\n const splitNodeAst = babel.parse(outputSplitNodeCode)\n\n if (!splitNodeAst) {\n throw new Error(\n `Failed to parse the generated code for \"${splitType}\" in the node type \"${splitNode.type}\"`,\n )\n }\n\n const statement = splitNodeAst.program.body[0]\n\n if (!statement) {\n throw new Error(\n `Failed to parse the generated code for \"${splitType}\" in the node type \"${splitNode.type}\" as no statement was found in the program body`,\n )\n }\n\n if (t.isExpressionStatement(statement)) {\n const expression = statement.expression\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n expression,\n ),\n ]),\n )\n } else {\n throw new Error(\n `Unexpected expression type encounter for \"${splitType}\" in the node type \"${splitNode.type}\"`,\n )\n }\n } else {\n console.info('Unexpected splitNode type:', splitNode)\n throw new Error(\n `Unexpected splitNode type ☝️: ${splitNode.type}`,\n )\n }\n }\n\n // If the splitNode exists at the top of the program\n // then we need to remove that copy\n programPath.node.body = programPath.node.body.filter(\n (node) => {\n return node !== splitNode\n },\n )\n\n // Export the node\n programPath.pushContainer('body', [\n t.exportNamedDeclaration(null, [\n t.exportSpecifier(\n t.identifier(splitType),\n t.identifier(splitType),\n ),\n ]),\n ])\n })\n\n // convert exports to imports from the original file\n programPath.traverse({\n ExportNamedDeclaration(path) {\n // e.g. export const x = 1 or export { x }\n // becomes\n // import { x } from '${opts.id}'\n\n if (path.node.declaration) {\n if (t.isVariableDeclaration(path.node.declaration)) {\n path.replaceWith(\n t.importDeclaration(\n path.node.declaration.declarations.map((decl) =>\n t.importSpecifier(\n t.identifier((decl.id as any).name),\n t.identifier((decl.id as any).name),\n ),\n ),\n t.stringLiteral(\n opts.filename.split(\n `?${splitPrefix}`,\n )[0] as string,\n ),\n ),\n )\n }\n }\n },\n })\n\n eliminateUnreferencedIdentifiers(programPath)\n },\n },\n },\n },\n {\n root: process.cwd(),\n minify: process.env.NODE_ENV === 'production',\n },\n ],\n ].filter(Boolean),\n }),\n })\n}\n"],"names":["splitPrefix","t","template","eliminateUnreferencedIdentifiers"],"mappings":"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"}
1
+ {"version":3,"file":"compilers.cjs","sources":["../../src/compilers.ts"],"sourcesContent":["import * as t from '@babel/types'\nimport babel from '@babel/core'\nimport generate from '@babel/generator'\nimport * as template from '@babel/template'\nimport { splitPrefix } from './constants'\nimport { eliminateUnreferencedIdentifiers } from './eliminateUnreferencedIdentifiers'\nimport type { CompileAstFn } from './ast'\n\ntype SplitModulesById = Record<\n string,\n { id: string; node: t.FunctionExpression }\n>\n\ninterface State {\n filename: string\n opts: {\n minify: boolean\n root: string\n }\n imported: Record<string, boolean>\n refs: Set<any>\n serverIndex: number\n splitIndex: number\n splitModulesById: SplitModulesById\n}\n\nexport async function compileFile(opts: {\n code: string\n compileAst: CompileAstFn\n filename: string\n}) {\n return await opts.compileAst({\n code: opts.code,\n filename: opts.filename,\n getBabelConfig: () => ({\n plugins: [\n [\n {\n visitor: {\n Program: {\n enter(programPath: babel.NodePath<t.Program>, state: State) {\n const splitUrl = `${splitPrefix}:${opts.filename}?${splitPrefix}`\n\n /**\n * If the component for the route is being imported from\n * another file, this is to track the path to that file\n * the path itself doesn't matter, we just need to keep\n * track of it so that we can remove it from the imports\n * list if it's not being used like:\n *\n * `import '../shared/imported'`\n */\n let existingCompImportPath: string | null = null\n let existingLoaderImportPath: string | null = null\n\n programPath.traverse(\n {\n CallExpression: (path) => {\n if (!t.isIdentifier(path.node.callee)) {\n return\n }\n\n if (\n !(\n path.node.callee.name === 'createRoute' ||\n path.node.callee.name === 'createFileRoute'\n )\n ) {\n return\n }\n\n if (t.isCallExpression(path.parentPath.node)) {\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n let found = false\n\n const hasImportedOrDefinedIdentifier = (\n name: string,\n ) => {\n return programPath.scope.hasBinding(name)\n }\n\n if (t.isObjectExpression(options)) {\n options.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n if (t.isIdentifier(prop.key)) {\n if (prop.key.name === 'component') {\n const value = prop.value\n\n if (t.isIdentifier(value)) {\n existingCompImportPath =\n getImportSpecifierAndPathFromLocalName(\n programPath,\n value.name,\n ).path\n\n removeIdentifierLiteral(path, value)\n }\n\n // Prepend the import statement to the program along with the importer function\n // Check to see if lazyRouteComponent is already imported before attempting\n // to import it again\n\n if (\n !hasImportedOrDefinedIdentifier(\n 'lazyRouteComponent',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `import { lazyRouteComponent } from '@tanstack/react-router'`,\n )(),\n ])\n }\n\n if (\n !hasImportedOrDefinedIdentifier(\n '$$splitComponentImporter',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `const $$splitComponentImporter = () => import('${splitUrl}')`,\n )(),\n ])\n }\n\n prop.value = template.expression(\n `lazyRouteComponent($$splitComponentImporter, 'component')`,\n )()\n\n programPath.pushContainer('body', [\n template.statement(\n `function DummyComponent() { return null }`,\n )(),\n ])\n\n found = true\n } else if (prop.key.name === 'loader') {\n const value = prop.value\n\n if (t.isIdentifier(value)) {\n existingLoaderImportPath =\n getImportSpecifierAndPathFromLocalName(\n programPath,\n value.name,\n ).path\n\n removeIdentifierLiteral(path, value)\n }\n\n // Prepend the import statement to the program along with the importer function\n\n if (\n !hasImportedOrDefinedIdentifier('lazyFn')\n ) {\n programPath.unshiftContainer('body', [\n template.smart(\n `import { lazyFn } from '@tanstack/react-router'`,\n )() as t.Statement,\n ])\n }\n\n if (\n !hasImportedOrDefinedIdentifier(\n '$$splitLoaderImporter',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `const $$splitLoaderImporter = () => import('${splitUrl}')`,\n )(),\n ])\n }\n\n prop.value = template.expression(\n `lazyFn($$splitLoaderImporter, 'loader')`,\n )()\n\n found = true\n }\n }\n }\n\n programPath.scope.crawl()\n })\n }\n\n if (found as boolean) {\n programPath.pushContainer('body', [\n template.statement(\n `function TSR_Dummy_Component() {}`,\n )(),\n ])\n }\n }\n },\n },\n state,\n )\n\n eliminateUnreferencedIdentifiers(programPath)\n\n /**\n * If the component for the route is being imported,\n * and it's not being used, remove the import statement\n * from the program, by checking that the import has no\n * specifiers\n */\n if (\n (existingCompImportPath as string | null) ||\n (existingLoaderImportPath as string | null)\n ) {\n programPath.traverse({\n ImportDeclaration(path) {\n if (path.node.specifiers.length > 0) return\n if (\n path.node.source.value === existingCompImportPath ||\n path.node.source.value === existingLoaderImportPath\n ) {\n path.remove()\n }\n },\n })\n }\n },\n },\n },\n },\n {\n root: process.cwd(),\n minify: process.env.NODE_ENV === 'production',\n },\n ],\n ].filter(Boolean),\n }),\n })\n}\n\nfunction getImportSpecifierAndPathFromLocalName(\n programPath: babel.NodePath<t.Program>,\n name: string,\n): {\n specifier:\n | t.ImportSpecifier\n | t.ImportDefaultSpecifier\n | t.ImportNamespaceSpecifier\n | null\n path: string | null\n} {\n let specifier:\n | t.ImportSpecifier\n | t.ImportDefaultSpecifier\n | t.ImportNamespaceSpecifier\n | null = null\n let path: string | null = null\n\n programPath.traverse({\n ImportDeclaration(importPath) {\n const found = importPath.node.specifiers.find(\n (targetSpecifier) => targetSpecifier.local.name === name,\n )\n if (found) {\n specifier = found\n path = importPath.node.source.value\n }\n },\n })\n\n return { specifier, path }\n}\n\n// Reusable function to get literal value or resolve variable to literal\nfunction resolveIdentifier(path: any, node: any) {\n if (t.isIdentifier(node)) {\n const binding = path.scope.getBinding(node.name)\n if (\n binding\n // && binding.kind === 'const'\n ) {\n const declarator = binding.path.node\n if (t.isObjectExpression(declarator.init)) {\n return declarator.init\n } else if (t.isFunctionDeclaration(declarator.init)) {\n return declarator.init\n }\n }\n return undefined\n }\n\n return node\n}\n\nfunction removeIdentifierLiteral(path: any, node: any) {\n if (t.isIdentifier(node)) {\n const binding = path.scope.getBinding(node.name)\n if (binding) {\n binding.path.remove()\n }\n }\n}\n\nconst splitNodeTypes = ['component', 'loader'] as const\ntype SplitNodeType = (typeof splitNodeTypes)[number]\n\nexport async function splitFile(opts: {\n code: string\n compileAst: CompileAstFn\n filename: string\n}) {\n return await opts.compileAst({\n code: opts.code,\n filename: opts.filename,\n getBabelConfig: () => ({\n plugins: [\n [\n {\n visitor: {\n Program: {\n enter(programPath: babel.NodePath<t.Program>, state: State) {\n const splitNodesByType: Record<\n SplitNodeType,\n t.Node | undefined\n > = {\n component: undefined,\n loader: undefined,\n }\n\n // Find the node\n programPath.traverse(\n {\n CallExpression: (path) => {\n if (!t.isIdentifier(path.node.callee)) {\n return\n }\n\n if (\n !(\n path.node.callee.name === 'createRoute' ||\n path.node.callee.name === 'createFileRoute'\n )\n ) {\n return\n }\n\n if (t.isCallExpression(path.parentPath.node)) {\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n if (t.isObjectExpression(options)) {\n options.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n splitNodeTypes.forEach((type) => {\n if (t.isIdentifier(prop.key)) {\n if (prop.key.name === type) {\n splitNodesByType[type] = prop.value\n }\n }\n })\n }\n })\n\n // Remove all of the options\n options.properties = []\n }\n }\n },\n },\n state,\n )\n\n splitNodeTypes.forEach((splitType) => {\n let splitNode = splitNodesByType[splitType]\n\n if (!splitNode) {\n return\n }\n\n while (t.isIdentifier(splitNode)) {\n const binding = programPath.scope.getBinding(\n splitNode.name,\n )\n splitNode = binding?.path.node\n }\n\n // Add the node to the program\n if (splitNode) {\n if (t.isFunctionDeclaration(splitNode)) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n t.functionExpression(\n splitNode.id || null, // Anonymize the function expression\n splitNode.params,\n splitNode.body,\n splitNode.generator,\n splitNode.async,\n ),\n ),\n ]),\n )\n } else if (\n t.isFunctionExpression(splitNode) ||\n t.isArrowFunctionExpression(splitNode)\n ) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n splitNode as any,\n ),\n ]),\n )\n } else if (\n t.isImportSpecifier(splitNode) ||\n t.isImportDefaultSpecifier(splitNode)\n ) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n splitNode.local,\n ),\n ]),\n )\n } else if (t.isCallExpression(splitNode)) {\n const outputSplitNodeCode = generate(splitNode).code\n const splitNodeAst = babel.parse(outputSplitNodeCode)\n\n if (!splitNodeAst) {\n throw new Error(\n `Failed to parse the generated code for \"${splitType}\" in the node type \"${splitNode.type}\"`,\n )\n }\n\n const statement = splitNodeAst.program.body[0]\n\n if (!statement) {\n throw new Error(\n `Failed to parse the generated code for \"${splitType}\" in the node type \"${splitNode.type}\" as no statement was found in the program body`,\n )\n }\n\n if (t.isExpressionStatement(statement)) {\n const expression = statement.expression\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n expression,\n ),\n ]),\n )\n } else {\n throw new Error(\n `Unexpected expression type encounter for \"${splitType}\" in the node type \"${splitNode.type}\"`,\n )\n }\n } else {\n console.info('Unexpected splitNode type:', splitNode)\n throw new Error(\n `Unexpected splitNode type ☝️: ${splitNode.type}`,\n )\n }\n }\n\n // If the splitNode exists at the top of the program\n // then we need to remove that copy\n programPath.node.body = programPath.node.body.filter(\n (node) => {\n return node !== splitNode\n },\n )\n\n // Export the node\n programPath.pushContainer('body', [\n t.exportNamedDeclaration(null, [\n t.exportSpecifier(\n t.identifier(splitType),\n t.identifier(splitType),\n ),\n ]),\n ])\n })\n\n // convert exports to imports from the original file\n programPath.traverse({\n ExportNamedDeclaration(path) {\n // e.g. export const x = 1 or export { x }\n // becomes\n // import { x } from '${opts.id}'\n\n if (path.node.declaration) {\n if (t.isVariableDeclaration(path.node.declaration)) {\n path.replaceWith(\n t.importDeclaration(\n path.node.declaration.declarations.map((decl) =>\n t.importSpecifier(\n t.identifier((decl.id as any).name),\n t.identifier((decl.id as any).name),\n ),\n ),\n t.stringLiteral(\n opts.filename.split(\n `?${splitPrefix}`,\n )[0] as string,\n ),\n ),\n )\n }\n }\n },\n })\n\n eliminateUnreferencedIdentifiers(programPath)\n },\n },\n },\n },\n {\n root: process.cwd(),\n minify: process.env.NODE_ENV === 'production',\n },\n ],\n ].filter(Boolean),\n }),\n })\n}\n"],"names":["splitPrefix","t","template","eliminateUnreferencedIdentifiers"],"mappings":"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"}
@@ -21,8 +21,7 @@ const t__namespace = /* @__PURE__ */ _interopNamespaceDefault(t);
21
21
  const eliminateUnreferencedIdentifiers = (programPath, refs) => {
22
22
  let referencesRemovedInThisPass;
23
23
  const shouldBeRemoved = (ident) => {
24
- if (isIdentifierReferenced(ident))
25
- return false;
24
+ if (isIdentifierReferenced(ident)) return false;
26
25
  return true;
27
26
  };
28
27
  const sweepFunction = (path) => {
@@ -1 +1 @@
1
- {"version":3,"file":"eliminateUnreferencedIdentifiers.cjs","sources":["../../src/eliminateUnreferencedIdentifiers.ts"],"sourcesContent":["// Copied from https://github.com/pcattori/vite-env-only/blob/main/src/dce.ts\n// Adapted with some minor changes for the purpose of this project\n\nimport * as t from '@babel/types'\nimport type { types as BabelTypes } from '@babel/core'\nimport type { NodePath } from '@babel/traverse'\n\ntype IdentifierPath = NodePath<BabelTypes.Identifier>\n\n/**\n * @param refs - If provided, only these identifiers will be considered for removal.\n */\nexport const eliminateUnreferencedIdentifiers = (\n programPath: NodePath<BabelTypes.Program>,\n refs?: Set<IdentifierPath>,\n) => {\n let referencesRemovedInThisPass: number\n\n const shouldBeRemoved = (ident: IdentifierPath) => {\n if (isIdentifierReferenced(ident)) return false\n if (!refs) return true\n return refs.has(ident)\n }\n\n const sweepFunction = (\n path: NodePath<\n | BabelTypes.FunctionDeclaration\n | BabelTypes.FunctionExpression\n | BabelTypes.ArrowFunctionExpression\n >,\n ) => {\n const identifier = getIdentifier(path)\n if (identifier?.node && shouldBeRemoved(identifier)) {\n ++referencesRemovedInThisPass\n\n if (\n t.isAssignmentExpression(path.parentPath.node) ||\n t.isVariableDeclarator(path.parentPath.node)\n ) {\n path.parentPath.remove()\n } else {\n path.remove()\n }\n }\n }\n\n const sweepImport = (\n path: NodePath<\n | BabelTypes.ImportSpecifier\n | BabelTypes.ImportDefaultSpecifier\n | BabelTypes.ImportNamespaceSpecifier\n >,\n ) => {\n const local = path.get('local')\n if (shouldBeRemoved(local)) {\n ++referencesRemovedInThisPass\n path.remove()\n if (\n (path.parent as BabelTypes.ImportDeclaration).specifiers.length === 0\n ) {\n path.parentPath.remove()\n }\n }\n }\n\n const handleObjectPattern = (pattern: NodePath<BabelTypes.ObjectPattern>) => {\n const properties = pattern.get('properties')\n properties.forEach((property) => {\n if (property.node.type === 'ObjectProperty') {\n const value = property.get('value') as any\n if (t.isIdentifier(value)) {\n if (shouldBeRemoved(value as any)) {\n property.remove()\n }\n } else if (t.isObjectPattern(value)) {\n handleObjectPattern(value as any)\n }\n } else if (t.isRestElement(property.node)) {\n const argument = property.get('argument')\n if (\n t.isIdentifier(argument as any) &&\n shouldBeRemoved(argument as NodePath<BabelTypes.Identifier>)\n ) {\n property.remove()\n }\n }\n })\n }\n\n // Traverse again to remove unused references. This happens at least once,\n // then repeats until no more references are removed.\n do {\n referencesRemovedInThisPass = 0\n\n programPath.scope.crawl()\n\n programPath.traverse({\n VariableDeclarator(path) {\n if (path.node.id.type === 'Identifier') {\n const local = path.get('id') as NodePath<BabelTypes.Identifier>\n if (shouldBeRemoved(local)) {\n ++referencesRemovedInThisPass\n path.remove()\n }\n } else if (path.node.id.type === 'ObjectPattern') {\n handleObjectPattern(\n path.get('id') as NodePath<BabelTypes.ObjectPattern>,\n )\n } else if (path.node.id.type === 'ArrayPattern') {\n const pattern = path.get('id') as NodePath<BabelTypes.ArrayPattern>\n\n let hasRemoved = false as boolean\n\n pattern.get('elements').forEach((element, index) => {\n // if (!element) return // Skip holes in the pattern\n\n let identifierPath: NodePath<BabelTypes.Identifier>\n\n if (t.isIdentifier(element.node)) {\n identifierPath = element as NodePath<BabelTypes.Identifier>\n } else if (t.isRestElement(element.node)) {\n identifierPath = element.get(\n 'argument',\n ) as NodePath<BabelTypes.Identifier>\n } else {\n // For now, ignore other types like AssignmentPattern\n return\n }\n\n if (shouldBeRemoved(identifierPath)) {\n hasRemoved = true\n pattern.node.elements[index] = null // Remove the element by setting it to null\n }\n })\n\n // If any elements were removed and no elements are left, remove the entire declaration\n if (\n hasRemoved &&\n pattern.node.elements.every((element) => element === null)\n ) {\n path.remove()\n ++referencesRemovedInThisPass\n }\n }\n },\n FunctionDeclaration: sweepFunction,\n FunctionExpression: sweepFunction,\n ArrowFunctionExpression: sweepFunction,\n ImportSpecifier: sweepImport,\n ImportDefaultSpecifier: sweepImport,\n ImportNamespaceSpecifier: sweepImport,\n })\n } while (referencesRemovedInThisPass)\n}\n\nfunction getIdentifier(\n path: NodePath<\n | BabelTypes.FunctionDeclaration\n | BabelTypes.FunctionExpression\n | BabelTypes.ArrowFunctionExpression\n >,\n): NodePath<BabelTypes.Identifier> | null {\n const parentPath = path.parentPath\n if (parentPath.type === 'VariableDeclarator') {\n const variablePath = parentPath as NodePath<BabelTypes.VariableDeclarator>\n const name = variablePath.get('id')\n return name.node.type === 'Identifier'\n ? (name as NodePath<BabelTypes.Identifier>)\n : null\n }\n\n if (parentPath.type === 'AssignmentExpression') {\n const variablePath = parentPath as NodePath<BabelTypes.AssignmentExpression>\n const name = variablePath.get('left')\n return name.node.type === 'Identifier'\n ? (name as NodePath<BabelTypes.Identifier>)\n : null\n }\n\n if (path.node.type === 'ArrowFunctionExpression') {\n return null\n }\n\n if (path.node.type === 'FunctionExpression') {\n return null\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return path.node.id && path.node.id.type === 'Identifier'\n ? (path.get('id') as NodePath<BabelTypes.Identifier>)\n : null\n}\n\nfunction isIdentifierReferenced(\n ident: NodePath<BabelTypes.Identifier>,\n): boolean {\n const binding = ident.scope.getBinding(ident.node.name)\n if (binding?.referenced) {\n // Functions can reference themselves, so we need to check if there's a\n // binding outside the function scope or not.\n if (binding.path.type === 'FunctionDeclaration') {\n return !binding.constantViolations\n .concat(binding.referencePaths)\n // Check that every reference is contained within the function:\n .every((ref) => ref.findParent((parent) => parent === binding.path))\n }\n\n return true\n }\n return false\n}\n"],"names":["t"],"mappings":"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"}
1
+ {"version":3,"file":"eliminateUnreferencedIdentifiers.cjs","sources":["../../src/eliminateUnreferencedIdentifiers.ts"],"sourcesContent":["// Copied from https://github.com/pcattori/vite-env-only/blob/main/src/dce.ts\n// Adapted with some minor changes for the purpose of this project\n\nimport * as t from '@babel/types'\nimport type { types as BabelTypes } from '@babel/core'\nimport type { NodePath } from '@babel/traverse'\n\ntype IdentifierPath = NodePath<BabelTypes.Identifier>\n\n/**\n * @param refs - If provided, only these identifiers will be considered for removal.\n */\nexport const eliminateUnreferencedIdentifiers = (\n programPath: NodePath<BabelTypes.Program>,\n refs?: Set<IdentifierPath>,\n) => {\n let referencesRemovedInThisPass: number\n\n const shouldBeRemoved = (ident: IdentifierPath) => {\n if (isIdentifierReferenced(ident)) return false\n if (!refs) return true\n return refs.has(ident)\n }\n\n const sweepFunction = (\n path: NodePath<\n | BabelTypes.FunctionDeclaration\n | BabelTypes.FunctionExpression\n | BabelTypes.ArrowFunctionExpression\n >,\n ) => {\n const identifier = getIdentifier(path)\n if (identifier?.node && shouldBeRemoved(identifier)) {\n ++referencesRemovedInThisPass\n\n if (\n t.isAssignmentExpression(path.parentPath.node) ||\n t.isVariableDeclarator(path.parentPath.node)\n ) {\n path.parentPath.remove()\n } else {\n path.remove()\n }\n }\n }\n\n const sweepImport = (\n path: NodePath<\n | BabelTypes.ImportSpecifier\n | BabelTypes.ImportDefaultSpecifier\n | BabelTypes.ImportNamespaceSpecifier\n >,\n ) => {\n const local = path.get('local')\n if (shouldBeRemoved(local)) {\n ++referencesRemovedInThisPass\n path.remove()\n if (\n (path.parent as BabelTypes.ImportDeclaration).specifiers.length === 0\n ) {\n path.parentPath.remove()\n }\n }\n }\n\n const handleObjectPattern = (pattern: NodePath<BabelTypes.ObjectPattern>) => {\n const properties = pattern.get('properties')\n properties.forEach((property) => {\n if (property.node.type === 'ObjectProperty') {\n const value = property.get('value') as any\n if (t.isIdentifier(value)) {\n if (shouldBeRemoved(value as any)) {\n property.remove()\n }\n } else if (t.isObjectPattern(value)) {\n handleObjectPattern(value as any)\n }\n } else if (t.isRestElement(property.node)) {\n const argument = property.get('argument')\n if (\n t.isIdentifier(argument as any) &&\n shouldBeRemoved(argument as NodePath<BabelTypes.Identifier>)\n ) {\n property.remove()\n }\n }\n })\n }\n\n // Traverse again to remove unused references. This happens at least once,\n // then repeats until no more references are removed.\n do {\n referencesRemovedInThisPass = 0\n\n programPath.scope.crawl()\n\n programPath.traverse({\n VariableDeclarator(path) {\n if (path.node.id.type === 'Identifier') {\n const local = path.get('id') as NodePath<BabelTypes.Identifier>\n if (shouldBeRemoved(local)) {\n ++referencesRemovedInThisPass\n path.remove()\n }\n } else if (path.node.id.type === 'ObjectPattern') {\n handleObjectPattern(\n path.get('id') as NodePath<BabelTypes.ObjectPattern>,\n )\n } else if (path.node.id.type === 'ArrayPattern') {\n const pattern = path.get('id') as NodePath<BabelTypes.ArrayPattern>\n\n let hasRemoved = false as boolean\n\n pattern.get('elements').forEach((element, index) => {\n // if (!element) return // Skip holes in the pattern\n\n let identifierPath: NodePath<BabelTypes.Identifier>\n\n if (t.isIdentifier(element.node)) {\n identifierPath = element as NodePath<BabelTypes.Identifier>\n } else if (t.isRestElement(element.node)) {\n identifierPath = element.get(\n 'argument',\n ) as NodePath<BabelTypes.Identifier>\n } else {\n // For now, ignore other types like AssignmentPattern\n return\n }\n\n if (shouldBeRemoved(identifierPath)) {\n hasRemoved = true\n pattern.node.elements[index] = null // Remove the element by setting it to null\n }\n })\n\n // If any elements were removed and no elements are left, remove the entire declaration\n if (\n hasRemoved &&\n pattern.node.elements.every((element) => element === null)\n ) {\n path.remove()\n ++referencesRemovedInThisPass\n }\n }\n },\n FunctionDeclaration: sweepFunction,\n FunctionExpression: sweepFunction,\n ArrowFunctionExpression: sweepFunction,\n ImportSpecifier: sweepImport,\n ImportDefaultSpecifier: sweepImport,\n ImportNamespaceSpecifier: sweepImport,\n })\n } while (referencesRemovedInThisPass)\n}\n\nfunction getIdentifier(\n path: NodePath<\n | BabelTypes.FunctionDeclaration\n | BabelTypes.FunctionExpression\n | BabelTypes.ArrowFunctionExpression\n >,\n): NodePath<BabelTypes.Identifier> | null {\n const parentPath = path.parentPath\n if (parentPath.type === 'VariableDeclarator') {\n const variablePath = parentPath as NodePath<BabelTypes.VariableDeclarator>\n const name = variablePath.get('id')\n return name.node.type === 'Identifier'\n ? (name as NodePath<BabelTypes.Identifier>)\n : null\n }\n\n if (parentPath.type === 'AssignmentExpression') {\n const variablePath = parentPath as NodePath<BabelTypes.AssignmentExpression>\n const name = variablePath.get('left')\n return name.node.type === 'Identifier'\n ? (name as NodePath<BabelTypes.Identifier>)\n : null\n }\n\n if (path.node.type === 'ArrowFunctionExpression') {\n return null\n }\n\n if (path.node.type === 'FunctionExpression') {\n return null\n }\n\n // eslint-disable-next-line ts/no-unnecessary-condition\n return path.node.id && path.node.id.type === 'Identifier'\n ? (path.get('id') as NodePath<BabelTypes.Identifier>)\n : null\n}\n\nfunction isIdentifierReferenced(\n ident: NodePath<BabelTypes.Identifier>,\n): boolean {\n const binding = ident.scope.getBinding(ident.node.name)\n if (binding?.referenced) {\n // Functions can reference themselves, so we need to check if there's a\n // binding outside the function scope or not.\n if (binding.path.type === 'FunctionDeclaration') {\n return !binding.constantViolations\n .concat(binding.referencePaths)\n // Check that every reference is contained within the function:\n .every((ref) => ref.findParent((parent) => parent === binding.path))\n }\n\n return true\n }\n return false\n}\n"],"names":["t"],"mappings":"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"}
package/dist/esm/ast.js CHANGED
@@ -1,11 +1,21 @@
1
1
  import * as babel from "@babel/core";
2
+ import _babelPluginJsx from "@babel/plugin-syntax-jsx";
3
+ import _babelPluginTypeScript from "@babel/plugin-syntax-typescript";
4
+ let babelPluginJsx = _babelPluginJsx;
5
+ let babelPluginTypeScript = _babelPluginTypeScript;
6
+ if (babelPluginJsx.default) {
7
+ babelPluginJsx = babelPluginJsx.default;
8
+ }
9
+ if (babelPluginTypeScript.default) {
10
+ babelPluginTypeScript = babelPluginTypeScript.default;
11
+ }
2
12
  function compileAst(makeOpts) {
3
13
  return async (opts) => {
4
14
  const res = babel.transformSync(opts.code, {
5
15
  plugins: [
6
- ["@babel/plugin-syntax-jsx", {}],
16
+ babelPluginJsx,
7
17
  [
8
- "@babel/plugin-syntax-typescript",
18
+ babelPluginTypeScript,
9
19
  {
10
20
  isTSX: true
11
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ast.js","sources":["../../src/ast.ts"],"sourcesContent":["import * as babel from '@babel/core'\n\nexport type CompileAstFn = (compileOpts: {\n code: string\n filename: string\n getBabelConfig: () => { plugins: Array<any> }\n}) => Promise<{\n code: string\n map: any\n}>\n\nexport function compileAst(makeOpts: { root: string }) {\n return async (opts: {\n code: string\n filename: string\n getBabelConfig: () => { plugins: Array<any> }\n }): Promise<{\n code: string\n map: any\n }> => {\n const res = babel.transformSync(opts.code, {\n plugins: [\n ['@babel/plugin-syntax-jsx', {}],\n [\n '@babel/plugin-syntax-typescript',\n {\n isTSX: true,\n },\n ],\n ...opts.getBabelConfig().plugins,\n ],\n root: makeOpts.root,\n filename: opts.filename,\n sourceMaps: true,\n })\n\n if (res?.code) {\n return {\n code: res.code,\n map: res.map,\n }\n }\n\n return {\n code: opts.code,\n map: null,\n }\n }\n}\n"],"names":[],"mappings":";AAWO,SAAS,WAAW,UAA4B;AACrD,SAAO,OAAO,SAOR;AACJ,UAAM,MAAM,MAAM,cAAc,KAAK,MAAM;AAAA,MACzC,SAAS;AAAA,QACP,CAAC,4BAA4B,CAAA,CAAE;AAAA,QAC/B;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA,GAAG,KAAK,eAAA,EAAiB;AAAA,MAC3B;AAAA,MACA,MAAM,SAAS;AAAA,MACf,UAAU,KAAK;AAAA,MACf,YAAY;AAAA,IAAA,CACb;AAED,QAAI,2BAAK,MAAM;AACN,aAAA;AAAA,QACL,MAAM,IAAI;AAAA,QACV,KAAK,IAAI;AAAA,MAAA;AAAA,IAEb;AAEO,WAAA;AAAA,MACL,MAAM,KAAK;AAAA,MACX,KAAK;AAAA,IAAA;AAAA,EACP;AAEJ;"}
1
+ {"version":3,"file":"ast.js","sources":["../../src/ast.ts"],"sourcesContent":["import * as babel from '@babel/core'\n// @ts-expect-error\nimport _babelPluginJsx from '@babel/plugin-syntax-jsx'\n// @ts-expect-error\nimport _babelPluginTypeScript from '@babel/plugin-syntax-typescript'\n\nlet babelPluginJsx = _babelPluginJsx\nlet babelPluginTypeScript = _babelPluginTypeScript\n\nif (babelPluginJsx.default) {\n babelPluginJsx = babelPluginJsx.default\n}\n\nif (babelPluginTypeScript.default) {\n babelPluginTypeScript = babelPluginTypeScript.default\n}\n\nexport type CompileAstFn = (compileOpts: {\n code: string\n filename: string\n getBabelConfig: () => { plugins: Array<any> }\n}) => Promise<{\n code: string\n map: any\n}>\n\nexport function compileAst(makeOpts: { root: string }) {\n return async (opts: {\n code: string\n filename: string\n getBabelConfig: () => { plugins: Array<any> }\n }): Promise<{\n code: string\n map: any\n }> => {\n const res = babel.transformSync(opts.code, {\n plugins: [\n babelPluginJsx,\n [\n babelPluginTypeScript,\n {\n isTSX: true,\n },\n ],\n ...opts.getBabelConfig().plugins,\n ],\n root: makeOpts.root,\n filename: opts.filename,\n sourceMaps: true,\n })\n\n if (res?.code) {\n return {\n code: res.code,\n map: res.map,\n }\n }\n\n return {\n code: opts.code,\n map: null,\n }\n }\n}\n"],"names":[],"mappings":";;;AAMA,IAAI,iBAAiB;AACrB,IAAI,wBAAwB;AAE5B,IAAI,eAAe,SAAS;AAC1B,mBAAiB,eAAe;AAClC;AAEA,IAAI,sBAAsB,SAAS;AACjC,0BAAwB,sBAAsB;AAChD;AAWO,SAAS,WAAW,UAA4B;AACrD,SAAO,OAAO,SAOR;AACJ,UAAM,MAAM,MAAM,cAAc,KAAK,MAAM;AAAA,MACzC,SAAS;AAAA,QACP;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA,GAAG,KAAK,eAAA,EAAiB;AAAA,MAC3B;AAAA,MACA,MAAM,SAAS;AAAA,MACf,UAAU,KAAK;AAAA,MACf,YAAY;AAAA,IAAA,CACb;AAED,QAAI,2BAAK,MAAM;AACN,aAAA;AAAA,QACL,MAAM,IAAI;AAAA,QACV,KAAK,IAAI;AAAA,MAAA;AAAA,IAEb;AAEO,WAAA;AAAA,MACL,MAAM,KAAK;AAAA,MACX,KAAK;AAAA,IAAA;AAAA,EACP;AAEJ;"}
@@ -38,78 +38,50 @@ const unpluginRouterCodeSplitterFactory = (options = {}, { framework }) => {
38
38
  const compiledAst = compileAst({
39
39
  root: ROOT
40
40
  });
41
- if (debug)
42
- console.info("Splitting route: ", id);
41
+ if (debug) console.info("Splitting route: ", id);
43
42
  const compiled = await splitFile({
44
43
  code,
45
44
  compileAst: compiledAst,
46
45
  filename: id
47
46
  });
48
- if (debug)
49
- console.info("");
50
- if (debug)
51
- console.info("Split Output");
52
- if (debug)
53
- console.info("");
54
- if (debug)
55
- console.info(compiled.code);
56
- if (debug)
57
- console.info("");
58
- if (debug)
59
- console.info("");
60
- if (debug)
61
- console.info("");
62
- if (debug)
63
- console.info("");
64
- if (debug)
65
- console.info("");
66
- if (debug)
67
- console.info("");
68
- if (debug)
69
- console.info("");
70
- if (debug)
71
- console.info("");
47
+ if (debug) console.info("");
48
+ if (debug) console.info("Split Output");
49
+ if (debug) console.info("");
50
+ if (debug) console.info(compiled.code);
51
+ if (debug) console.info("");
52
+ if (debug) console.info("");
53
+ if (debug) console.info("");
54
+ if (debug) console.info("");
55
+ if (debug) console.info("");
56
+ if (debug) console.info("");
57
+ if (debug) console.info("");
58
+ if (debug) console.info("");
72
59
  return compiled;
73
60
  };
74
61
  const handleCompilingFile = async (code, id) => {
75
62
  const compiledAst = compileAst({
76
63
  root: ROOT
77
64
  });
78
- if (debug)
79
- console.info("Handling createRoute: ", id);
65
+ if (debug) console.info("Handling createRoute: ", id);
80
66
  const compiled = await compileFile({
81
67
  code,
82
68
  compileAst: compiledAst,
83
69
  filename: id
84
70
  });
85
- if (debug)
86
- console.info("");
87
- if (debug)
88
- console.info("Compiled Output");
89
- if (debug)
90
- console.info("");
91
- if (debug)
92
- console.info(compiled.code);
93
- if (debug)
94
- console.info("");
95
- if (debug)
96
- console.info("");
97
- if (debug)
98
- console.info("");
99
- if (debug)
100
- console.info("");
101
- if (debug)
102
- console.info("");
103
- if (debug)
104
- console.info("");
105
- if (debug)
106
- console.info("");
107
- if (debug)
108
- console.info("");
109
- if (debug)
110
- console.info("");
111
- if (debug)
112
- console.info("");
71
+ if (debug) console.info("");
72
+ if (debug) console.info("Compiled Output");
73
+ if (debug) console.info("");
74
+ if (debug) console.info(compiled.code);
75
+ if (debug) console.info("");
76
+ if (debug) console.info("");
77
+ if (debug) console.info("");
78
+ if (debug) console.info("");
79
+ if (debug) console.info("");
80
+ if (debug) console.info("");
81
+ if (debug) console.info("");
82
+ if (debug) console.info("");
83
+ if (debug) console.info("");
84
+ if (debug) console.info("");
113
85
  return compiled;
114
86
  };
115
87
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"code-splitter.js","sources":["../../src/code-splitter.ts"],"sourcesContent":["import { isAbsolute, join } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\n\nimport { compileAst } from './ast'\nimport { compileFile, splitFile } from './compilers'\nimport { getConfig } from './config'\nimport { splitPrefix } from './constants'\n\nimport type { Config } from './config'\nimport type { UnpluginContextMeta, UnpluginFactory } from 'unplugin'\n\nfunction capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1)\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\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(externalPlugin: BannedBeforeExternalPlugin, framework: string) {\n super(`We detected that the '${externalPlugin.pkg}' was passed before '@tanstack/router-plugin'. Please make sure that '@tanstack/router-plugin' is passed before '${externalPlugin.pkg}' and try again: \ne.g.\nplugins: [\n TanStackRouter${capitalizeFirst(framework)}(), // 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> | undefined\n> = (options = {}, { framework }) => {\n const debug = Boolean(process.env.TSR_VITE_DEBUG)\n\n let ROOT: string = process.cwd()\n let userConfig = options as Config\n\n const handleSplittingFile = async (code: string, id: string) => {\n const compiledAst = compileAst({\n root: ROOT,\n })\n\n if (debug) console.info('Splitting route: ', id)\n\n const compiled = await splitFile({\n code,\n compileAst: compiledAst,\n filename: id,\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 }\n\n const handleCompilingFile = async (code: string, id: string) => {\n const compiledAst = compileAst({\n root: ROOT,\n })\n\n if (debug) console.info('Handling createRoute: ', id)\n\n const compiled = await compileFile({\n code,\n compileAst: compiledAst,\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 {\n name: 'router-code-splitter-plugin',\n enforce: 'pre',\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\n async transform(code, id) {\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 if (id.includes(splitPrefix)) {\n return await handleSplittingFile(code, id)\n } else if (\n fileIsInRoutesDirectory(id, userConfig.routesDirectory) &&\n (code.includes('createRoute(') || code.includes('createFileRoute('))\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 await handleCompilingFile(code, id)\n }\n\n return null\n },\n\n vite: {\n async configResolved(config) {\n ROOT = config.root\n userConfig = await getConfig(options, ROOT)\n },\n },\n\n async rspack(compiler) {\n userConfig = await getConfig(options, ROOT)\n },\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"code-splitter.js","sources":["../../src/code-splitter.ts"],"sourcesContent":["import { isAbsolute, join } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\n\nimport { compileAst } from './ast'\nimport { compileFile, splitFile } from './compilers'\nimport { getConfig } from './config'\nimport { splitPrefix } from './constants'\n\nimport type { Config } from './config'\nimport type { UnpluginContextMeta, UnpluginFactory } from 'unplugin'\n\nfunction capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1)\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\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(externalPlugin: BannedBeforeExternalPlugin, framework: string) {\n super(`We detected that the '${externalPlugin.pkg}' was passed before '@tanstack/router-plugin'. Please make sure that '@tanstack/router-plugin' is passed before '${externalPlugin.pkg}' and try again: \ne.g.\nplugins: [\n TanStackRouter${capitalizeFirst(framework)}(), // 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> | undefined\n> = (options = {}, { framework }) => {\n const debug = Boolean(process.env.TSR_VITE_DEBUG)\n\n let ROOT: string = process.cwd()\n let userConfig = options as Config\n\n const handleSplittingFile = async (code: string, id: string) => {\n const compiledAst = compileAst({\n root: ROOT,\n })\n\n if (debug) console.info('Splitting route: ', id)\n\n const compiled = await splitFile({\n code,\n compileAst: compiledAst,\n filename: id,\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 }\n\n const handleCompilingFile = async (code: string, id: string) => {\n const compiledAst = compileAst({\n root: ROOT,\n })\n\n if (debug) console.info('Handling createRoute: ', id)\n\n const compiled = await compileFile({\n code,\n compileAst: compiledAst,\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 {\n name: 'router-code-splitter-plugin',\n enforce: 'pre',\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\n async transform(code, id) {\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 if (id.includes(splitPrefix)) {\n return await handleSplittingFile(code, id)\n } else if (\n fileIsInRoutesDirectory(id, userConfig.routesDirectory) &&\n (code.includes('createRoute(') || code.includes('createFileRoute('))\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 await handleCompilingFile(code, id)\n }\n\n return null\n },\n\n vite: {\n async configResolved(config) {\n ROOT = config.root\n userConfig = await getConfig(options, ROOT)\n },\n },\n\n async rspack(compiler) {\n userConfig = await getConfig(options, ROOT)\n },\n }\n}\n"],"names":[],"mappings":"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"}
@@ -127,8 +127,7 @@ async function compileFile(opts) {
127
127
  if (existingCompImportPath || existingLoaderImportPath) {
128
128
  programPath.traverse({
129
129
  ImportDeclaration(path) {
130
- if (path.node.specifiers.length > 0)
131
- return;
130
+ if (path.node.specifiers.length > 0) return;
132
131
  if (path.node.source.value === existingCompImportPath || path.node.source.value === existingLoaderImportPath) {
133
132
  path.remove();
134
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compilers.js","sources":["../../src/compilers.ts"],"sourcesContent":["import * as t from '@babel/types'\nimport babel from '@babel/core'\nimport generate from '@babel/generator'\nimport * as template from '@babel/template'\nimport { splitPrefix } from './constants'\nimport { eliminateUnreferencedIdentifiers } from './eliminateUnreferencedIdentifiers'\nimport type { CompileAstFn } from './ast'\n\ntype SplitModulesById = Record<\n string,\n { id: string; node: t.FunctionExpression }\n>\n\ninterface State {\n filename: string\n opts: {\n minify: boolean\n root: string\n }\n imported: Record<string, boolean>\n refs: Set<any>\n serverIndex: number\n splitIndex: number\n splitModulesById: SplitModulesById\n}\n\nexport async function compileFile(opts: {\n code: string\n compileAst: CompileAstFn\n filename: string\n}) {\n return await opts.compileAst({\n code: opts.code,\n filename: opts.filename,\n getBabelConfig: () => ({\n plugins: [\n [\n {\n visitor: {\n Program: {\n enter(programPath: babel.NodePath<t.Program>, state: State) {\n const splitUrl = `${splitPrefix}:${opts.filename}?${splitPrefix}`\n\n /**\n * If the component for the route is being imported from\n * another file, this is to track the path to that file\n * the path itself doesn't matter, we just need to keep\n * track of it so that we can remove it from the imports\n * list if it's not being used like:\n *\n * `import '../shared/imported'`\n */\n let existingCompImportPath: string | null = null\n let existingLoaderImportPath: string | null = null\n\n programPath.traverse(\n {\n CallExpression: (path) => {\n if (!t.isIdentifier(path.node.callee)) {\n return\n }\n\n if (\n !(\n path.node.callee.name === 'createRoute' ||\n path.node.callee.name === 'createFileRoute'\n )\n ) {\n return\n }\n\n if (t.isCallExpression(path.parentPath.node)) {\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n let found = false\n\n const hasImportedOrDefinedIdentifier = (\n name: string,\n ) => {\n return programPath.scope.hasBinding(name)\n }\n\n if (t.isObjectExpression(options)) {\n options.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n if (t.isIdentifier(prop.key)) {\n if (prop.key.name === 'component') {\n const value = prop.value\n\n if (t.isIdentifier(value)) {\n existingCompImportPath =\n getImportSpecifierAndPathFromLocalName(\n programPath,\n value.name,\n ).path\n\n removeIdentifierLiteral(path, value)\n }\n\n // Prepend the import statement to the program along with the importer function\n // Check to see if lazyRouteComponent is already imported before attempting\n // to import it again\n\n if (\n !hasImportedOrDefinedIdentifier(\n 'lazyRouteComponent',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `import { lazyRouteComponent } from '@tanstack/react-router'`,\n )(),\n ])\n }\n\n if (\n !hasImportedOrDefinedIdentifier(\n '$$splitComponentImporter',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `const $$splitComponentImporter = () => import('${splitUrl}')`,\n )(),\n ])\n }\n\n prop.value = template.expression(\n `lazyRouteComponent($$splitComponentImporter, 'component')`,\n )()\n\n programPath.pushContainer('body', [\n template.statement(\n `function DummyComponent() { return null }`,\n )(),\n ])\n\n found = true\n } else if (prop.key.name === 'loader') {\n const value = prop.value\n\n if (t.isIdentifier(value)) {\n existingLoaderImportPath =\n getImportSpecifierAndPathFromLocalName(\n programPath,\n value.name,\n ).path\n\n removeIdentifierLiteral(path, value)\n }\n\n // Prepend the import statement to the program along with the importer function\n\n if (\n !hasImportedOrDefinedIdentifier('lazyFn')\n ) {\n programPath.unshiftContainer('body', [\n template.smart(\n `import { lazyFn } from '@tanstack/react-router'`,\n )() as t.Statement,\n ])\n }\n\n if (\n !hasImportedOrDefinedIdentifier(\n '$$splitLoaderImporter',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `const $$splitLoaderImporter = () => import('${splitUrl}')`,\n )(),\n ])\n }\n\n prop.value = template.expression(\n `lazyFn($$splitLoaderImporter, 'loader')`,\n )()\n\n found = true\n }\n }\n }\n\n programPath.scope.crawl()\n })\n }\n\n if (found as boolean) {\n programPath.pushContainer('body', [\n template.statement(\n `function TSR_Dummy_Component() {}`,\n )(),\n ])\n }\n }\n },\n },\n state,\n )\n\n eliminateUnreferencedIdentifiers(programPath)\n\n /**\n * If the component for the route is being imported,\n * and it's not being used, remove the import statement\n * from the program, by checking that the import has no\n * specifiers\n */\n if (\n (existingCompImportPath as string | null) ||\n (existingLoaderImportPath as string | null)\n ) {\n programPath.traverse({\n ImportDeclaration(path) {\n if (path.node.specifiers.length > 0) return\n if (\n path.node.source.value === existingCompImportPath ||\n path.node.source.value === existingLoaderImportPath\n ) {\n path.remove()\n }\n },\n })\n }\n },\n },\n },\n },\n {\n root: process.cwd(),\n minify: process.env.NODE_ENV === 'production',\n },\n ],\n ].filter(Boolean),\n }),\n })\n}\n\nfunction getImportSpecifierAndPathFromLocalName(\n programPath: babel.NodePath<t.Program>,\n name: string,\n): {\n specifier:\n | t.ImportSpecifier\n | t.ImportDefaultSpecifier\n | t.ImportNamespaceSpecifier\n | null\n path: string | null\n} {\n let specifier:\n | t.ImportSpecifier\n | t.ImportDefaultSpecifier\n | t.ImportNamespaceSpecifier\n | null = null\n let path: string | null = null\n\n programPath.traverse({\n ImportDeclaration(importPath) {\n const found = importPath.node.specifiers.find(\n (targetSpecifier) => targetSpecifier.local.name === name,\n )\n if (found) {\n specifier = found\n path = importPath.node.source.value\n }\n },\n })\n\n return { specifier, path }\n}\n\n// Reusable function to get literal value or resolve variable to literal\nfunction resolveIdentifier(path: any, node: any) {\n if (t.isIdentifier(node)) {\n const binding = path.scope.getBinding(node.name)\n if (\n binding\n // && binding.kind === 'const'\n ) {\n const declarator = binding.path.node\n if (t.isObjectExpression(declarator.init)) {\n return declarator.init\n } else if (t.isFunctionDeclaration(declarator.init)) {\n return declarator.init\n }\n }\n return undefined\n }\n\n return node\n}\n\nfunction removeIdentifierLiteral(path: any, node: any) {\n if (t.isIdentifier(node)) {\n const binding = path.scope.getBinding(node.name)\n if (binding) {\n binding.path.remove()\n }\n }\n}\n\nconst splitNodeTypes = ['component', 'loader'] as const\ntype SplitNodeType = (typeof splitNodeTypes)[number]\n\nexport async function splitFile(opts: {\n code: string\n compileAst: CompileAstFn\n filename: string\n}) {\n return await opts.compileAst({\n code: opts.code,\n filename: opts.filename,\n getBabelConfig: () => ({\n plugins: [\n [\n {\n visitor: {\n Program: {\n enter(programPath: babel.NodePath<t.Program>, state: State) {\n const splitNodesByType: Record<\n SplitNodeType,\n t.Node | undefined\n > = {\n component: undefined,\n loader: undefined,\n }\n\n // Find the node\n programPath.traverse(\n {\n CallExpression: (path) => {\n if (!t.isIdentifier(path.node.callee)) {\n return\n }\n\n if (\n !(\n path.node.callee.name === 'createRoute' ||\n path.node.callee.name === 'createFileRoute'\n )\n ) {\n return\n }\n\n if (t.isCallExpression(path.parentPath.node)) {\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n if (t.isObjectExpression(options)) {\n options.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n splitNodeTypes.forEach((type) => {\n if (t.isIdentifier(prop.key)) {\n if (prop.key.name === type) {\n splitNodesByType[type] = prop.value\n }\n }\n })\n }\n })\n\n // Remove all of the options\n options.properties = []\n }\n }\n },\n },\n state,\n )\n\n splitNodeTypes.forEach((splitType) => {\n let splitNode = splitNodesByType[splitType]\n\n if (!splitNode) {\n return\n }\n\n while (t.isIdentifier(splitNode)) {\n const binding = programPath.scope.getBinding(\n splitNode.name,\n )\n splitNode = binding?.path.node\n }\n\n // Add the node to the program\n if (splitNode) {\n if (t.isFunctionDeclaration(splitNode)) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n t.functionExpression(\n splitNode.id || null, // Anonymize the function expression\n splitNode.params,\n splitNode.body,\n splitNode.generator,\n splitNode.async,\n ),\n ),\n ]),\n )\n } else if (\n t.isFunctionExpression(splitNode) ||\n t.isArrowFunctionExpression(splitNode)\n ) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n splitNode as any,\n ),\n ]),\n )\n } else if (\n t.isImportSpecifier(splitNode) ||\n t.isImportDefaultSpecifier(splitNode)\n ) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n splitNode.local,\n ),\n ]),\n )\n } else if (t.isCallExpression(splitNode)) {\n const outputSplitNodeCode = generate(splitNode).code\n const splitNodeAst = babel.parse(outputSplitNodeCode)\n\n if (!splitNodeAst) {\n throw new Error(\n `Failed to parse the generated code for \"${splitType}\" in the node type \"${splitNode.type}\"`,\n )\n }\n\n const statement = splitNodeAst.program.body[0]\n\n if (!statement) {\n throw new Error(\n `Failed to parse the generated code for \"${splitType}\" in the node type \"${splitNode.type}\" as no statement was found in the program body`,\n )\n }\n\n if (t.isExpressionStatement(statement)) {\n const expression = statement.expression\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n expression,\n ),\n ]),\n )\n } else {\n throw new Error(\n `Unexpected expression type encounter for \"${splitType}\" in the node type \"${splitNode.type}\"`,\n )\n }\n } else {\n console.info('Unexpected splitNode type:', splitNode)\n throw new Error(\n `Unexpected splitNode type ☝️: ${splitNode.type}`,\n )\n }\n }\n\n // If the splitNode exists at the top of the program\n // then we need to remove that copy\n programPath.node.body = programPath.node.body.filter(\n (node) => {\n return node !== splitNode\n },\n )\n\n // Export the node\n programPath.pushContainer('body', [\n t.exportNamedDeclaration(null, [\n t.exportSpecifier(\n t.identifier(splitType),\n t.identifier(splitType),\n ),\n ]),\n ])\n })\n\n // convert exports to imports from the original file\n programPath.traverse({\n ExportNamedDeclaration(path) {\n // e.g. export const x = 1 or export { x }\n // becomes\n // import { x } from '${opts.id}'\n\n if (path.node.declaration) {\n if (t.isVariableDeclaration(path.node.declaration)) {\n path.replaceWith(\n t.importDeclaration(\n path.node.declaration.declarations.map((decl) =>\n t.importSpecifier(\n t.identifier((decl.id as any).name),\n t.identifier((decl.id as any).name),\n ),\n ),\n t.stringLiteral(\n opts.filename.split(\n `?${splitPrefix}`,\n )[0] as string,\n ),\n ),\n )\n }\n }\n },\n })\n\n eliminateUnreferencedIdentifiers(programPath)\n },\n },\n },\n },\n {\n root: process.cwd(),\n minify: process.env.NODE_ENV === 'production',\n },\n ],\n ].filter(Boolean),\n }),\n })\n}\n"],"names":["babel"],"mappings":"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"}
1
+ {"version":3,"file":"compilers.js","sources":["../../src/compilers.ts"],"sourcesContent":["import * as t from '@babel/types'\nimport babel from '@babel/core'\nimport generate from '@babel/generator'\nimport * as template from '@babel/template'\nimport { splitPrefix } from './constants'\nimport { eliminateUnreferencedIdentifiers } from './eliminateUnreferencedIdentifiers'\nimport type { CompileAstFn } from './ast'\n\ntype SplitModulesById = Record<\n string,\n { id: string; node: t.FunctionExpression }\n>\n\ninterface State {\n filename: string\n opts: {\n minify: boolean\n root: string\n }\n imported: Record<string, boolean>\n refs: Set<any>\n serverIndex: number\n splitIndex: number\n splitModulesById: SplitModulesById\n}\n\nexport async function compileFile(opts: {\n code: string\n compileAst: CompileAstFn\n filename: string\n}) {\n return await opts.compileAst({\n code: opts.code,\n filename: opts.filename,\n getBabelConfig: () => ({\n plugins: [\n [\n {\n visitor: {\n Program: {\n enter(programPath: babel.NodePath<t.Program>, state: State) {\n const splitUrl = `${splitPrefix}:${opts.filename}?${splitPrefix}`\n\n /**\n * If the component for the route is being imported from\n * another file, this is to track the path to that file\n * the path itself doesn't matter, we just need to keep\n * track of it so that we can remove it from the imports\n * list if it's not being used like:\n *\n * `import '../shared/imported'`\n */\n let existingCompImportPath: string | null = null\n let existingLoaderImportPath: string | null = null\n\n programPath.traverse(\n {\n CallExpression: (path) => {\n if (!t.isIdentifier(path.node.callee)) {\n return\n }\n\n if (\n !(\n path.node.callee.name === 'createRoute' ||\n path.node.callee.name === 'createFileRoute'\n )\n ) {\n return\n }\n\n if (t.isCallExpression(path.parentPath.node)) {\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n let found = false\n\n const hasImportedOrDefinedIdentifier = (\n name: string,\n ) => {\n return programPath.scope.hasBinding(name)\n }\n\n if (t.isObjectExpression(options)) {\n options.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n if (t.isIdentifier(prop.key)) {\n if (prop.key.name === 'component') {\n const value = prop.value\n\n if (t.isIdentifier(value)) {\n existingCompImportPath =\n getImportSpecifierAndPathFromLocalName(\n programPath,\n value.name,\n ).path\n\n removeIdentifierLiteral(path, value)\n }\n\n // Prepend the import statement to the program along with the importer function\n // Check to see if lazyRouteComponent is already imported before attempting\n // to import it again\n\n if (\n !hasImportedOrDefinedIdentifier(\n 'lazyRouteComponent',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `import { lazyRouteComponent } from '@tanstack/react-router'`,\n )(),\n ])\n }\n\n if (\n !hasImportedOrDefinedIdentifier(\n '$$splitComponentImporter',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `const $$splitComponentImporter = () => import('${splitUrl}')`,\n )(),\n ])\n }\n\n prop.value = template.expression(\n `lazyRouteComponent($$splitComponentImporter, 'component')`,\n )()\n\n programPath.pushContainer('body', [\n template.statement(\n `function DummyComponent() { return null }`,\n )(),\n ])\n\n found = true\n } else if (prop.key.name === 'loader') {\n const value = prop.value\n\n if (t.isIdentifier(value)) {\n existingLoaderImportPath =\n getImportSpecifierAndPathFromLocalName(\n programPath,\n value.name,\n ).path\n\n removeIdentifierLiteral(path, value)\n }\n\n // Prepend the import statement to the program along with the importer function\n\n if (\n !hasImportedOrDefinedIdentifier('lazyFn')\n ) {\n programPath.unshiftContainer('body', [\n template.smart(\n `import { lazyFn } from '@tanstack/react-router'`,\n )() as t.Statement,\n ])\n }\n\n if (\n !hasImportedOrDefinedIdentifier(\n '$$splitLoaderImporter',\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `const $$splitLoaderImporter = () => import('${splitUrl}')`,\n )(),\n ])\n }\n\n prop.value = template.expression(\n `lazyFn($$splitLoaderImporter, 'loader')`,\n )()\n\n found = true\n }\n }\n }\n\n programPath.scope.crawl()\n })\n }\n\n if (found as boolean) {\n programPath.pushContainer('body', [\n template.statement(\n `function TSR_Dummy_Component() {}`,\n )(),\n ])\n }\n }\n },\n },\n state,\n )\n\n eliminateUnreferencedIdentifiers(programPath)\n\n /**\n * If the component for the route is being imported,\n * and it's not being used, remove the import statement\n * from the program, by checking that the import has no\n * specifiers\n */\n if (\n (existingCompImportPath as string | null) ||\n (existingLoaderImportPath as string | null)\n ) {\n programPath.traverse({\n ImportDeclaration(path) {\n if (path.node.specifiers.length > 0) return\n if (\n path.node.source.value === existingCompImportPath ||\n path.node.source.value === existingLoaderImportPath\n ) {\n path.remove()\n }\n },\n })\n }\n },\n },\n },\n },\n {\n root: process.cwd(),\n minify: process.env.NODE_ENV === 'production',\n },\n ],\n ].filter(Boolean),\n }),\n })\n}\n\nfunction getImportSpecifierAndPathFromLocalName(\n programPath: babel.NodePath<t.Program>,\n name: string,\n): {\n specifier:\n | t.ImportSpecifier\n | t.ImportDefaultSpecifier\n | t.ImportNamespaceSpecifier\n | null\n path: string | null\n} {\n let specifier:\n | t.ImportSpecifier\n | t.ImportDefaultSpecifier\n | t.ImportNamespaceSpecifier\n | null = null\n let path: string | null = null\n\n programPath.traverse({\n ImportDeclaration(importPath) {\n const found = importPath.node.specifiers.find(\n (targetSpecifier) => targetSpecifier.local.name === name,\n )\n if (found) {\n specifier = found\n path = importPath.node.source.value\n }\n },\n })\n\n return { specifier, path }\n}\n\n// Reusable function to get literal value or resolve variable to literal\nfunction resolveIdentifier(path: any, node: any) {\n if (t.isIdentifier(node)) {\n const binding = path.scope.getBinding(node.name)\n if (\n binding\n // && binding.kind === 'const'\n ) {\n const declarator = binding.path.node\n if (t.isObjectExpression(declarator.init)) {\n return declarator.init\n } else if (t.isFunctionDeclaration(declarator.init)) {\n return declarator.init\n }\n }\n return undefined\n }\n\n return node\n}\n\nfunction removeIdentifierLiteral(path: any, node: any) {\n if (t.isIdentifier(node)) {\n const binding = path.scope.getBinding(node.name)\n if (binding) {\n binding.path.remove()\n }\n }\n}\n\nconst splitNodeTypes = ['component', 'loader'] as const\ntype SplitNodeType = (typeof splitNodeTypes)[number]\n\nexport async function splitFile(opts: {\n code: string\n compileAst: CompileAstFn\n filename: string\n}) {\n return await opts.compileAst({\n code: opts.code,\n filename: opts.filename,\n getBabelConfig: () => ({\n plugins: [\n [\n {\n visitor: {\n Program: {\n enter(programPath: babel.NodePath<t.Program>, state: State) {\n const splitNodesByType: Record<\n SplitNodeType,\n t.Node | undefined\n > = {\n component: undefined,\n loader: undefined,\n }\n\n // Find the node\n programPath.traverse(\n {\n CallExpression: (path) => {\n if (!t.isIdentifier(path.node.callee)) {\n return\n }\n\n if (\n !(\n path.node.callee.name === 'createRoute' ||\n path.node.callee.name === 'createFileRoute'\n )\n ) {\n return\n }\n\n if (t.isCallExpression(path.parentPath.node)) {\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n if (t.isObjectExpression(options)) {\n options.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n splitNodeTypes.forEach((type) => {\n if (t.isIdentifier(prop.key)) {\n if (prop.key.name === type) {\n splitNodesByType[type] = prop.value\n }\n }\n })\n }\n })\n\n // Remove all of the options\n options.properties = []\n }\n }\n },\n },\n state,\n )\n\n splitNodeTypes.forEach((splitType) => {\n let splitNode = splitNodesByType[splitType]\n\n if (!splitNode) {\n return\n }\n\n while (t.isIdentifier(splitNode)) {\n const binding = programPath.scope.getBinding(\n splitNode.name,\n )\n splitNode = binding?.path.node\n }\n\n // Add the node to the program\n if (splitNode) {\n if (t.isFunctionDeclaration(splitNode)) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n t.functionExpression(\n splitNode.id || null, // Anonymize the function expression\n splitNode.params,\n splitNode.body,\n splitNode.generator,\n splitNode.async,\n ),\n ),\n ]),\n )\n } else if (\n t.isFunctionExpression(splitNode) ||\n t.isArrowFunctionExpression(splitNode)\n ) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n splitNode as any,\n ),\n ]),\n )\n } else if (\n t.isImportSpecifier(splitNode) ||\n t.isImportDefaultSpecifier(splitNode)\n ) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n splitNode.local,\n ),\n ]),\n )\n } else if (t.isCallExpression(splitNode)) {\n const outputSplitNodeCode = generate(splitNode).code\n const splitNodeAst = babel.parse(outputSplitNodeCode)\n\n if (!splitNodeAst) {\n throw new Error(\n `Failed to parse the generated code for \"${splitType}\" in the node type \"${splitNode.type}\"`,\n )\n }\n\n const statement = splitNodeAst.program.body[0]\n\n if (!statement) {\n throw new Error(\n `Failed to parse the generated code for \"${splitType}\" in the node type \"${splitNode.type}\" as no statement was found in the program body`,\n )\n }\n\n if (t.isExpressionStatement(statement)) {\n const expression = statement.expression\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitType),\n expression,\n ),\n ]),\n )\n } else {\n throw new Error(\n `Unexpected expression type encounter for \"${splitType}\" in the node type \"${splitNode.type}\"`,\n )\n }\n } else {\n console.info('Unexpected splitNode type:', splitNode)\n throw new Error(\n `Unexpected splitNode type ☝️: ${splitNode.type}`,\n )\n }\n }\n\n // If the splitNode exists at the top of the program\n // then we need to remove that copy\n programPath.node.body = programPath.node.body.filter(\n (node) => {\n return node !== splitNode\n },\n )\n\n // Export the node\n programPath.pushContainer('body', [\n t.exportNamedDeclaration(null, [\n t.exportSpecifier(\n t.identifier(splitType),\n t.identifier(splitType),\n ),\n ]),\n ])\n })\n\n // convert exports to imports from the original file\n programPath.traverse({\n ExportNamedDeclaration(path) {\n // e.g. export const x = 1 or export { x }\n // becomes\n // import { x } from '${opts.id}'\n\n if (path.node.declaration) {\n if (t.isVariableDeclaration(path.node.declaration)) {\n path.replaceWith(\n t.importDeclaration(\n path.node.declaration.declarations.map((decl) =>\n t.importSpecifier(\n t.identifier((decl.id as any).name),\n t.identifier((decl.id as any).name),\n ),\n ),\n t.stringLiteral(\n opts.filename.split(\n `?${splitPrefix}`,\n )[0] as string,\n ),\n ),\n )\n }\n }\n },\n })\n\n eliminateUnreferencedIdentifiers(programPath)\n },\n },\n },\n },\n {\n root: process.cwd(),\n minify: process.env.NODE_ENV === 'production',\n },\n ],\n ].filter(Boolean),\n }),\n })\n}\n"],"names":["babel"],"mappings":"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"}
@@ -2,8 +2,7 @@ import * as t from "@babel/types";
2
2
  const eliminateUnreferencedIdentifiers = (programPath, refs) => {
3
3
  let referencesRemovedInThisPass;
4
4
  const shouldBeRemoved = (ident) => {
5
- if (isIdentifierReferenced(ident))
6
- return false;
5
+ if (isIdentifierReferenced(ident)) return false;
7
6
  return true;
8
7
  };
9
8
  const sweepFunction = (path) => {
@@ -1 +1 @@
1
- {"version":3,"file":"eliminateUnreferencedIdentifiers.js","sources":["../../src/eliminateUnreferencedIdentifiers.ts"],"sourcesContent":["// Copied from https://github.com/pcattori/vite-env-only/blob/main/src/dce.ts\n// Adapted with some minor changes for the purpose of this project\n\nimport * as t from '@babel/types'\nimport type { types as BabelTypes } from '@babel/core'\nimport type { NodePath } from '@babel/traverse'\n\ntype IdentifierPath = NodePath<BabelTypes.Identifier>\n\n/**\n * @param refs - If provided, only these identifiers will be considered for removal.\n */\nexport const eliminateUnreferencedIdentifiers = (\n programPath: NodePath<BabelTypes.Program>,\n refs?: Set<IdentifierPath>,\n) => {\n let referencesRemovedInThisPass: number\n\n const shouldBeRemoved = (ident: IdentifierPath) => {\n if (isIdentifierReferenced(ident)) return false\n if (!refs) return true\n return refs.has(ident)\n }\n\n const sweepFunction = (\n path: NodePath<\n | BabelTypes.FunctionDeclaration\n | BabelTypes.FunctionExpression\n | BabelTypes.ArrowFunctionExpression\n >,\n ) => {\n const identifier = getIdentifier(path)\n if (identifier?.node && shouldBeRemoved(identifier)) {\n ++referencesRemovedInThisPass\n\n if (\n t.isAssignmentExpression(path.parentPath.node) ||\n t.isVariableDeclarator(path.parentPath.node)\n ) {\n path.parentPath.remove()\n } else {\n path.remove()\n }\n }\n }\n\n const sweepImport = (\n path: NodePath<\n | BabelTypes.ImportSpecifier\n | BabelTypes.ImportDefaultSpecifier\n | BabelTypes.ImportNamespaceSpecifier\n >,\n ) => {\n const local = path.get('local')\n if (shouldBeRemoved(local)) {\n ++referencesRemovedInThisPass\n path.remove()\n if (\n (path.parent as BabelTypes.ImportDeclaration).specifiers.length === 0\n ) {\n path.parentPath.remove()\n }\n }\n }\n\n const handleObjectPattern = (pattern: NodePath<BabelTypes.ObjectPattern>) => {\n const properties = pattern.get('properties')\n properties.forEach((property) => {\n if (property.node.type === 'ObjectProperty') {\n const value = property.get('value') as any\n if (t.isIdentifier(value)) {\n if (shouldBeRemoved(value as any)) {\n property.remove()\n }\n } else if (t.isObjectPattern(value)) {\n handleObjectPattern(value as any)\n }\n } else if (t.isRestElement(property.node)) {\n const argument = property.get('argument')\n if (\n t.isIdentifier(argument as any) &&\n shouldBeRemoved(argument as NodePath<BabelTypes.Identifier>)\n ) {\n property.remove()\n }\n }\n })\n }\n\n // Traverse again to remove unused references. This happens at least once,\n // then repeats until no more references are removed.\n do {\n referencesRemovedInThisPass = 0\n\n programPath.scope.crawl()\n\n programPath.traverse({\n VariableDeclarator(path) {\n if (path.node.id.type === 'Identifier') {\n const local = path.get('id') as NodePath<BabelTypes.Identifier>\n if (shouldBeRemoved(local)) {\n ++referencesRemovedInThisPass\n path.remove()\n }\n } else if (path.node.id.type === 'ObjectPattern') {\n handleObjectPattern(\n path.get('id') as NodePath<BabelTypes.ObjectPattern>,\n )\n } else if (path.node.id.type === 'ArrayPattern') {\n const pattern = path.get('id') as NodePath<BabelTypes.ArrayPattern>\n\n let hasRemoved = false as boolean\n\n pattern.get('elements').forEach((element, index) => {\n // if (!element) return // Skip holes in the pattern\n\n let identifierPath: NodePath<BabelTypes.Identifier>\n\n if (t.isIdentifier(element.node)) {\n identifierPath = element as NodePath<BabelTypes.Identifier>\n } else if (t.isRestElement(element.node)) {\n identifierPath = element.get(\n 'argument',\n ) as NodePath<BabelTypes.Identifier>\n } else {\n // For now, ignore other types like AssignmentPattern\n return\n }\n\n if (shouldBeRemoved(identifierPath)) {\n hasRemoved = true\n pattern.node.elements[index] = null // Remove the element by setting it to null\n }\n })\n\n // If any elements were removed and no elements are left, remove the entire declaration\n if (\n hasRemoved &&\n pattern.node.elements.every((element) => element === null)\n ) {\n path.remove()\n ++referencesRemovedInThisPass\n }\n }\n },\n FunctionDeclaration: sweepFunction,\n FunctionExpression: sweepFunction,\n ArrowFunctionExpression: sweepFunction,\n ImportSpecifier: sweepImport,\n ImportDefaultSpecifier: sweepImport,\n ImportNamespaceSpecifier: sweepImport,\n })\n } while (referencesRemovedInThisPass)\n}\n\nfunction getIdentifier(\n path: NodePath<\n | BabelTypes.FunctionDeclaration\n | BabelTypes.FunctionExpression\n | BabelTypes.ArrowFunctionExpression\n >,\n): NodePath<BabelTypes.Identifier> | null {\n const parentPath = path.parentPath\n if (parentPath.type === 'VariableDeclarator') {\n const variablePath = parentPath as NodePath<BabelTypes.VariableDeclarator>\n const name = variablePath.get('id')\n return name.node.type === 'Identifier'\n ? (name as NodePath<BabelTypes.Identifier>)\n : null\n }\n\n if (parentPath.type === 'AssignmentExpression') {\n const variablePath = parentPath as NodePath<BabelTypes.AssignmentExpression>\n const name = variablePath.get('left')\n return name.node.type === 'Identifier'\n ? (name as NodePath<BabelTypes.Identifier>)\n : null\n }\n\n if (path.node.type === 'ArrowFunctionExpression') {\n return null\n }\n\n if (path.node.type === 'FunctionExpression') {\n return null\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return path.node.id && path.node.id.type === 'Identifier'\n ? (path.get('id') as NodePath<BabelTypes.Identifier>)\n : null\n}\n\nfunction isIdentifierReferenced(\n ident: NodePath<BabelTypes.Identifier>,\n): boolean {\n const binding = ident.scope.getBinding(ident.node.name)\n if (binding?.referenced) {\n // Functions can reference themselves, so we need to check if there's a\n // binding outside the function scope or not.\n if (binding.path.type === 'FunctionDeclaration') {\n return !binding.constantViolations\n .concat(binding.referencePaths)\n // Check that every reference is contained within the function:\n .every((ref) => ref.findParent((parent) => parent === binding.path))\n }\n\n return true\n }\n return false\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eliminateUnreferencedIdentifiers.js","sources":["../../src/eliminateUnreferencedIdentifiers.ts"],"sourcesContent":["// Copied from https://github.com/pcattori/vite-env-only/blob/main/src/dce.ts\n// Adapted with some minor changes for the purpose of this project\n\nimport * as t from '@babel/types'\nimport type { types as BabelTypes } from '@babel/core'\nimport type { NodePath } from '@babel/traverse'\n\ntype IdentifierPath = NodePath<BabelTypes.Identifier>\n\n/**\n * @param refs - If provided, only these identifiers will be considered for removal.\n */\nexport const eliminateUnreferencedIdentifiers = (\n programPath: NodePath<BabelTypes.Program>,\n refs?: Set<IdentifierPath>,\n) => {\n let referencesRemovedInThisPass: number\n\n const shouldBeRemoved = (ident: IdentifierPath) => {\n if (isIdentifierReferenced(ident)) return false\n if (!refs) return true\n return refs.has(ident)\n }\n\n const sweepFunction = (\n path: NodePath<\n | BabelTypes.FunctionDeclaration\n | BabelTypes.FunctionExpression\n | BabelTypes.ArrowFunctionExpression\n >,\n ) => {\n const identifier = getIdentifier(path)\n if (identifier?.node && shouldBeRemoved(identifier)) {\n ++referencesRemovedInThisPass\n\n if (\n t.isAssignmentExpression(path.parentPath.node) ||\n t.isVariableDeclarator(path.parentPath.node)\n ) {\n path.parentPath.remove()\n } else {\n path.remove()\n }\n }\n }\n\n const sweepImport = (\n path: NodePath<\n | BabelTypes.ImportSpecifier\n | BabelTypes.ImportDefaultSpecifier\n | BabelTypes.ImportNamespaceSpecifier\n >,\n ) => {\n const local = path.get('local')\n if (shouldBeRemoved(local)) {\n ++referencesRemovedInThisPass\n path.remove()\n if (\n (path.parent as BabelTypes.ImportDeclaration).specifiers.length === 0\n ) {\n path.parentPath.remove()\n }\n }\n }\n\n const handleObjectPattern = (pattern: NodePath<BabelTypes.ObjectPattern>) => {\n const properties = pattern.get('properties')\n properties.forEach((property) => {\n if (property.node.type === 'ObjectProperty') {\n const value = property.get('value') as any\n if (t.isIdentifier(value)) {\n if (shouldBeRemoved(value as any)) {\n property.remove()\n }\n } else if (t.isObjectPattern(value)) {\n handleObjectPattern(value as any)\n }\n } else if (t.isRestElement(property.node)) {\n const argument = property.get('argument')\n if (\n t.isIdentifier(argument as any) &&\n shouldBeRemoved(argument as NodePath<BabelTypes.Identifier>)\n ) {\n property.remove()\n }\n }\n })\n }\n\n // Traverse again to remove unused references. This happens at least once,\n // then repeats until no more references are removed.\n do {\n referencesRemovedInThisPass = 0\n\n programPath.scope.crawl()\n\n programPath.traverse({\n VariableDeclarator(path) {\n if (path.node.id.type === 'Identifier') {\n const local = path.get('id') as NodePath<BabelTypes.Identifier>\n if (shouldBeRemoved(local)) {\n ++referencesRemovedInThisPass\n path.remove()\n }\n } else if (path.node.id.type === 'ObjectPattern') {\n handleObjectPattern(\n path.get('id') as NodePath<BabelTypes.ObjectPattern>,\n )\n } else if (path.node.id.type === 'ArrayPattern') {\n const pattern = path.get('id') as NodePath<BabelTypes.ArrayPattern>\n\n let hasRemoved = false as boolean\n\n pattern.get('elements').forEach((element, index) => {\n // if (!element) return // Skip holes in the pattern\n\n let identifierPath: NodePath<BabelTypes.Identifier>\n\n if (t.isIdentifier(element.node)) {\n identifierPath = element as NodePath<BabelTypes.Identifier>\n } else if (t.isRestElement(element.node)) {\n identifierPath = element.get(\n 'argument',\n ) as NodePath<BabelTypes.Identifier>\n } else {\n // For now, ignore other types like AssignmentPattern\n return\n }\n\n if (shouldBeRemoved(identifierPath)) {\n hasRemoved = true\n pattern.node.elements[index] = null // Remove the element by setting it to null\n }\n })\n\n // If any elements were removed and no elements are left, remove the entire declaration\n if (\n hasRemoved &&\n pattern.node.elements.every((element) => element === null)\n ) {\n path.remove()\n ++referencesRemovedInThisPass\n }\n }\n },\n FunctionDeclaration: sweepFunction,\n FunctionExpression: sweepFunction,\n ArrowFunctionExpression: sweepFunction,\n ImportSpecifier: sweepImport,\n ImportDefaultSpecifier: sweepImport,\n ImportNamespaceSpecifier: sweepImport,\n })\n } while (referencesRemovedInThisPass)\n}\n\nfunction getIdentifier(\n path: NodePath<\n | BabelTypes.FunctionDeclaration\n | BabelTypes.FunctionExpression\n | BabelTypes.ArrowFunctionExpression\n >,\n): NodePath<BabelTypes.Identifier> | null {\n const parentPath = path.parentPath\n if (parentPath.type === 'VariableDeclarator') {\n const variablePath = parentPath as NodePath<BabelTypes.VariableDeclarator>\n const name = variablePath.get('id')\n return name.node.type === 'Identifier'\n ? (name as NodePath<BabelTypes.Identifier>)\n : null\n }\n\n if (parentPath.type === 'AssignmentExpression') {\n const variablePath = parentPath as NodePath<BabelTypes.AssignmentExpression>\n const name = variablePath.get('left')\n return name.node.type === 'Identifier'\n ? (name as NodePath<BabelTypes.Identifier>)\n : null\n }\n\n if (path.node.type === 'ArrowFunctionExpression') {\n return null\n }\n\n if (path.node.type === 'FunctionExpression') {\n return null\n }\n\n // eslint-disable-next-line ts/no-unnecessary-condition\n return path.node.id && path.node.id.type === 'Identifier'\n ? (path.get('id') as NodePath<BabelTypes.Identifier>)\n : null\n}\n\nfunction isIdentifierReferenced(\n ident: NodePath<BabelTypes.Identifier>,\n): boolean {\n const binding = ident.scope.getBinding(ident.node.name)\n if (binding?.referenced) {\n // Functions can reference themselves, so we need to check if there's a\n // binding outside the function scope or not.\n if (binding.path.type === 'FunctionDeclaration') {\n return !binding.constantViolations\n .concat(binding.referencePaths)\n // Check that every reference is contained within the function:\n .every((ref) => ref.findParent((parent) => parent === binding.path))\n }\n\n return true\n }\n return false\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/router-plugin",
3
- "version": "1.40.3",
3
+ "version": "1.41.0",
4
4
  "description": "",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -67,7 +67,7 @@
67
67
  ],
68
68
  "peerDependencies": {
69
69
  "@rsbuild/core": ">=0.7.9",
70
- "vite": ">=5"
70
+ "vite": ">=5.0.13"
71
71
  },
72
72
  "peerDependenciesMeta": {
73
73
  "vite": {
@@ -82,8 +82,6 @@
82
82
  "@babel/generator": "^7.24.7",
83
83
  "@babel/plugin-syntax-jsx": "^7.24.7",
84
84
  "@babel/plugin-syntax-typescript": "^7.24.7",
85
- "@babel/plugin-transform-react-jsx": "^7.24.7",
86
- "@babel/plugin-transform-typescript": "^7.24.7",
87
85
  "@babel/template": "^7.24.7",
88
86
  "@babel/traverse": "^7.24.7",
89
87
  "@babel/types": "^7.24.7",
@@ -93,7 +91,10 @@
93
91
  "@types/babel__traverse": "^7.20.6",
94
92
  "unplugin": "^1.10.1",
95
93
  "zod": "^3.22.4",
96
- "@tanstack/router-generator": "^1.40.3"
94
+ "@tanstack/router-generator": "^1.41.0"
95
+ },
96
+ "devDependencies": {
97
+ "vite": "^5.3.1"
97
98
  },
98
99
  "scripts": {}
99
100
  }
package/src/ast.ts CHANGED
@@ -1,4 +1,19 @@
1
1
  import * as babel from '@babel/core'
2
+ // @ts-expect-error
3
+ import _babelPluginJsx from '@babel/plugin-syntax-jsx'
4
+ // @ts-expect-error
5
+ import _babelPluginTypeScript from '@babel/plugin-syntax-typescript'
6
+
7
+ let babelPluginJsx = _babelPluginJsx
8
+ let babelPluginTypeScript = _babelPluginTypeScript
9
+
10
+ if (babelPluginJsx.default) {
11
+ babelPluginJsx = babelPluginJsx.default
12
+ }
13
+
14
+ if (babelPluginTypeScript.default) {
15
+ babelPluginTypeScript = babelPluginTypeScript.default
16
+ }
2
17
 
3
18
  export type CompileAstFn = (compileOpts: {
4
19
  code: string
@@ -20,9 +35,9 @@ export function compileAst(makeOpts: { root: string }) {
20
35
  }> => {
21
36
  const res = babel.transformSync(opts.code, {
22
37
  plugins: [
23
- ['@babel/plugin-syntax-jsx', {}],
38
+ babelPluginJsx,
24
39
  [
25
- '@babel/plugin-syntax-typescript',
40
+ babelPluginTypeScript,
26
41
  {
27
42
  isTSX: true,
28
43
  },
@@ -185,7 +185,7 @@ function getIdentifier(
185
185
  return null
186
186
  }
187
187
 
188
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
188
+ // eslint-disable-next-line ts/no-unnecessary-condition
189
189
  return path.node.id && path.node.id.type === 'Identifier'
190
190
  ? (path.get('id') as NodePath<BabelTypes.Identifier>)
191
191
  : null