@tanstack/router-plugin
Version:
Modern and scalable routing for React applications
1 lines • 83.8 kB
Source Map (JSON)
{"version":3,"file":"compilers.cjs","names":[],"sources":["../../../../src/core/code-splitter/compilers.ts"],"sourcesContent":["import * as t from '@babel/types'\nimport * as babel from '@babel/core'\nimport * as template from '@babel/template'\nimport {\n buildDeclarationMap,\n buildDependencyGraph,\n collectIdentifiersFromPattern,\n collectLocalBindingsFromStatement,\n collectModuleLevelRefsFromNode,\n createIdentifier,\n deadCodeElimination,\n expandDestructuredDeclarations,\n expandSharedDestructuredDeclarators,\n expandTransitively,\n findReferencedIdentifiers,\n generateFromAst,\n parseAst,\n removeBindingsTransitivelyDependingOn,\n retainModuleLevelDeclarations,\n stripUnreferencedTopLevelExpressionStatements,\n unwrapExportedDeclarations,\n} from '@tanstack/router-utils'\nimport { tsrShared, tsrSplit } from '../constants'\nimport { createRouteHmrStatement } from '../hmr'\nimport { getObjectPropertyKeyName } from '../utils'\nimport { getFrameworkOptions } from './framework-options'\nimport type {\n CodeSplitCompilerPlugin,\n CompileCodeSplitReferenceRouteOptions,\n} from './plugins'\nimport type { GeneratorResult, ParseAstOptions } from '@tanstack/router-utils'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from '../constants'\nimport type { SplitNodeMeta } from './types'\n\nexport {\n buildDeclarationMap,\n buildDependencyGraph,\n collectIdentifiersFromNode,\n collectLocalBindingsFromStatement,\n collectModuleLevelRefsFromNode,\n expandDestructuredDeclarations,\n expandSharedDestructuredDeclarators,\n expandTransitively,\n removeBindingsTransitivelyDependingOn,\n} from '@tanstack/router-utils'\n\nexport function removeBindingsDependingOnRoute(\n bindings: Set<string>,\n dependencyGraph: Map<string, Set<string>>,\n) {\n removeBindingsTransitivelyDependingOn(bindings, dependencyGraph, ['Route'])\n}\n\nconst SPLIT_NODES_CONFIG = new Map<SplitRouteIdentNodes, SplitNodeMeta>([\n [\n 'loader',\n {\n routeIdent: 'loader',\n localImporterIdent: '$$splitLoaderImporter', // const $$splitLoaderImporter = () => import('...')\n splitStrategy: 'lazyFn',\n localExporterIdent: 'SplitLoader', // const SplitLoader = ...\n exporterIdent: 'loader', // export { SplitLoader as loader }\n },\n ],\n [\n 'component',\n {\n routeIdent: 'component',\n localImporterIdent: '$$splitComponentImporter', // const $$splitComponentImporter = () => import('...')\n splitStrategy: 'lazyRouteComponent',\n localExporterIdent: 'SplitComponent', // const SplitComponent = ...\n exporterIdent: 'component', // export { SplitComponent as component }\n },\n ],\n [\n 'pendingComponent',\n {\n routeIdent: 'pendingComponent',\n localImporterIdent: '$$splitPendingComponentImporter', // const $$splitPendingComponentImporter = () => import('...')\n splitStrategy: 'lazyRouteComponent',\n localExporterIdent: 'SplitPendingComponent', // const SplitPendingComponent = ...\n exporterIdent: 'pendingComponent', // export { SplitPendingComponent as pendingComponent }\n },\n ],\n [\n 'errorComponent',\n {\n routeIdent: 'errorComponent',\n localImporterIdent: '$$splitErrorComponentImporter', // const $$splitErrorComponentImporter = () => import('...')\n splitStrategy: 'lazyRouteComponent',\n localExporterIdent: 'SplitErrorComponent', // const SplitErrorComponent = ...\n exporterIdent: 'errorComponent', // export { SplitErrorComponent as errorComponent }\n },\n ],\n [\n 'notFoundComponent',\n {\n routeIdent: 'notFoundComponent',\n localImporterIdent: '$$splitNotFoundComponentImporter', // const $$splitNotFoundComponentImporter = () => import('...')\n splitStrategy: 'lazyRouteComponent',\n localExporterIdent: 'SplitNotFoundComponent', // const SplitNotFoundComponent = ...\n exporterIdent: 'notFoundComponent', // export { SplitNotFoundComponent as notFoundComponent }\n },\n ],\n])\n\nconst KNOWN_SPLIT_ROUTE_IDENTS = [...SPLIT_NODES_CONFIG.keys()] as const\n\nfunction addSplitSearchParamToFilename(\n filename: string,\n grouping: Array<string>,\n) {\n const [bareFilename] = filename.split('?')\n\n const params = new URLSearchParams()\n params.append(tsrSplit, createIdentifier(grouping))\n\n const result = `${bareFilename}?${params.toString()}`\n return result\n}\n\nfunction removeSplitSearchParamFromFilename(filename: string) {\n const [bareFilename] = filename.split('?')\n return bareFilename!\n}\n\nexport function addSharedSearchParamToFilename(filename: string) {\n const [bareFilename] = filename.split('?')\n return `${bareFilename}?${tsrShared}=1`\n}\n\nconst splittableCreateRouteFns = ['createFileRoute']\nconst unsplittableCreateRouteFns = [\n 'createRootRoute',\n 'createRootRouteWithContext',\n]\nconst allCreateRouteFns = [\n ...splittableCreateRouteFns,\n ...unsplittableCreateRouteFns,\n]\n\n/**\n * Computes module-level bindings that are shared between split and non-split\n * route properties. These bindings need to be extracted into a shared virtual\n * module to avoid double-initialization.\n *\n * A binding is \"shared\" if it is referenced by at least one split property\n * AND at least one non-split property. Only locally-declared module-level\n * bindings are candidates (not imports — bundlers dedupe those).\n */\nexport function computeSharedBindings(opts: {\n code: string\n filename?: string\n codeSplitGroupings: CodeSplitGroupings\n}): Set<string> {\n const ast = parseAst(opts)\n\n // Early bailout: collect all module-level locally-declared binding names.\n // This is a cheap loop over program.body (no traversal). If the file has\n // no local bindings (aside from `Route`), nothing can be shared — skip\n // the expensive babel.traverse entirely.\n const localModuleLevelBindings = new Set<string>()\n for (const node of ast.program.body) {\n collectLocalBindingsFromStatement(node, localModuleLevelBindings)\n }\n\n // File-based routes always export a route config binding (usually `Route`).\n // This must never be extracted into the shared module.\n localModuleLevelBindings.delete('Route')\n\n if (localModuleLevelBindings.size === 0) {\n return new Set()\n }\n\n function findIndexForSplitNode(str: string) {\n return opts.codeSplitGroupings.findIndex((group) =>\n group.includes(str as any),\n )\n }\n\n // Find the route options object — needs babel.traverse for scope resolution\n let routeOptions: t.ObjectExpression | undefined\n\n babel.traverse(ast, {\n CallExpression(path) {\n if (!t.isIdentifier(path.node.callee)) return\n if (!splittableCreateRouteFns.includes(path.node.callee.name)) return\n\n if (t.isCallExpression(path.parentPath.node)) {\n const opts = resolveIdentifier(path, path.parentPath.node.arguments[0])\n if (t.isObjectExpression(opts)) routeOptions = opts\n } else if (t.isVariableDeclarator(path.parentPath.node)) {\n const caller = resolveIdentifier(path, path.parentPath.node.init)\n if (t.isCallExpression(caller)) {\n const opts = resolveIdentifier(path, caller.arguments[0])\n if (t.isObjectExpression(opts)) routeOptions = opts\n }\n }\n },\n })\n\n if (!routeOptions) return new Set()\n\n // Fast path: if fewer than 2 distinct groups are referenced by route options,\n // nothing can be shared and we can skip the rest of the work.\n const splitGroupsPresent = new Set<number>()\n let hasNonSplit = false\n for (const prop of routeOptions.properties) {\n if (!t.isObjectProperty(prop)) continue\n const key = getObjectPropertyKeyName(prop)\n if (!key) continue\n if (key === 'codeSplitGroupings') continue\n if (t.isIdentifier(prop.value) && prop.value.name === 'undefined') continue\n const groupIndex = findIndexForSplitNode(key) // -1 if non-split\n if (groupIndex === -1) {\n hasNonSplit = true\n } else {\n splitGroupsPresent.add(groupIndex)\n }\n }\n\n if (!hasNonSplit && splitGroupsPresent.size < 2) return new Set()\n\n // Build dependency graph up front — needed for transitive expansion per-property.\n // This graph excludes `Route` (deleted above) so group attribution works correctly.\n const declMap = buildDeclarationMap(ast)\n const depGraph = buildDependencyGraph(declMap, localModuleLevelBindings)\n\n // Build a second dependency graph that includes `Route` so we can detect\n // bindings that transitively depend on it. Such bindings must NOT be\n // extracted into the shared module because they would drag the Route\n // singleton with them, duplicating it across modules.\n const allLocalBindings = new Set(localModuleLevelBindings)\n allLocalBindings.add('Route')\n const fullDepGraph = buildDependencyGraph(declMap, allLocalBindings)\n\n // For each route property, track which \"group\" it belongs to.\n // Non-split properties get group index -1.\n // Split properties get their codeSplitGroupings index (0, 1, ...).\n // A binding is \"shared\" if it appears in 2+ distinct groups.\n // We expand each property's refs transitively BEFORE comparing groups,\n // so indirect refs (e.g., component: MyComp where MyComp uses `shared`)\n // are correctly attributed.\n const refsByGroup = new Map<string, Set<number>>()\n\n for (const prop of routeOptions.properties) {\n if (!t.isObjectProperty(prop)) continue\n const key = getObjectPropertyKeyName(prop)\n if (!key) continue\n\n if (key === 'codeSplitGroupings') continue\n\n const groupIndex = findIndexForSplitNode(key) // -1 if non-split\n\n const directRefs = collectModuleLevelRefsFromNode(\n prop.value,\n localModuleLevelBindings,\n )\n\n // Expand transitively: if component references SharedComp which references\n // `shared`, then `shared` is also attributed to component's group.\n const allRefs = new Set(directRefs)\n expandTransitively(allRefs, depGraph)\n\n for (const ref of allRefs) {\n let groups = refsByGroup.get(ref)\n if (!groups) {\n groups = new Set()\n refsByGroup.set(ref, groups)\n }\n groups.add(groupIndex)\n }\n }\n\n // Shared = bindings appearing in 2+ distinct groups\n const shared = new Set<string>()\n for (const [name, groups] of refsByGroup) {\n if (groups.size >= 2) shared.add(name)\n }\n\n // Destructured declarators (e.g. `const { a, b } = fn()`) must be treated\n // as a single initialization unit. Even if each binding is referenced by\n // only one group, if *different* bindings from the same declarator are\n // referenced by different groups, the declarator must be extracted to the\n // shared module to avoid double initialization.\n expandSharedDestructuredDeclarators(ast, refsByGroup, shared)\n\n if (shared.size === 0) return shared\n\n // If any binding from a destructured declaration is shared,\n // all bindings from that declaration must be shared\n expandDestructuredDeclarations(ast, shared)\n\n // Remove shared bindings that transitively depend on `Route`.\n // The Route singleton must stay in the reference file; extracting a\n // binding that references it would duplicate Route in the shared module.\n removeBindingsTransitivelyDependingOn(shared, fullDepGraph, ['Route'])\n\n return shared\n}\n\n/**\n * Find which shared bindings are user-exported in the original source.\n * These need to be re-exported from the shared module.\n */\nfunction findExportedSharedBindings(\n ast: t.File,\n sharedBindings: Set<string>,\n): Set<string> {\n const exported = new Set<string>()\n for (const stmt of ast.program.body) {\n if (!t.isExportNamedDeclaration(stmt) || !stmt.declaration) continue\n\n if (t.isVariableDeclaration(stmt.declaration)) {\n for (const decl of stmt.declaration.declarations) {\n for (const name of collectIdentifiersFromPattern(decl.id)) {\n if (sharedBindings.has(name)) exported.add(name)\n }\n }\n } else if (\n t.isFunctionDeclaration(stmt.declaration) &&\n stmt.declaration.id\n ) {\n if (sharedBindings.has(stmt.declaration.id.name))\n exported.add(stmt.declaration.id.name)\n } else if (t.isClassDeclaration(stmt.declaration) && stmt.declaration.id) {\n if (sharedBindings.has(stmt.declaration.id.name))\n exported.add(stmt.declaration.id.name)\n }\n }\n return exported\n}\n\n/**\n * Remove declarations of shared bindings from the AST.\n * Handles both plain and exported declarations, including destructured patterns.\n * Removes the entire statement if all bindings in it are shared.\n */\nfunction removeSharedDeclarations(ast: t.File, sharedBindings: Set<string>) {\n ast.program.body = ast.program.body.filter((stmt) => {\n const decl =\n t.isExportNamedDeclaration(stmt) && stmt.declaration\n ? stmt.declaration\n : stmt\n\n if (t.isVariableDeclaration(decl)) {\n // Filter out declarators where all bound names are shared\n decl.declarations = decl.declarations.filter((declarator) => {\n const names = collectIdentifiersFromPattern(declarator.id)\n return !names.every((n) => sharedBindings.has(n))\n })\n // If no declarators remain, remove the entire statement\n if (decl.declarations.length === 0) return false\n } else if (t.isFunctionDeclaration(decl) && decl.id) {\n if (sharedBindings.has(decl.id.name)) return false\n } else if (t.isClassDeclaration(decl) && decl.id) {\n if (sharedBindings.has(decl.id.name)) return false\n }\n\n return true\n })\n}\n\nexport function compileCodeSplitReferenceRoute(\n opts: ParseAstOptions &\n CompileCodeSplitReferenceRouteOptions & {\n compilerPlugins?: Array<CodeSplitCompilerPlugin>\n },\n): GeneratorResult | null {\n const ast = parseAst(opts)\n\n const refIdents = findReferencedIdentifiers(ast)\n\n const knownExportedIdents = new Set<string>()\n\n function findIndexForSplitNode(str: string) {\n return opts.codeSplitGroupings.findIndex((group) =>\n group.includes(str as any),\n )\n }\n\n const frameworkOptions = getFrameworkOptions(opts.targetFramework)\n const PACKAGE = frameworkOptions.package\n const LAZY_ROUTE_COMPONENT_IDENT = frameworkOptions.idents.lazyRouteComponent\n const LAZY_FN_IDENT = frameworkOptions.idents.lazyFn\n const stableRouteOptionKeys = [\n ...new Set(\n (opts.compilerPlugins ?? []).flatMap(\n (plugin) => plugin.getStableRouteOptionKeys?.() ?? [],\n ),\n ),\n ]\n\n let createRouteFn: string\n\n let modified = false as boolean\n let hmrAdded = false as boolean\n let sharedExportedNames: Set<string> | undefined\n babel.traverse(ast, {\n Program: {\n enter(programPath) {\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 const removableImportPaths = new Set<string>([])\n\n programPath.traverse({\n CallExpression: (path) => {\n if (!t.isIdentifier(path.node.callee)) {\n return\n }\n\n if (!allCreateRouteFns.includes(path.node.callee.name)) {\n return\n }\n\n createRouteFn = path.node.callee.name\n\n function babelHandleReference(routeOptions: t.Node | undefined) {\n const hasImportedOrDefinedIdentifier = (name: string) => {\n return programPath.scope.hasBinding(name)\n }\n\n const addRouteHmr = (\n insertionPath: babel.NodePath,\n routeOptions: t.ObjectExpression,\n ) => {\n if (!opts.addHmr || hmrAdded) {\n return\n }\n\n opts.compilerPlugins?.forEach((plugin) => {\n const pluginResult = plugin.onAddHmr?.({\n programPath,\n callExpressionPath: path,\n insertionPath,\n routeOptions,\n createRouteFn,\n opts: opts as CompileCodeSplitReferenceRouteOptions,\n })\n\n if (pluginResult?.modified) {\n modified = true\n }\n })\n\n programPath.pushContainer(\n 'body',\n createRouteHmrStatement(stableRouteOptionKeys, {\n hmrStyle: opts.hmrStyle ?? 'vite',\n targetFramework: opts.targetFramework,\n routeId: opts.hmrRouteId,\n }),\n )\n modified = true\n hmrAdded = true\n }\n\n if (t.isObjectExpression(routeOptions)) {\n const insertionPath = path.getStatementParent() ?? path\n\n opts.compilerPlugins?.forEach((plugin) => {\n const pluginResult = plugin.onRouteOptions?.({\n programPath,\n callExpressionPath: path,\n insertionPath,\n routeOptions,\n createRouteFn,\n opts: opts as CompileCodeSplitReferenceRouteOptions,\n })\n\n if (pluginResult?.modified) {\n modified = true\n }\n })\n\n if (opts.deleteNodes && opts.deleteNodes.size > 0) {\n routeOptions.properties = routeOptions.properties.filter(\n (prop) => {\n if (t.isObjectProperty(prop)) {\n const key = getObjectPropertyKeyName(prop)\n if (key && opts.deleteNodes!.has(key as any)) {\n modified = true\n return false\n }\n }\n return true\n },\n )\n }\n if (!splittableCreateRouteFns.includes(createRouteFn)) {\n opts.compilerPlugins?.forEach((plugin) => {\n const pluginResult = plugin.onUnsplittableRoute?.({\n programPath,\n callExpressionPath: path,\n insertionPath,\n routeOptions,\n createRouteFn,\n opts: opts as CompileCodeSplitReferenceRouteOptions,\n })\n\n if (pluginResult?.modified) {\n modified = true\n }\n })\n\n // we can't split this route but we still add HMR handling if enabled\n addRouteHmr(insertionPath, routeOptions)\n // exit traversal so this route is not split\n return programPath.stop()\n }\n routeOptions.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n const key = getObjectPropertyKeyName(prop)\n\n if (key) {\n // If the user has not specified a split grouping for this key\n // then we should not split it\n const codeSplitGroupingByKey = findIndexForSplitNode(key)\n if (codeSplitGroupingByKey === -1) {\n return\n }\n const codeSplitGroup = [\n ...new Set(\n opts.codeSplitGroupings[codeSplitGroupingByKey],\n ),\n ]\n\n // find key in nodeSplitConfig\n const isNodeConfigAvailable = SPLIT_NODES_CONFIG.has(\n key as any,\n )\n\n if (!isNodeConfigAvailable) {\n return\n }\n\n // Exit early if the value is a boolean, null, or undefined.\n // These values mean \"don't use this component, fallback to parent\"\n // No code splitting needed to preserve fallback behavior\n if (\n t.isBooleanLiteral(prop.value) ||\n t.isNullLiteral(prop.value) ||\n (t.isIdentifier(prop.value) &&\n prop.value.name === 'undefined')\n ) {\n return\n }\n\n const splitNodeMeta = SPLIT_NODES_CONFIG.get(key as any)!\n\n // We need to extract the existing search params from the filename, if any\n // and add the relevant codesplitPrefix to them, then write them back to the filename\n const splitUrl = addSplitSearchParamToFilename(\n opts.filename,\n codeSplitGroup,\n )\n\n if (\n splitNodeMeta.splitStrategy === 'lazyRouteComponent'\n ) {\n const value = prop.value\n\n let shouldSplit = true\n\n if (t.isIdentifier(value)) {\n const existingImportPath =\n getImportSpecifierAndPathFromLocalName(\n programPath,\n value.name,\n ).path\n if (existingImportPath) {\n removableImportPaths.add(existingImportPath)\n }\n\n // exported identifiers should not be split\n // since they are already being imported\n // and need to be retained in the compiled file\n const isExported = hasExport(ast, value)\n if (isExported) {\n knownExportedIdents.add(value.name)\n }\n shouldSplit = !isExported\n\n if (shouldSplit) {\n removeIdentifierLiteral(path, value)\n }\n }\n\n if (!shouldSplit) {\n return\n }\n\n modified = true\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 if (\n !hasImportedOrDefinedIdentifier(\n LAZY_ROUTE_COMPONENT_IDENT,\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `import { ${LAZY_ROUTE_COMPONENT_IDENT} } from '${PACKAGE}'`,\n )(),\n ])\n }\n\n // Check to see if the importer function is already defined\n // If not, define it with the dynamic import statement\n if (\n !hasImportedOrDefinedIdentifier(\n splitNodeMeta.localImporterIdent,\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`,\n )(),\n ])\n }\n\n const insertionPath = path.getStatementParent() ?? path\n let splitPropValue: t.Expression | undefined\n\n for (const plugin of opts.compilerPlugins ?? []) {\n const pluginPropValue = plugin.onSplitRouteProperty?.(\n {\n programPath,\n callExpressionPath: path,\n insertionPath,\n routeOptions,\n prop,\n splitNodeMeta,\n lazyRouteComponentIdent:\n LAZY_ROUTE_COMPONENT_IDENT,\n opts,\n },\n )\n\n if (!pluginPropValue) {\n continue\n }\n\n modified = true\n splitPropValue = pluginPropValue\n break\n }\n\n if (splitPropValue) {\n prop.value = splitPropValue\n } else {\n prop.value = template.expression(\n `${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`,\n )()\n }\n\n // add HMR handling\n addRouteHmr(insertionPath, routeOptions)\n } else {\n // if (splitNodeMeta.splitStrategy === 'lazyFn') {\n const value = prop.value\n\n let shouldSplit = true\n\n if (t.isIdentifier(value)) {\n const existingImportPath =\n getImportSpecifierAndPathFromLocalName(\n programPath,\n value.name,\n ).path\n if (existingImportPath) {\n removableImportPaths.add(existingImportPath)\n }\n\n // exported identifiers should not be split\n // since they are already being imported\n // and need to be retained in the compiled file\n const isExported = hasExport(ast, value)\n if (isExported) {\n knownExportedIdents.add(value.name)\n }\n shouldSplit = !isExported\n\n if (shouldSplit) {\n removeIdentifierLiteral(path, value)\n }\n }\n\n if (!shouldSplit) {\n return\n }\n modified = true\n\n // Prepend the import statement to the program along with the importer function\n if (!hasImportedOrDefinedIdentifier(LAZY_FN_IDENT)) {\n programPath.unshiftContainer(\n 'body',\n template.smart(\n `import { ${LAZY_FN_IDENT} } from '${PACKAGE}'`,\n )(),\n )\n }\n\n // Check to see if the importer function is already defined\n // If not, define it with the dynamic import statement\n if (\n !hasImportedOrDefinedIdentifier(\n splitNodeMeta.localImporterIdent,\n )\n ) {\n programPath.unshiftContainer('body', [\n template.statement(\n `const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`,\n )(),\n ])\n }\n\n // Add the lazyFn call with the dynamic import to the prop value\n prop.value = template.expression(\n `${LAZY_FN_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`,\n )()\n }\n }\n }\n\n programPath.scope.crawl()\n })\n\n addRouteHmr(insertionPath, routeOptions)\n }\n }\n\n if (t.isCallExpression(path.parentPath.node)) {\n // createFileRoute('/')({ ... })\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n babelHandleReference(options)\n } else if (t.isVariableDeclarator(path.parentPath.node)) {\n // createFileRoute({ ... })\n const caller = resolveIdentifier(path, path.parentPath.node.init)\n\n if (t.isCallExpression(caller)) {\n const options = resolveIdentifier(path, caller.arguments[0])\n babelHandleReference(options)\n }\n }\n },\n })\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 (removableImportPaths.size > 0) {\n modified = true\n programPath.traverse({\n ImportDeclaration(path) {\n if (path.node.specifiers.length > 0) return\n if (removableImportPaths.has(path.node.source.value)) {\n path.remove()\n }\n },\n })\n }\n\n // Handle shared bindings inside the Program visitor so we have\n // access to programPath for cheap refIdents registration.\n if (opts.sharedBindings && opts.sharedBindings.size > 0) {\n sharedExportedNames = findExportedSharedBindings(\n ast,\n opts.sharedBindings,\n )\n removeSharedDeclarations(ast, opts.sharedBindings)\n\n const sharedModuleUrl = addSharedSearchParamToFilename(opts.filename)\n\n const sharedImportSpecifiers = [...opts.sharedBindings].map((name) =>\n t.importSpecifier(t.identifier(name), t.identifier(name)),\n )\n const [sharedImportPath] = programPath.unshiftContainer(\n 'body',\n t.importDeclaration(\n sharedImportSpecifiers,\n t.stringLiteral(sharedModuleUrl),\n ),\n )\n\n // Register import specifier locals in refIdents so DCE can remove unused ones\n sharedImportPath.traverse({\n Identifier(identPath) {\n if (\n identPath.parentPath.isImportSpecifier() &&\n identPath.key === 'local'\n ) {\n refIdents.add(identPath)\n }\n },\n })\n\n // Re-export user-exported shared bindings from the shared module\n if (sharedExportedNames.size > 0) {\n const reExportSpecifiers = [...sharedExportedNames].map((name) =>\n t.exportSpecifier(t.identifier(name), t.identifier(name)),\n )\n programPath.pushContainer(\n 'body',\n t.exportNamedDeclaration(\n null,\n reExportSpecifiers,\n t.stringLiteral(sharedModuleUrl),\n ),\n )\n }\n }\n },\n },\n })\n\n if (!modified) {\n return null\n }\n\n deadCodeElimination(ast, refIdents)\n\n // if there are exported identifiers, then we need to add a warning\n // to the file to let the user know that the exported identifiers\n // will not in the split file but in the original file, therefore\n // increasing the bundle size\n if (knownExportedIdents.size > 0) {\n const warningMessage = createNotExportableMessage(\n opts.filename,\n knownExportedIdents,\n )\n console.warn(warningMessage)\n\n // append this warning to the file using a template\n if (process.env.NODE_ENV !== 'production') {\n const warningTemplate = template.statement(\n `console.warn(${JSON.stringify(warningMessage)})`,\n )()\n ast.program.body.unshift(warningTemplate)\n }\n }\n\n const result = generateFromAst(ast, {\n sourceMaps: true,\n sourceFileName: opts.filename,\n filename: opts.filename,\n })\n\n // @babel/generator does not populate sourcesContent because it only has\n // the AST, not the original text. Without this, Vite's composed\n // sourcemap omits the original source, causing downstream consumers\n // (e.g. import-protection snippet display) to fall back to the shorter\n // compiled output and fail to resolve original line numbers.\n if (result.map) {\n result.map.sourcesContent = [opts.code]\n }\n\n return result\n}\n\nexport function compileCodeSplitVirtualRoute(\n opts: ParseAstOptions & {\n splitTargets: Array<SplitRouteIdentNodes>\n filename: string\n sharedBindings?: Set<string>\n compilerPlugins?: Array<CodeSplitCompilerPlugin>\n },\n): GeneratorResult {\n const ast = parseAst(opts)\n const refIdents = findReferencedIdentifiers(ast)\n\n // Remove shared declarations BEFORE babel.traverse so the scope never sees\n // conflicting bindings (avoids checkBlockScopedCollisions crash in DCE)\n if (opts.sharedBindings && opts.sharedBindings.size > 0) {\n removeSharedDeclarations(ast, opts.sharedBindings)\n }\n\n const intendedSplitNodes = new Set(opts.splitTargets)\n\n const knownExportedIdents = new Set<string>()\n\n babel.traverse(ast, {\n Program: {\n enter(programPath) {\n const trackedNodesToSplitByType: Record<\n SplitRouteIdentNodes,\n { node: t.Node | undefined; meta: SplitNodeMeta } | undefined\n > = {\n component: undefined,\n loader: undefined,\n pendingComponent: undefined,\n errorComponent: undefined,\n notFoundComponent: undefined,\n }\n\n // Find and track all the known split-able nodes\n programPath.traverse({\n CallExpression: (path) => {\n if (!t.isIdentifier(path.node.callee)) {\n return\n }\n\n if (!splittableCreateRouteFns.includes(path.node.callee.name)) {\n return\n }\n\n function babelHandleVirtual(options: t.Node | undefined) {\n if (t.isObjectExpression(options)) {\n options.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n // do not use `intendedSplitNodes` here\n // since we have special considerations that need\n // to be accounted for like (not splitting exported identifiers)\n KNOWN_SPLIT_ROUTE_IDENTS.forEach((splitType) => {\n if (getObjectPropertyKeyName(prop) !== splitType) {\n return\n }\n\n const value = prop.value\n\n // If the value for the `key` is `undefined`, then we don't need to include it\n // in the split file, so we can just return, since it will kept in-place in the\n // reference file\n // This is useful for cases like: `createFileRoute('/')({ component: undefined })`\n if (t.isIdentifier(value) && value.name === 'undefined') {\n return\n }\n\n let isExported = false\n if (t.isIdentifier(value)) {\n isExported = hasExport(ast, value)\n if (isExported) {\n knownExportedIdents.add(value.name)\n }\n }\n\n // If the node is exported, we need to remove\n // the export from the split file\n if (isExported && t.isIdentifier(value)) {\n removeExports(ast, value)\n } else {\n const meta = SPLIT_NODES_CONFIG.get(splitType)!\n trackedNodesToSplitByType[splitType] = {\n node: prop.value,\n meta,\n }\n }\n })\n }\n })\n\n // Remove all of the options\n options.properties = []\n }\n }\n\n if (t.isCallExpression(path.parentPath.node)) {\n // createFileRoute('/')({ ... })\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n babelHandleVirtual(options)\n } else if (t.isVariableDeclarator(path.parentPath.node)) {\n // createFileRoute({ ... })\n const caller = resolveIdentifier(path, path.parentPath.node.init)\n\n if (t.isCallExpression(caller)) {\n const options = resolveIdentifier(path, caller.arguments[0])\n babelHandleVirtual(options)\n }\n }\n },\n })\n\n // Start the transformation to only exported the intended split nodes\n intendedSplitNodes.forEach((SPLIT_TYPE) => {\n const splitKey = trackedNodesToSplitByType[SPLIT_TYPE]\n\n if (!splitKey) {\n return\n }\n\n let splitNode = splitKey.node\n const splitMeta = { ...splitKey.meta, shouldRemoveNode: true }\n\n // Track the original identifier name before resolving through bindings,\n // needed for destructured patterns where the binding resolves to the\n // entire VariableDeclarator (ObjectPattern) rather than the specific binding\n let originalIdentName: string | undefined\n if (t.isIdentifier(splitNode)) {\n originalIdentName = splitNode.name\n }\n\n while (t.isIdentifier(splitNode)) {\n const binding = programPath.scope.getBinding(splitNode.name)\n splitNode = binding?.path.node\n }\n\n // Add the node to the program\n if (splitNode) {\n for (const plugin of opts.compilerPlugins ?? []) {\n plugin.onVirtualRouteSplitNode?.({\n programPath,\n splitNode,\n splitNodeMeta: splitMeta,\n })\n }\n\n if (t.isFunctionDeclaration(splitNode)) {\n // an anonymous function declaration should only happen for `export default function() {...}`\n // so we should never get here\n if (!splitNode.id) {\n throw new Error(\n `Function declaration for \"${SPLIT_TYPE}\" must have an identifier.`,\n )\n }\n\n splitMeta.shouldRemoveNode = false\n splitMeta.localExporterIdent = splitNode.id.name\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(splitMeta.localExporterIdent),\n splitNode,\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(splitMeta.localExporterIdent),\n splitNode.local,\n ),\n ]),\n )\n } else if (t.isVariableDeclarator(splitNode)) {\n if (t.isIdentifier(splitNode.id)) {\n splitMeta.localExporterIdent = splitNode.id.name\n splitMeta.shouldRemoveNode = false\n } else if (t.isObjectPattern(splitNode.id)) {\n // Destructured binding like `const { component: MyComp } = createBits()`\n // Use the original identifier name that was tracked before resolving\n if (originalIdentName) {\n splitMeta.localExporterIdent = originalIdentName\n }\n splitMeta.shouldRemoveNode = false\n } else {\n throw new Error(\n `Unexpected splitNode type ☝️: ${splitNode.type}`,\n )\n }\n } else if (t.isCallExpression(splitNode)) {\n const outputSplitNodeCode = generateFromAst(splitNode).code\n const splitNodeAst = babel.parse(outputSplitNodeCode)\n\n if (!splitNodeAst) {\n throw new Error(\n `Failed to parse the generated code for \"${SPLIT_TYPE}\" 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 \"${SPLIT_TYPE}\" 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(splitMeta.localExporterIdent),\n expression,\n ),\n ]),\n )\n } else {\n throw new Error(\n `Unexpected expression type encounter for \"${SPLIT_TYPE}\" in the node type \"${splitNode.type}\"`,\n )\n }\n } else if (t.isConditionalExpression(splitNode)) {\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitMeta.localExporterIdent),\n splitNode,\n ),\n ]),\n )\n } else if (t.isTSAsExpression(splitNode)) {\n // remove the type assertion\n splitNode = splitNode.expression\n programPath.pushContainer(\n 'body',\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(splitMeta.localExporterIdent),\n splitNode,\n ),\n ]),\n )\n } else if (t.isBooleanLiteral(splitNode)) {\n // Handle boolean literals\n // This exits early here, since this value will be kept in the reference file\n return\n } else if (t.isNullLiteral(splitNode)) {\n // Handle null literals\n // This exits early here, since this value will be kept in the reference file\n return\n } else {\n console.info('Unexpected splitNode type:', splitNode)\n throw new Error(`Unexpected splitNode type ☝️: ${splitNode.type}`)\n }\n }\n\n if (splitMeta.shouldRemoveNode) {\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((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(splitMeta.localExporterIdent), // local variable name\n t.identifier(splitMeta.exporterIdent), // as what name it should be exported as\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 const specifiers = path.node.declaration.declarations.flatMap(\n (decl) => {\n if (t.isIdentifier(decl.id)) {\n return [\n t.importSpecifier(\n t.identifier(decl.id.name),\n t.identifier(decl.id.name),\n ),\n ]\n }\n\n if (t.isObjectPattern(decl.id)) {\n return collectIdentifiersFromPattern(decl.id).map(\n (name) =>\n t.importSpecifier(\n t.identifier(name),\n t.identifier(name),\n ),\n )\n }\n\n if (t.isArrayPattern(decl.id)) {\n return collectIdentifiersFromPattern(decl.id).map(\n (name) =>\n t.importSpecifier(\n t.identifier(name),\n t.identifier(name),\n ),\n )\n }\n\n return []\n },\n )\n\n if (specifiers.length === 0) {\n path.remove()\n return\n }\n\n const importDecl = t.importDeclaration(\n specifiers,\n t.stringLiteral(\n removeSplitSearchParamFromFilename(opts.filename),\n ),\n )\n\n path.replaceWith(importDecl)\n\n // Track the imported identifier paths so deadCodeElimination can remove them if unused\n // We need to traverse the newly created import to get the identifier paths\n path.traverse({\n Identifier(identPath) {\n // Only track the local binding identifiers (the imported names)\n if (\n identPath.parentPath.isImportSpecifier() &&\n identPath.key === 'local'\n ) {\n refIdents.add(identPath)\n }\n },\n })\n }\n }\n },\n })\n\n // Add shared bindings import, registering specifiers in refIdents\n // so DCE can remove unused ones (same pattern as import replacements above).\n if (opts.sharedBindings && opts.sharedBindings.size > 0) {\n const sharedImportSpecifiers = [...opts.sharedBindings].map((name) =>\n t.importSpecifier(t.identifier(name), t.identifier(name)),\n )\n const sharedModuleUrl = addSharedSearchParamToFilename(\n removeSplitSearchParamFromFilename(opts.filename),\n )\n const [sharedImportPath] = programPath.unshiftContainer(\n 'body',\n t.importDeclaration(\n sharedImportSpecifiers,\n t.stringLiteral(sharedModuleUrl),\n ),\n )\n\n sharedImportPath.traverse({\n Identifier(identPath) {\n if (\n identPath.parentPath.isImportSpecifier() &&\n identPath.key === 'local'\n ) {\n refIdents.add(identPath)\n }\n },\n })\n }\n },\n },\n })\n\n deadCodeElimination(ast, refIdents)\n stripUnreferencedTopLevelExpressionStatements(ast)\n\n // If the body is empty after DCE, strip directive prologues too.\n // A file containing only `'use client'` with no real code is useless.\n if (ast.program.body.length === 0) {\n ast.program.directives = []\n }\n\n const result = generateFromAst(ast, {\n sourceMaps: true,\n sourceFileName: opts.filename,\n filename: opts.filename,\n })\n\n // @babel/generator does not populate sourcesContent — see compileCodeSplitReferenceRoute.\n if (result.map) {\n result.map.sourcesContent = [opts.code]\n }\n\n return result\n}\n\n/**\n * Compile the shared virtual module (`?tsr-shared=1`).\n * Keeps only shared binding declarations, their transitive dependencies,\n * and imports they need. Exports all shared bindings.\n */\nexport function compileCodeSplitSharedRoute(\n opts: ParseAstOptions & {\n sharedBindings: Set<string>\n filename: string\n },\n): GeneratorResult {\n const ast = parseAst(opts)\n const refIdents = findReferencedIdentifiers(ast)\n\n // Collect all names that need to stay: shared bindings + their transitive deps\n const localBindings = new Set<string>()\n for (const node of ast.program.body) {\n collectLocalBindingsFromStatement(node, localBindings)\n }\n\n // Route must never be extracted into the shared module.\n // Excluding it from the dep graph prevents expandTransitively from\n // pulling it in as a transitive dependency of a shared binding.\n localBindings.delete('Route')\n\n const declMap = buildDeclarationMap(ast)\n const depGraph = buildDependencyGraph(declMap, localBindings)\n\n // Start with shared bindings and expand transitively\n const keepBindings = new Set(opts.sharedBindings)\n keepBindings.delete('Route')\n expandTransitively(keepBindings, depGraph)\n\n retainModuleLevelDeclarations(ast, keepBindings)\n unwrapExportedDeclarations(ast)\n\n // Export all shared bindings (sorted for deterministic output)\n const exportNames = [...opts.sharedBindings].sort((a, b) =>\n a.localeCompare(b),\n )\n const exportSpecifiers = exportNames.map((name) =>\n t.exportSpecifier(t.identifier(name), t.identifier(name)),\n )\n if (exportSpecifiers.length > 0) {\n const exportDecl = t.exportNamedDeclaration(null, exportSpecifiers)\n ast.program.body.push(exportDecl)\n\n // Register export specifier locals in refIdents so DCE doesn't treat\n // the exported bindings as unreferenced.\n babel.traverse(ast, {\n Program(programPath) {\n const bodyPaths = programPath.get('body')\n const last = bodyPaths[bodyPaths.length - 1]\n if (last && last.isExportNamedDeclaration()) {\n last.traverse({\n Identifier(identPath) {\n if (\n identPath.parentPath.isExportSpecifier() &&\n identPath.key === 'local'\n ) {\n refIdents.add(identPath)\n }\n },\n })\n }\n programPath.stop()\n },\n })\n }\n\n deadCodeElimination(ast, refIdents)\n\n // If the body is empty after DCE, strip directive prologues too.\n if (ast.program.body.length === 0) {\n ast.program.directives = []\n }\n\n const result = generateFromAst(ast, {\n sourceMaps: true,\n sourceFileName: opts.filename,\n filename: opts.filename,\n })\n\n // @babel/generator does not populate sourcesContent — see compileCodeSplitReferenceRoute.\n if (result.map) {\n result.map.sourcesContent = [opts.code]\n }\n\n return result\n}\n\n/**\n * This function should read get the options from by searching for the key `codeSplitGroupings`\n * on createFileRoute and return it's values if it exists, else return undefined\n */\nexport function detectCodeSplitGroupingsFromRoute(opts: ParseAstOptions): {\n groupings: CodeSplitGroupings | undefined\n} {\n const ast = parseAst(opts)\n\n let codeSplitGroupings: CodeSplitGroupings | undefined = undefined\n\n babel.traverse(ast, {\n Program: {\n enter(programPath) {\n programPath.traverse({\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 function babelHandleSplittingGroups(\n routeOptions: t.Node | undefined,\n ) {\n if (t.isObjectExpression(routeOptions)) {\n routeOptions.properties.forEach((prop) => {\n if (t.isObjectProperty(prop)) {\n const key = getObjectPropertyKeyName(prop)\n if (key === 'codeSplitGroupings') {\n const value = prop.value\n\n if (t.isArrayExpression(value)) {\n codeSplitGroupings = value.elements.map((group) => {\n if (t.isArrayExpression(group)) {\n return group.elements.map((node) => {\n if (!t.isStringLiteral(node)) {\n throw new Error(\n 'You must provide a string literal for the codeSplitGroupings',\n )\n }\n\n return node.value\n }) as Array<SplitRouteIdentNodes>\n }\n\n throw new Error(\n 'You must provide arrays with codeSplitGroupings options.',\n )\n })\n } else {\n throw new Error(\n 'You must provide an array of arrays for the codeSplitGroupings.',\n )\n }\n }\n }\n })\n }\n }\n\n // Extracting the codeSplitGroupings\n if (t.isCallExpression(path.parentPath.node)) {\n // createFileRoute('/')({ ... })\n const options = resolveIdentifier(\n path,\n path.parentPath.node.arguments[0],\n )\n\n babelHandleSplittingGroups(options)\n } else if (t.isVariableDeclarator(path.parentPath.node)) {\n // createFileRoute({ ... })\n const caller = resolveIdentifier(path, path.parentPath.node.init)\n\n if (t.isCallExpression(caller)) {\n const options = resolveIdentifier(path, caller.arguments[0])\n babelHandleSplittingGroups(options)\n }\n }\n },\n })\n },\n },\n })\n\n return { groupings: codeSplitGroupings }\n}\n\nfunction createNotExportableMessage(\n filename: string,\n idents: Set<string>,\n): string {\n const list = Array.from(idents).map((d) => `- ${d}`)\n\n const message = [\n `[tanstack-router] These exports from \"${filename}\" will not be code-split and will increase your bundle size:`,\n ...list,\n 'For the best optimization, these items should either have their export statements removed, or be imported from another location that is not a route file.',\n ].join('\\n')\n\n return message\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): t.Node | undefined {\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: babel.NodePath, node: t.Identifier) {\n const binding = path.scope.getBinding(node.name)\n if (binding) {\n // If the binding is a destructured property from an ObjectPattern,\n // only remove that property instead of the entire declaration\n if (\n t.isVariableDeclarator(binding.path.node) &&\n t.isObjectPattern(binding.path.node.id)\n ) {\n const objectPattern = binding.path.node.id\n objectPattern.properties = objectPattern.properties.filter((prop) => {\n if (!t.isObjectProperty(prop)) {\n return true\n }\n\n if (t.isIdentifier(prop.value) && prop.value.name === node.name) {\n return false\n }\n\n if (\n t.isAssignmentPattern(prop.value) &&\n t.isIdentifier(prop.value.left) &&\n prop.value.left.name === node.name\n ) {\n return false\n }\n\n return true\n })\n\n // If no properties remain, remove the entire declaration\n if (objectPattern.properties.length === 0) {\n binding.path.remove()\n }\n\n return\n }\n\n binding.path.remove()\n }\n}\n\nfunction hasExport(ast: t.File, node: t.Identifier): boolean {\n let found = false\n\n babel.traverse(ast, {\n ExportNamedDeclaration(path) {\n if (path.node.declaration) {\n // declared as `const loaderFn = () => {}`\n if (t.isVariableDeclaration(path.node.declaration)) {\n path.node.declaration.declarations.forEach((decl) => {\n if (t.isVariableDeclarator(decl)) {\n if (t.isIdentifier(decl.id)) {\n if (decl.id.name === node.name) {\n found = true\n }\n } else if (\n t.isObjectPattern(decl.id) ||\n t.isArrayPattern(decl.id)\n ) {\n // Handle destructured exports like `export const { a, b } = fn()`\n const names = collectIdentifiersFromPattern(decl.id)\n if (names.includes(node.name)) {\n found = true\n }\n }\n }\n })\n }\n\n // declared as `function loaderFn() {}`\n if (t.isFunctionDeclaration(path.node.declaration)) {\n if (t.isIdentifier(path.node.declaration.id)) {\n if (path.node.declaration.id.name === node.name) {\n found = true\n }\n }\n }\n }\n },\n ExportDefaultDeclaration(path) {\n // declared as `export default loaderFn`\n if (t.isIdentifier(path.node.declaration)) {\n if (path.node.declaration.name === node.name) {\n found = true\n }\n }\n\n // declared as `export default function loaderFn() {}`\n if (t.isFunctionDeclaration(path.node.declaration)) {\n if (t.isIdentifier(path.node.declaration.id)) {\n if (path.node.declaration.id.name === node.name) {\n found = true\n }\n }\n }\n },\n })\n\n return found\n}\n\nfunction removeExports(ast: t.File, node: t.Identifier): boolean {\n let removed = false\n\n // The checks use sequential if/else if statements since it\n // directly mutates the AST and as such doing normal checks\n // (using only if statements) could lead to a situation where\n // `path.node` is null since it has been already removed from\n // the program tree but typescript doesn't know that.\n babel.traverse(ast, {\n ExportNamedDeclaration(path) {\n if (path.node.declaration) {\n if (t.isVariableDeclaration(path.node.declaration)) {\n // declared as `const loaderFn = () => {}`\n path.node.declaration.declarations.forEach((decl) => {\n if (t.isVariableDeclarator(decl)) {\n if (t.isIdentifier(decl.id)) {\n if (decl.id.name === node.name) {\n path.remove()\n removed = true\n }\n } else if (\n t.isObjectPattern(decl.id) ||\n t.isArrayPattern(decl.id)\n ) {\n // Handle destructured exports like `export const { a, b } = fn()`\n const names = collectIdentifiersFromPattern(decl.id)\n if (names.includes(node.name)) {\n path.remove()\n removed = true\n }\n }\n }\n })\n } else if (t.isFunctionDeclaration(path.node.declaration)) {\n // declared as `export const loaderFn = () => {}`\n if (t.isIdentifier(path.node.declaration.id)) {\n if (path.node.declaration.id.name === node.name) {\n path.remove()\n removed = true\n }\n }\n }\n }\n },\n ExportDefaultDeclaration(path) {\n // declared as `export default loaderFn`\n if (t.isIdentifier(path.node.declaration)) {\n if (path.node.declaration.name === node.name) {\n path.remove()\n removed = true\n }\n } else if (t.isFunctionDeclaration(path.node.declaration)) {\n // declared as `export default function loaderFn() {}`\n if (t.isIdentifier(path.node.declaration.id)) {\n if (path.node.declaration.id.name === node.name) {\n path.remove()\n removed = true\n }\n }\n }\n },\n })\n\n return removed\n}\n"],"mappings":"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"}