{"version":3,"file":"router-code-splitter-plugin.cjs","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 {\n  compileCodeSplitReferenceRoute,\n  compileCodeSplitVirtualRoute,\n  detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport {\n  defaultCodeSplitGroupings,\n  splitRouteIdentNodes,\n  tsrSplit,\n} from './constants'\nimport { decodeIdentifier } from './code-splitter/path-ids'\nimport { debug } from './utils'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type {\n  UnpluginContextMeta,\n  UnpluginFactory,\n  TransformResult as UnpluginTransformResult,\n} from 'unplugin'\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(\n    externalPlugin: BannedBeforeExternalPlugin,\n    pluginFramework: string,\n  ) {\n    super(`We detected that the '${externalPlugin.pkg}' was passed before '@tanstack/router-plugin/${pluginFramework}'. Please make sure that '@tanstack/router-plugin' is passed before '${externalPlugin.pkg}' and try again: \ne.g.\nplugins: [\n  tanstackRouter(), // 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  let ROOT: string = process.cwd()\n  let userConfig = options as Config\n\n  const isProduction = process.env.NODE_ENV === 'production'\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) {\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    const compiledReferenceRoute = compileCodeSplitReferenceRoute({\n      code,\n      runtimeEnv: isProduction ? 'prod' : 'dev',\n      codeSplitGroupings: splitGroupings,\n      targetFramework: userConfig.target,\n      filename: id,\n      id,\n    })\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 result = compileCodeSplitVirtualRoute({\n      code,\n      filename: id,\n      splitTargets: grouping,\n    })\n\n    if (debug) {\n      logDiff(code, result.code)\n      console.log('Output:\\n', result.code + '\\n\\n')\n    }\n\n    return result\n  }\n\n  return [\n    {\n      name: 'tanstack-router:code-splitter:compile-reference-file',\n      enforce: 'pre',\n\n      transform: {\n        filter: {\n          id: {\n            exclude: tsrSplit,\n          },\n          code: 'createFileRoute(',\n        },\n        handler(code, id) {\n          const generatorFileInfo = globalThis.TSR_ROUTES_BY_ID_MAP?.get(id)\n          if (generatorFileInfo && code.includes('createFileRoute(')) {\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 handleCompilingReferenceFile(code, id, generatorFileInfo)\n          }\n\n          return null\n        },\n      },\n\n      vite: {\n        configResolved(config) {\n          ROOT = config.root\n          userConfig = getConfig(options, ROOT)\n        },\n      },\n\n      rspack() {\n        ROOT = process.cwd()\n        userConfig = getConfig(options, ROOT)\n      },\n\n      webpack(compiler) {\n        ROOT = process.cwd()\n        userConfig = getConfig(options, ROOT)\n\n        if (compiler.options.mode === 'production') {\n          compiler.hooks.done.tap(PLUGIN_NAME, () => {\n            console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n            setTimeout(() => {\n              process.exit(0)\n            })\n          })\n        }\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          id = fileURLToPath(url).replace(/\\\\/g, '/')\n          return handleCompilingVirtualFile(code, id)\n        },\n      },\n    },\n  ]\n}\n"],"names":["defaultCodeSplitGroupings","debug","detectCodeSplitGroupingsFromRoute","splitGroupingsSchema","compileCodeSplitReferenceRoute","logDiff","tsrSplit","decodeIdentifier","splitRouteIdentNodes","compileCodeSplitVirtualRoute","config","getConfig","pathToFileURL","fileURLToPath"],"mappings":"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"}