UNPKG

@tanstack/react-start

Version:

Modern and scalable routing for React applications

123 lines (116 loc) 4.48 kB
import { START_ENVIRONMENT_NAMES, tanStackStartVite, } from '@tanstack/start-plugin-core' import type { TanStackStartViteInputConfig, TanStackStartVitePluginCoreOptions, } from '@tanstack/start-plugin-core' import { configureRsc, reactStartRscVitePlugin, } from '@tanstack/react-start-rsc/plugin/vite' import path from 'pathe' import { reactStartDefaultEntryPaths, reactStartPluginDir } from './shared' import type { PluginOption } from 'vite' const isInsideRouterMonoRepo = path.basename(path.resolve(reactStartPluginDir, '../../../../')) === 'packages' export function tanstackStart( options?: TanStackStartViteInputConfig & { rsc?: { enabled?: boolean } }, ): Array<PluginOption> { const rscEnabled = options?.rsc?.enabled ?? false const rscConfig = rscEnabled ? configureRsc() : undefined let corePluginOpts: TanStackStartVitePluginCoreOptions = { framework: 'react', defaultEntryPaths: reactStartDefaultEntryPaths, providerEnvironmentName: START_ENVIRONMENT_NAMES.server, ssrIsProvider: true, ssrResolverStrategy: { type: 'default', }, } const serverEnvironments: Array<string> = [ START_ENVIRONMENT_NAMES.server, ...(rscConfig ? [rscConfig.envName] : []), ] if (rscConfig) { corePluginOpts = { ...corePluginOpts, providerEnvironmentName: rscConfig.providerEnvironmentName, ssrIsProvider: false, ssrResolverStrategy: rscConfig.ssrResolverStrategy, serializationAdapters: rscConfig.serializationAdapters, } } return [ { name: 'tanstack-react-start:config', configEnvironment(environmentName, options) { const needsOptimizeDeps = environmentName === START_ENVIRONMENT_NAMES.client || (serverEnvironments.includes(environmentName) && // This indicates that the server environment has opted in to dependency optimization options.optimizeDeps?.noDiscovery === false) // Check if @tanstack/react-router is in noExternal (as array) const reactRouterInNoExternal = Array.isArray(options.resolve?.noExternal) && options.resolve.noExternal.some( (pattern) => pattern === '@tanstack/react-router' || (typeof pattern === 'string' && pattern.includes('react-router')), ) return { resolve: { dedupe: [ 'react', 'react-dom', '@tanstack/react-start', '@tanstack/react-router', ], // Don't mark react-router as external if: // 1. noExternal is true (bundle everything) // 2. We're not in the router monorepo // 3. react-router is explicitly in noExternal for this environment external: options.resolve?.noExternal === true || !isInsideRouterMonoRepo || reactRouterInNoExternal ? undefined : ['@tanstack/react-router', '@tanstack/react-router-devtools'], }, optimizeDeps: needsOptimizeDeps ? { // As `@tanstack/react-start` depends on `@tanstack/react-router`, we should exclude both. exclude: [ '@tanstack/react-start', '@tanstack/react-router', '@tanstack/react-router-devtools', '@tanstack/start-static-server-functions', ], include: [ 'react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom', ...(environmentName === START_ENVIRONMENT_NAMES.client ? ['react-dom/client'] : ['react-dom/server']), // `@tanstack/react-store` has a dependency on `use-sync-external-store`, which is CJS. // It therefore needs to be included so that it is converted to ESM. '@tanstack/react-router > @tanstack/react-store', ...(options.optimizeDeps?.exclude?.find( (x) => x === '@tanstack/react-form', ) ? ['@tanstack/react-form > @tanstack/react-store'] : []), ], } : undefined, } }, }, rscConfig ? reactStartRscVitePlugin() : null, tanStackStartVite(corePluginOpts, options), ] }