{"version":3,"file":"router-code-splitter-plugin.cjs","names":[],"sources":["../../../src/core/router-code-splitter-plugin.ts"],"sourcesContent":["/**\n * It is important to familiarize yourself with how the code-splitting works in this plugin.\n * https://github.com/TanStack/router/pull/3355\n */\n\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport { resolveHmrHotExpression } from './hmr-hot-expression'\nimport {\n  compileCodeSplitReferenceRoute,\n  compileCodeSplitSharedRoute,\n  compileCodeSplitVirtualRoute,\n  computeSharedBindings,\n  detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport { getReferenceRouteCompilerPlugins } from './code-splitter/plugins/framework-plugins'\nimport {\n  defaultCodeSplitGroupings,\n  splitRouteIdentNodes,\n  tsrShared,\n  tsrSplit,\n} from './constants'\nimport { decodeIdentifier } from './code-splitter/path-ids'\nimport { debug, normalizePath } from './utils'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type {\n  UnpluginFactory,\n  TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\nconst CODE_SPLITTER_PLUGIN_NAME =\n  'tanstack-router:code-splitter:compile-reference-file'\n\ntype TransformationPluginInfo = {\n  pluginNames: Array<string>\n  pkg: string\n  usage: string\n}\n\n/**\n * JSX transformation plugins grouped by framework.\n * These plugins must come AFTER the TanStack Router plugin in the Vite config.\n */\nconst TRANSFORMATION_PLUGINS_BY_FRAMEWORK: Record<\n  string,\n  Array<TransformationPluginInfo>\n> = {\n  react: [\n    {\n      // Babel-based React plugin\n      pluginNames: ['vite:react-babel', 'vite:react-refresh'],\n      pkg: '@vitejs/plugin-react',\n      usage: 'react()',\n    },\n    {\n      // SWC-based React plugin\n      pluginNames: ['vite:react-swc', 'vite:react-swc:resolve-runtime'],\n      pkg: '@vitejs/plugin-react-swc',\n      usage: 'reactSwc()',\n    },\n    {\n      // OXC-based React plugin (deprecated but should still be handled)\n      pluginNames: ['vite:react-oxc:config', 'vite:react-oxc:refresh-runtime'],\n      pkg: '@vitejs/plugin-react-oxc',\n      usage: 'reactOxc()',\n    },\n  ],\n  solid: [\n    {\n      pluginNames: ['solid'],\n      pkg: 'vite-plugin-solid',\n      usage: 'solid()',\n    },\n  ],\n}\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n  Partial<Config | (() => Config)> | undefined\n> = (options = {}, { framework: _framework }) => {\n  let ROOT: string = process.cwd()\n  let userConfig: Config\n\n  function initUserConfig() {\n    if (typeof options === 'function') {\n      userConfig = options()\n    } else {\n      userConfig = getConfig(options, ROOT)\n    }\n  }\n  const isProduction = process.env.NODE_ENV === 'production'\n  // Map from normalized route file path → set of shared binding names.\n  // Populated by the reference compiler, consumed by virtual and shared compilers.\n  const sharedBindingsMap = new Map<string, Set<string>>()\n\n  const getGlobalCodeSplitGroupings = () => {\n    return (\n      userConfig.codeSplittingOptions?.defaultBehavior ||\n      defaultCodeSplitGroupings\n    )\n  }\n  const getShouldSplitFn = () => {\n    return userConfig.codeSplittingOptions?.splitBehavior\n  }\n\n  const handleCompilingReferenceFile = (\n    code: string,\n    id: string,\n    generatorNodeInfo: GetRoutesByFileMapResultValue,\n  ): UnpluginTransformResult => {\n    if (debug) console.info('Compiling Route: ', id)\n\n    const fromCode = detectCodeSplitGroupingsFromRoute({\n      code,\n    })\n\n    if (fromCode.groupings !== undefined) {\n      const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n      if (!res.success) {\n        const message = res.error.errors.map((e) => e.message).join('. ')\n        throw new Error(\n          `The groupings for the route \"${id}\" are invalid.\\n${message}`,\n        )\n      }\n    }\n\n    const userShouldSplitFn = getShouldSplitFn()\n\n    const pluginSplitBehavior = userShouldSplitFn?.({\n      routeId: generatorNodeInfo.routePath,\n    }) as CodeSplitGroupings | undefined\n\n    if (pluginSplitBehavior) {\n      const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n      if (!res.success) {\n        const message = res.error.errors.map((e) => e.message).join('. ')\n        throw new Error(\n          `The groupings returned when using \\`splitBehavior\\` for the route \"${id}\" are invalid.\\n${message}`,\n        )\n      }\n    }\n\n    const splitGroupings: CodeSplitGroupings =\n      fromCode.groupings ?? pluginSplitBehavior ?? getGlobalCodeSplitGroupings()\n\n    // Compute shared bindings before compiling the reference route\n    const sharedBindings = computeSharedBindings({\n      code,\n      codeSplitGroupings: splitGroupings,\n    })\n    if (sharedBindings.size > 0) {\n      sharedBindingsMap.set(id, sharedBindings)\n    } else {\n      sharedBindingsMap.delete(id)\n    }\n\n    const addHmr =\n      (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction\n    const hmrHotExpression = resolveHmrHotExpression(\n      userConfig.plugin?.hmr?.hotExpression,\n    )\n\n    const compiledReferenceRoute = compileCodeSplitReferenceRoute({\n      code,\n      codeSplitGroupings: splitGroupings,\n      targetFramework: userConfig.target,\n      filename: id,\n      id,\n      deleteNodes: userConfig.codeSplittingOptions?.deleteNodes\n        ? new Set(userConfig.codeSplittingOptions.deleteNodes)\n        : undefined,\n      addHmr,\n      hmrHotExpression,\n      sharedBindings: sharedBindings.size > 0 ? sharedBindings : undefined,\n      compilerPlugins: getReferenceRouteCompilerPlugins({\n        targetFramework: userConfig.target,\n        addHmr,\n        hmrHotExpression,\n      }),\n    })\n\n    if (compiledReferenceRoute === null) {\n      if (debug) {\n        console.info(\n          `No changes made to route \"${id}\", skipping code-splitting.`,\n        )\n      }\n      return null\n    }\n    if (debug) {\n      logDiff(code, compiledReferenceRoute.code)\n      console.log('Output:\\n', compiledReferenceRoute.code + '\\n\\n')\n    }\n\n    return compiledReferenceRoute\n  }\n\n  const handleCompilingVirtualFile = (\n    code: string,\n    id: string,\n  ): UnpluginTransformResult => {\n    if (debug) console.info('Splitting Route: ', id)\n\n    const [_, ...pathnameParts] = id.split('?')\n\n    const searchParams = new URLSearchParams(pathnameParts.join('?'))\n    const splitValue = searchParams.get(tsrSplit)\n\n    if (!splitValue) {\n      throw new Error(\n        `The split value for the virtual route \"${id}\" was not found.`,\n      )\n    }\n\n    const rawGrouping = decodeIdentifier(splitValue)\n    const grouping = [...new Set(rawGrouping)].filter((p) =>\n      splitRouteIdentNodes.includes(p as any),\n    ) as Array<SplitRouteIdentNodes>\n\n    const baseId = id.split('?')[0]!\n    const resolvedSharedBindings = sharedBindingsMap.get(baseId)\n\n    const result = compileCodeSplitVirtualRoute({\n      code,\n      filename: id,\n      splitTargets: grouping,\n      sharedBindings: resolvedSharedBindings,\n    })\n\n    if (debug) {\n      logDiff(code, result.code)\n      console.log('Output:\\n', result.code + '\\n\\n')\n    }\n\n    return result\n  }\n\n  const includedCode = [\n    'createFileRoute(',\n    'createRootRoute(',\n    'createRootRouteWithContext(',\n  ]\n  return [\n    {\n      name: 'tanstack-router:code-splitter:compile-reference-file',\n      enforce: 'pre',\n\n      transform: {\n        filter: {\n          id: {\n            exclude: [tsrSplit, tsrShared],\n            // this is necessary for webpack / rspack to avoid matching .html files\n            include: /\\.(m|c)?(j|t)sx?$/,\n          },\n          code: {\n            include: includedCode,\n          },\n        },\n        handler(code, id) {\n          const normalizedId = normalizePath(id)\n          const generatorFileInfo =\n            globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId)\n          if (\n            generatorFileInfo &&\n            includedCode.some((included) => code.includes(included))\n          ) {\n            return handleCompilingReferenceFile(\n              code,\n              normalizedId,\n              generatorFileInfo,\n            )\n          }\n\n          return null\n        },\n      },\n\n      vite: {\n        configResolved(config) {\n          ROOT = config.root\n          initUserConfig()\n\n          // Validate plugin order - router must come before JSX transformation plugins\n          const routerPluginIndex = config.plugins.findIndex(\n            (p) => p.name === CODE_SPLITTER_PLUGIN_NAME,\n          )\n\n          if (routerPluginIndex === -1) return\n\n          const frameworkPlugins =\n            TRANSFORMATION_PLUGINS_BY_FRAMEWORK[userConfig.target]\n          if (!frameworkPlugins) return\n\n          for (const transformPlugin of frameworkPlugins) {\n            const transformPluginIndex = config.plugins.findIndex((p) =>\n              transformPlugin.pluginNames.includes(p.name),\n            )\n\n            if (\n              transformPluginIndex !== -1 &&\n              transformPluginIndex < routerPluginIndex\n            ) {\n              throw new Error(\n                `Plugin order error: '${transformPlugin.pkg}' is placed before '@tanstack/router-plugin'.\\n\\n` +\n                  `The TanStack Router plugin must come BEFORE JSX transformation plugins.\\n\\n` +\n                  `Please update your Vite config:\\n\\n` +\n                  `  plugins: [\\n` +\n                  `    tanstackRouter(),\\n` +\n                  `    ${transformPlugin.usage},\\n` +\n                  `  ]\\n`,\n              )\n            }\n          }\n        },\n        applyToEnvironment(environment) {\n          if (userConfig.plugin?.vite?.environmentName) {\n            return userConfig.plugin.vite.environmentName === environment.name\n          }\n          return true\n        },\n      },\n\n      rspack() {\n        ROOT = process.cwd()\n        initUserConfig()\n      },\n\n      webpack() {\n        ROOT = process.cwd()\n        initUserConfig()\n      },\n    },\n    {\n      name: 'tanstack-router:code-splitter:compile-virtual-file',\n      enforce: 'pre',\n\n      transform: {\n        filter: {\n          id: /tsr-split/,\n        },\n        handler(code, id) {\n          const url = pathToFileURL(id)\n          url.searchParams.delete('v')\n          const normalizedId = normalizePath(fileURLToPath(url))\n          return handleCompilingVirtualFile(code, normalizedId)\n        },\n      },\n\n      vite: {\n        applyToEnvironment(environment) {\n          if (userConfig.plugin?.vite?.environmentName) {\n            return userConfig.plugin.vite.environmentName === environment.name\n          }\n          return true\n        },\n      },\n    },\n    {\n      name: 'tanstack-router:code-splitter:compile-shared-file',\n      enforce: 'pre',\n\n      transform: {\n        filter: {\n          id: /tsr-shared/,\n        },\n        handler(code, id) {\n          const url = pathToFileURL(id)\n          url.searchParams.delete('v')\n          const normalizedId = normalizePath(fileURLToPath(url))\n          const [baseId] = normalizedId.split('?')\n\n          if (!baseId) return null\n\n          const sharedBindings = sharedBindingsMap.get(baseId)\n          if (!sharedBindings || sharedBindings.size === 0) return null\n\n          if (debug) console.info('Compiling Shared Module: ', id)\n\n          const result = compileCodeSplitSharedRoute({\n            code,\n            sharedBindings,\n            filename: normalizedId,\n          })\n\n          if (debug) {\n            logDiff(code, result.code)\n            console.log('Output:\\n', result.code + '\\n\\n')\n          }\n\n          return result\n        },\n      },\n\n      vite: {\n        applyToEnvironment(environment) {\n          if (userConfig.plugin?.vite?.environmentName) {\n            return userConfig.plugin.vite.environmentName === environment.name\n          }\n          return true\n        },\n      },\n    },\n  ]\n}\n"],"mappings":"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"}