@tanstack/start-plugin-core 1.169.11 → 1.169.13
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/esm/index.d.ts +1 -1
- package/dist/esm/rsbuild/index.d.ts +1 -0
- package/dist/esm/rsbuild/plugin.js +2 -0
- package/dist/esm/rsbuild/plugin.js.map +1 -1
- package/dist/esm/rsbuild/schema.d.ts +27 -27
- package/dist/esm/rsbuild/start-compiler-host.d.ts +3 -1
- package/dist/esm/rsbuild/start-compiler-host.js +6 -2
- package/dist/esm/rsbuild/start-compiler-host.js.map +1 -1
- package/dist/esm/schema.d.ts +51 -51
- package/dist/esm/start-compiler/compiler.d.ts +21 -5
- package/dist/esm/start-compiler/compiler.js +197 -48
- package/dist/esm/start-compiler/compiler.js.map +1 -1
- package/dist/esm/start-compiler/config.d.ts +7 -3
- package/dist/esm/start-compiler/config.js +19 -7
- package/dist/esm/start-compiler/config.js.map +1 -1
- package/dist/esm/start-compiler/handleCreateServerFn.js +12 -0
- package/dist/esm/start-compiler/handleCreateServerFn.js.map +1 -1
- package/dist/esm/start-compiler/host.d.ts +3 -1
- package/dist/esm/start-compiler/host.js +5 -3
- package/dist/esm/start-compiler/host.js.map +1 -1
- package/dist/esm/start-compiler/types.d.ts +4 -13
- package/dist/esm/types.d.ts +33 -0
- package/dist/esm/vite/index.d.ts +1 -0
- package/dist/esm/vite/plugin.js +2 -0
- package/dist/esm/vite/plugin.js.map +1 -1
- package/dist/esm/vite/schema.d.ts +27 -27
- package/dist/esm/vite/start-compiler-plugin/plugin.d.ts +3 -1
- package/dist/esm/vite/start-compiler-plugin/plugin.js +6 -2
- package/dist/esm/vite/start-compiler-plugin/plugin.js.map +1 -1
- package/package.json +6 -6
- package/src/index.ts +6 -1
- package/src/rsbuild/index.ts +5 -0
- package/src/rsbuild/plugin.ts +3 -0
- package/src/rsbuild/start-compiler-host.ts +22 -3
- package/src/start-compiler/compiler.ts +389 -70
- package/src/start-compiler/config.ts +43 -6
- package/src/start-compiler/handleCreateServerFn.ts +29 -0
- package/src/start-compiler/host.ts +13 -3
- package/src/start-compiler/types.ts +5 -14
- package/src/types.ts +44 -0
- package/src/vite/index.ts +5 -0
- package/src/vite/plugin.ts +3 -0
- package/src/vite/start-compiler-plugin/plugin.ts +22 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StartCompiler } from './compiler.js';
|
|
2
|
-
import { CompileStartFrameworkOptions } from '../types.js';
|
|
2
|
+
import { CompileStartFrameworkOptions, StartCompilerImportTransform } from '../types.js';
|
|
3
3
|
import { DevServerFnModuleSpecifierEncoder, GenerateFunctionIdFnOptional, ServerFn } from './types.js';
|
|
4
4
|
export interface CreateStartCompilerOptions {
|
|
5
5
|
env: 'client' | 'server';
|
|
@@ -9,6 +9,8 @@ export interface CreateStartCompilerOptions {
|
|
|
9
9
|
providerEnvName: string;
|
|
10
10
|
mode: 'dev' | 'build';
|
|
11
11
|
generateFunctionId?: GenerateFunctionIdFnOptional;
|
|
12
|
+
compilerTransforms?: Array<StartCompilerImportTransform> | undefined;
|
|
13
|
+
serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined;
|
|
12
14
|
onServerFnsById?: (d: Record<string, ServerFn>) => void;
|
|
13
15
|
getKnownServerFns: () => Record<string, ServerFn>;
|
|
14
16
|
encodeModuleSpecifierInDev?: DevServerFnModuleSpecifierEncoder;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StartCompiler, getLookupKindsForEnv } from "./compiler.js";
|
|
2
2
|
import { getLookupConfigurationsForEnv } from "./config.js";
|
|
3
3
|
//#region src/start-compiler/host.ts
|
|
4
4
|
function createStartCompiler(options) {
|
|
@@ -6,13 +6,15 @@ function createStartCompiler(options) {
|
|
|
6
6
|
env: options.env,
|
|
7
7
|
envName: options.envName,
|
|
8
8
|
root: options.root,
|
|
9
|
-
lookupKinds:
|
|
10
|
-
lookupConfigurations: getLookupConfigurationsForEnv(options.env, options.framework),
|
|
9
|
+
lookupKinds: getLookupKindsForEnv(options.env, { compilerTransforms: options.compilerTransforms }),
|
|
10
|
+
lookupConfigurations: getLookupConfigurationsForEnv(options.env, options.framework, { compilerTransforms: options.compilerTransforms }),
|
|
11
11
|
mode: options.mode,
|
|
12
12
|
framework: options.framework,
|
|
13
13
|
providerEnvName: options.providerEnvName,
|
|
14
14
|
generateFunctionId: options.generateFunctionId,
|
|
15
15
|
onServerFnsById: options.onServerFnsById,
|
|
16
|
+
compilerTransforms: options.compilerTransforms,
|
|
17
|
+
serverFnProviderModuleDirectives: options.serverFnProviderModuleDirectives,
|
|
16
18
|
getKnownServerFns: options.getKnownServerFns,
|
|
17
19
|
devServerFnModuleSpecifierEncoder: options.encodeModuleSpecifierInDev,
|
|
18
20
|
loadModule: options.loadModule,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","names":[],"sources":["../../../src/start-compiler/host.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"host.js","names":[],"sources":["../../../src/start-compiler/host.ts"],"sourcesContent":["import { StartCompiler, getLookupKindsForEnv } from './compiler'\nimport { getLookupConfigurationsForEnv } from './config'\nimport type {\n CompileStartFrameworkOptions,\n StartCompilerImportTransform,\n} from '../types'\nimport type {\n DevServerFnModuleSpecifierEncoder,\n GenerateFunctionIdFnOptional,\n ServerFn,\n} from './types'\n\nexport interface CreateStartCompilerOptions {\n env: 'client' | 'server'\n envName: string\n root: string\n framework: CompileStartFrameworkOptions\n providerEnvName: string\n mode: 'dev' | 'build'\n generateFunctionId?: GenerateFunctionIdFnOptional\n compilerTransforms?: Array<StartCompilerImportTransform> | undefined\n serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined\n onServerFnsById?: (d: Record<string, ServerFn>) => void\n getKnownServerFns: () => Record<string, ServerFn>\n encodeModuleSpecifierInDev?: DevServerFnModuleSpecifierEncoder\n loadModule: (id: string) => Promise<void>\n resolveId: (id: string, importer?: string) => Promise<string | null>\n}\n\nexport function createStartCompiler(\n options: CreateStartCompilerOptions,\n): StartCompiler {\n return new StartCompiler({\n env: options.env,\n envName: options.envName,\n root: options.root,\n lookupKinds: getLookupKindsForEnv(options.env, {\n compilerTransforms: options.compilerTransforms,\n }),\n lookupConfigurations: getLookupConfigurationsForEnv(\n options.env,\n options.framework,\n { compilerTransforms: options.compilerTransforms },\n ),\n mode: options.mode,\n framework: options.framework,\n providerEnvName: options.providerEnvName,\n generateFunctionId: options.generateFunctionId,\n onServerFnsById: options.onServerFnsById,\n compilerTransforms: options.compilerTransforms,\n serverFnProviderModuleDirectives: options.serverFnProviderModuleDirectives,\n getKnownServerFns: options.getKnownServerFns,\n devServerFnModuleSpecifierEncoder: options.encodeModuleSpecifierInDev,\n loadModule: options.loadModule,\n resolveId: options.resolveId,\n })\n}\n\nexport function mergeServerFnsById(\n current: Record<string, ServerFn>,\n next: Record<string, ServerFn>,\n): void {\n for (const [id, fn] of Object.entries(next)) {\n const existing = current[id]\n\n if (existing) {\n current[id] = {\n ...fn,\n isClientReferenced:\n existing.isClientReferenced || fn.isClientReferenced,\n }\n continue\n }\n\n current[id] = fn\n }\n}\n\nexport function matchesCodeFilters(\n code: string,\n filters: ReadonlyArray<RegExp>,\n): boolean {\n for (const pattern of filters) {\n if (pattern.test(code)) {\n return true\n }\n }\n\n return false\n}\n"],"mappings":";;;AA6BA,SAAgB,oBACd,SACe;AACf,QAAO,IAAI,cAAc;EACvB,KAAK,QAAQ;EACb,SAAS,QAAQ;EACjB,MAAM,QAAQ;EACd,aAAa,qBAAqB,QAAQ,KAAK,EAC7C,oBAAoB,QAAQ,oBAC7B,CAAC;EACF,sBAAsB,8BACpB,QAAQ,KACR,QAAQ,WACR,EAAE,oBAAoB,QAAQ,oBAAoB,CACnD;EACD,MAAM,QAAQ;EACd,WAAW,QAAQ;EACnB,iBAAiB,QAAQ;EACzB,oBAAoB,QAAQ;EAC5B,iBAAiB,QAAQ;EACzB,oBAAoB,QAAQ;EAC5B,kCAAkC,QAAQ;EAC1C,mBAAmB,QAAQ;EAC3B,mCAAmC,QAAQ;EAC3C,YAAY,QAAQ;EACpB,WAAW,QAAQ;EACpB,CAAC;;AAGJ,SAAgB,mBACd,SACA,MACM;AACN,MAAK,MAAM,CAAC,IAAI,OAAO,OAAO,QAAQ,KAAK,EAAE;EAC3C,MAAM,WAAW,QAAQ;AAEzB,MAAI,UAAU;AACZ,WAAQ,MAAM;IACZ,GAAG;IACH,oBACE,SAAS,sBAAsB,GAAG;IACrC;AACD;;AAGF,UAAQ,MAAM;;;AAIlB,SAAgB,mBACd,MACA,SACS;AACT,MAAK,MAAM,WAAW,QACpB,KAAI,QAAQ,KAAK,KAAK,CACpB,QAAO;AAIX,QAAO"}
|
|
@@ -1,26 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StartCompilerTransformContext } from '../types.js';
|
|
2
2
|
import type * as babel from '@babel/core';
|
|
3
3
|
import type * as t from '@babel/types';
|
|
4
4
|
/**
|
|
5
5
|
* Context passed to all plugin handlers during compilation.
|
|
6
6
|
* Contains both read-only input data and mutable state that handlers update.
|
|
7
7
|
*/
|
|
8
|
-
export interface CompilationContext {
|
|
9
|
-
readonly ast: t.File;
|
|
10
|
-
readonly code: string;
|
|
11
|
-
readonly id: string;
|
|
12
|
-
readonly env: 'client' | 'server';
|
|
13
|
-
readonly envName: string;
|
|
14
|
-
readonly mode: 'dev' | 'build';
|
|
15
|
-
readonly root: string;
|
|
16
|
-
/** The framework being used (e.g., 'react', 'solid') */
|
|
17
|
-
readonly framework: CompileStartFrameworkOptions;
|
|
18
|
-
/** The Vite environment name for the server function provider */
|
|
19
|
-
readonly providerEnvName: string;
|
|
8
|
+
export interface CompilationContext extends StartCompilerTransformContext {
|
|
20
9
|
/** Generate a unique function ID */
|
|
21
10
|
generateFunctionId: GenerateFunctionIdFn;
|
|
22
11
|
/** Get known server functions from previous builds (e.g., client build) */
|
|
23
12
|
getKnownServerFns: () => Record<string, ServerFn>;
|
|
13
|
+
/** Module-level directives to add to extracted server function provider files. */
|
|
14
|
+
serverFnProviderModuleDirectives: ReadonlyArray<string> | undefined;
|
|
24
15
|
/**
|
|
25
16
|
* Callback when server functions are discovered.
|
|
26
17
|
* Called after each file is compiled with its new functions.
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { TanStackStartOutputConfig } from './schema.js';
|
|
2
|
+
import type * as babel from '@babel/core';
|
|
3
|
+
import type * as t from '@babel/types';
|
|
2
4
|
export type CompileStartFrameworkOptions = 'react' | 'solid' | 'vue';
|
|
3
5
|
export type ServerFnLookupAccess = {
|
|
4
6
|
origin: 'client';
|
|
@@ -13,6 +15,35 @@ export interface SerializationAdapterModuleRef {
|
|
|
13
15
|
}
|
|
14
16
|
export type SerializationAdapterByRuntime = Partial<Record<SerializationRuntime, SerializationAdapterModuleRef>>;
|
|
15
17
|
export type SerializationAdapterConfig = SerializationAdapterModuleRef | SerializationAdapterByRuntime;
|
|
18
|
+
export type StartCompilerEnvironment = 'client' | 'server';
|
|
19
|
+
export interface StartCompilerImportTransformImport {
|
|
20
|
+
libName: string;
|
|
21
|
+
rootExport: string;
|
|
22
|
+
}
|
|
23
|
+
export interface StartCompilerTransformCandidate {
|
|
24
|
+
path: babel.NodePath<t.CallExpression>;
|
|
25
|
+
}
|
|
26
|
+
export interface StartCompilerTransformContext {
|
|
27
|
+
readonly ast: t.File;
|
|
28
|
+
readonly code: string;
|
|
29
|
+
readonly id: string;
|
|
30
|
+
readonly env: StartCompilerEnvironment;
|
|
31
|
+
readonly envName: string;
|
|
32
|
+
readonly mode: 'dev' | 'build';
|
|
33
|
+
readonly root: string;
|
|
34
|
+
readonly framework: CompileStartFrameworkOptions;
|
|
35
|
+
readonly providerEnvName: string;
|
|
36
|
+
readonly types: typeof t;
|
|
37
|
+
parseExpression: (code: string) => t.Expression;
|
|
38
|
+
}
|
|
39
|
+
export interface StartCompilerImportTransform {
|
|
40
|
+
name: string;
|
|
41
|
+
environment?: StartCompilerEnvironment | Array<StartCompilerEnvironment> | undefined;
|
|
42
|
+
imports: Array<StartCompilerImportTransformImport>;
|
|
43
|
+
detect: RegExp;
|
|
44
|
+
order?: 'pre' | 'post' | undefined;
|
|
45
|
+
transform: (candidates: Array<StartCompilerTransformCandidate>, context: StartCompilerTransformContext) => void;
|
|
46
|
+
}
|
|
16
47
|
export interface NormalizedBasePaths {
|
|
17
48
|
publicBase: string;
|
|
18
49
|
assetBase: {
|
|
@@ -49,6 +80,8 @@ export interface TanStackStartCoreOptions {
|
|
|
49
80
|
providerEnvironmentName: string;
|
|
50
81
|
ssrIsProvider: boolean;
|
|
51
82
|
serializationAdapters?: Array<SerializationAdapterConfig> | undefined;
|
|
83
|
+
compilerTransforms?: Array<StartCompilerImportTransform> | undefined;
|
|
84
|
+
serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined;
|
|
52
85
|
}
|
|
53
86
|
export interface ResolvedStartConfig {
|
|
54
87
|
root: string;
|
package/dist/esm/vite/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type { TanStackStartVitePluginCoreOptions, ViteRscForwardSsrResolverStrategy, } from './types.js';
|
|
2
2
|
export type { TanStackStartViteInputConfig } from './schema.js';
|
|
3
|
+
export type { StartCompilerImportTransform, StartCompilerTransformCandidate, StartCompilerTransformContext, } from '../types.js';
|
|
3
4
|
export { START_ENVIRONMENT_NAMES, VITE_ENVIRONMENT_NAMES } from '../constants.js';
|
|
4
5
|
export { createVirtualModule } from './createVirtualModule.js';
|
|
5
6
|
export { tanStackStartVite } from './plugin.js';
|
package/dist/esm/vite/plugin.js
CHANGED
|
@@ -126,6 +126,8 @@ function tanStackStartVite(corePluginOpts, startPluginOpts) {
|
|
|
126
126
|
framework: corePluginOpts.framework,
|
|
127
127
|
environments,
|
|
128
128
|
generateFunctionId: normalizedStartPluginOpts.serverFns?.generateFunctionId,
|
|
129
|
+
compilerTransforms: corePluginOpts.compilerTransforms,
|
|
130
|
+
serverFnProviderModuleDirectives: corePluginOpts.serverFnProviderModuleDirectives,
|
|
129
131
|
providerEnvName: serverFnProviderEnv
|
|
130
132
|
}),
|
|
131
133
|
importProtectionPlugin({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[],"sources":["../../../src/vite/plugin.ts"],"sourcesContent":["import { crawlFrameworkPkgs } from 'vitefu'\nimport {\n applyResolvedBaseAndOutput,\n applyResolvedRouterBasepath,\n createStartConfigContext,\n} from '../config-context'\nimport { START_ENVIRONMENT_NAMES } from '../constants'\nimport {\n createServerFnBasePath,\n normalizePublicBase,\n shouldRewriteDevBasepath,\n} from '../planning'\nimport { importProtectionPlugin } from './import-protection-plugin/plugin'\nimport { startCompilerPlugin } from './start-compiler-plugin/plugin'\nimport { loadEnvPlugin } from './load-env-plugin/plugin'\nimport {\n buildStartViteEnvironments,\n createViteConfigPlan,\n createViteDefineConfig,\n createViteResolvedEntryAliases,\n} from './planning'\nimport { devServerPlugin } from './dev-server-plugin/plugin'\nimport { previewServerPlugin } from './preview-server-plugin/plugin'\nimport {\n createDevBaseRewritePlugin,\n createPostBuildPlugin,\n createVirtualClientEntryPlugin,\n} from './plugins'\nimport { parseStartConfig } from './schema'\nimport { startManifestPlugin } from './start-manifest-plugin/plugin'\nimport { tanStackStartRouter } from './start-router-plugin/plugin'\nimport {\n getClientOutputDirectory,\n getServerOutputDirectory,\n} from './output-directory'\nimport { postServerBuild } from './post-server-build'\nimport { serializationAdaptersPlugin } from './serialization-adapters-plugin'\nimport type {\n TanStackStartVitePluginCoreOptions,\n ViteRscForwardSsrResolverStrategy,\n} from './types'\nimport type { TanStackStartViteInputConfig } from './schema'\nimport type { PluginOption } from 'vite'\n\nexport function tanStackStartVite(\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n startPluginOpts: TanStackStartViteInputConfig | undefined,\n): Array<PluginOption> {\n const normalizedStartPluginOpts = startPluginOpts ?? {}\n\n const configContext = createStartConfigContext({\n corePluginOpts,\n startPluginOpts: normalizedStartPluginOpts,\n parseConfig: parseStartConfig,\n })\n const { getConfig, resolvedStartConfig } = configContext\n const serverFnProviderEnv = corePluginOpts.providerEnvironmentName\n const ssrIsProvider = corePluginOpts.ssrIsProvider\n\n // When the router basepath and vite base are misaligned during dev,\n // we install a URL rewrite middleware instead of erroring.\n let needsDevBaseRewrite = false\n\n const environments: Array<{\n name: string\n type: 'client' | 'server'\n getServerFnById?: string\n }> = [\n { name: START_ENVIRONMENT_NAMES.client, type: 'client' },\n {\n name: START_ENVIRONMENT_NAMES.server,\n type: 'server',\n getServerFnById:\n corePluginOpts.ssrResolverStrategy.type === 'vite-rsc-forward'\n ? createViteRscForwarder(corePluginOpts.ssrResolverStrategy)\n : undefined,\n },\n ]\n if (\n serverFnProviderEnv !== START_ENVIRONMENT_NAMES.server &&\n !environments.find((e) => e.name === serverFnProviderEnv)\n ) {\n environments.push({\n name: serverFnProviderEnv,\n type: 'server',\n })\n }\n return [\n {\n name: 'tanstack-start-core:config',\n enforce: 'pre',\n async config(viteConfig, { command }) {\n const publicBase = normalizePublicBase(viteConfig.base)\n applyResolvedBaseAndOutput({\n resolvedStartConfig,\n root: viteConfig.root || process.cwd(),\n publicBase,\n clientOutputDirectory: getClientOutputDirectory(viteConfig),\n serverOutputDirectory: getServerOutputDirectory(viteConfig),\n })\n const { startConfig } = getConfig()\n const routerBasepath = applyResolvedRouterBasepath({\n resolvedStartConfig,\n startConfig,\n })\n\n if (\n shouldRewriteDevBasepath({\n command,\n middlewareMode: Boolean(viteConfig.server?.middlewareMode),\n routerBasepath,\n publicBase: resolvedStartConfig.basePaths.publicBase,\n })\n ) {\n // The router basepath and vite base are misaligned.\n // Instead of erroring, we install a dev-server middleware that\n // rewrites incoming request URLs to prepend the vite base prefix.\n // This allows users to have e.g. base: '/_ui/' for asset URLs\n // while keeping router basepath at '/' for page navigation.\n needsDevBaseRewrite = true\n }\n\n const TSS_SERVER_FN_BASE = createServerFnBasePath({\n routerBasepath,\n serverFnBase: startConfig.serverFns.base,\n })\n const resolvedEntryPlan = configContext.resolveEntries()\n\n const entryAliases = createViteResolvedEntryAliases({\n entryPaths: resolvedEntryPlan.entryPaths,\n })\n\n const startPackageName =\n `@tanstack/${corePluginOpts.framework}-start` as const\n\n // crawl packages that have start in \"peerDependencies\"\n // see https://github.com/svitejs/vitefu/blob/d8d82fa121e3b2215ba437107093c77bde51b63b/src/index.js#L95-L101\n\n // this is currently uncached; could be implemented similarly as vite handles lock file changes\n // see https://github.com/vitejs/vite/blob/557f797d29422027e8c451ca50dd84bf8c41b5f0/packages/vite/src/node/optimizer/index.ts#L1282\n\n const crawlFrameworkPkgsResult = await crawlFrameworkPkgs({\n root: process.cwd(),\n isBuild: command === 'build',\n isFrameworkPkgByJson(pkgJson) {\n const peerDependencies = pkgJson['peerDependencies']\n\n if (peerDependencies) {\n if (\n startPackageName in peerDependencies ||\n '@tanstack/start-client-core' in peerDependencies\n ) {\n return true\n }\n }\n\n return false\n },\n })\n\n const viteConfigPlan = createViteConfigPlan({\n viteConfig,\n framework: corePluginOpts.framework,\n entryAliases,\n clientOutputDirectory: resolvedStartConfig.outputDirectories.client,\n serverOutputDirectory: resolvedStartConfig.outputDirectories.server,\n serverFnProviderEnv,\n optimizeDepsExclude: crawlFrameworkPkgsResult.optimizeDeps.exclude,\n noExternal: crawlFrameworkPkgsResult.ssr.noExternal.sort(),\n })\n\n return {\n // see https://vite.dev/config/shared-options.html#apptype\n // this will prevent vite from injecting middlewares that we don't want\n appType: viteConfig.appType ?? 'custom',\n environments: viteConfigPlan.environments,\n resolve: viteConfigPlan.resolve,\n define: createViteDefineConfig({\n command,\n mode: viteConfig.mode,\n serverFnBase: TSS_SERVER_FN_BASE,\n routerBasepath,\n spaEnabled: startConfig.spa?.enabled,\n devSsrStylesEnabled: startConfig.dev.ssrStyles.enabled,\n devSsrStylesBasepath:\n startConfig.dev.ssrStyles.basepath ??\n resolvedStartConfig.basePaths.publicBase,\n inlineCssEnabled:\n command === 'build' && startConfig.server.build.inlineCss,\n staticNodeEnv: startConfig.server.build.staticNodeEnv,\n }),\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n await buildStartViteEnvironments({\n builder,\n providerEnvironmentName: serverFnProviderEnv,\n ssrIsProvider,\n })\n },\n },\n }\n },\n },\n createPostBuildPlugin({\n getConfig,\n postServerBuild,\n }),\n // Server function plugin handles:\n // 1. Identifying createServerFn().handler() calls\n // 2. Extracting server functions to separate modules\n // 3. Replacing call sites with RPC stubs\n // 4. Generating the server function manifest\n // Also handles createIsomorphicFn, createServerOnlyFn, createClientOnlyFn, createMiddleware\n startCompilerPlugin({\n framework: corePluginOpts.framework,\n environments,\n generateFunctionId:\n normalizedStartPluginOpts.serverFns?.generateFunctionId,\n providerEnvName: serverFnProviderEnv,\n }),\n importProtectionPlugin({\n getConfig,\n framework: corePluginOpts.framework,\n environments,\n providerEnvName: serverFnProviderEnv,\n }),\n tanStackStartRouter(normalizedStartPluginOpts, getConfig, corePluginOpts),\n loadEnvPlugin(),\n createVirtualClientEntryPlugin({\n getClientEntry: () => configContext.resolveEntries().entryPaths.client,\n }),\n startManifestPlugin({\n getConfig,\n }),\n // When the vite base and router basepath are misaligned (e.g. base: '/_ui/', basepath: '/'),\n // install a middleware that rewrites incoming request URLs to prepend the vite base prefix.\n // This allows Vite's internal base middleware to accept the requests, then strips the prefix\n // before passing to the SSR handler.\n // Registered BEFORE devServerPlugin so this middleware is added to the Connect stack first,\n // ensuring all subsequent middlewares (CSS, SSR, etc.) see the rewritten URL.\n createDevBaseRewritePlugin({\n shouldRewriteDevBase: () => needsDevBaseRewrite,\n resolvedStartConfig,\n }),\n devServerPlugin({\n getConfig,\n devSsrStylesEnabled:\n normalizedStartPluginOpts.dev?.ssrStyles?.enabled ?? true,\n installDevServerMiddleware:\n normalizedStartPluginOpts.vite?.installDevServerMiddleware,\n }),\n previewServerPlugin(),\n serializationAdaptersPlugin({\n adapters: corePluginOpts.serializationAdapters,\n }),\n ]\n}\n\nfunction createViteRscForwarder(strategy: ViteRscForwardSsrResolverStrategy) {\n return `export async function getServerFnById(id, access) {\n const m = await import.meta.viteRsc.loadModule(${JSON.stringify(strategy.sourceEnvironmentName)}, ${JSON.stringify(strategy.sourceEntry)})\n return m[${JSON.stringify(strategy.exportName)}](id, access)\n}`\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","names":[],"sources":["../../../src/vite/plugin.ts"],"sourcesContent":["import { crawlFrameworkPkgs } from 'vitefu'\nimport {\n applyResolvedBaseAndOutput,\n applyResolvedRouterBasepath,\n createStartConfigContext,\n} from '../config-context'\nimport { START_ENVIRONMENT_NAMES } from '../constants'\nimport {\n createServerFnBasePath,\n normalizePublicBase,\n shouldRewriteDevBasepath,\n} from '../planning'\nimport { importProtectionPlugin } from './import-protection-plugin/plugin'\nimport { startCompilerPlugin } from './start-compiler-plugin/plugin'\nimport { loadEnvPlugin } from './load-env-plugin/plugin'\nimport {\n buildStartViteEnvironments,\n createViteConfigPlan,\n createViteDefineConfig,\n createViteResolvedEntryAliases,\n} from './planning'\nimport { devServerPlugin } from './dev-server-plugin/plugin'\nimport { previewServerPlugin } from './preview-server-plugin/plugin'\nimport {\n createDevBaseRewritePlugin,\n createPostBuildPlugin,\n createVirtualClientEntryPlugin,\n} from './plugins'\nimport { parseStartConfig } from './schema'\nimport { startManifestPlugin } from './start-manifest-plugin/plugin'\nimport { tanStackStartRouter } from './start-router-plugin/plugin'\nimport {\n getClientOutputDirectory,\n getServerOutputDirectory,\n} from './output-directory'\nimport { postServerBuild } from './post-server-build'\nimport { serializationAdaptersPlugin } from './serialization-adapters-plugin'\nimport type {\n TanStackStartVitePluginCoreOptions,\n ViteRscForwardSsrResolverStrategy,\n} from './types'\nimport type { TanStackStartViteInputConfig } from './schema'\nimport type { PluginOption } from 'vite'\n\nexport function tanStackStartVite(\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n startPluginOpts: TanStackStartViteInputConfig | undefined,\n): Array<PluginOption> {\n const normalizedStartPluginOpts = startPluginOpts ?? {}\n\n const configContext = createStartConfigContext({\n corePluginOpts,\n startPluginOpts: normalizedStartPluginOpts,\n parseConfig: parseStartConfig,\n })\n const { getConfig, resolvedStartConfig } = configContext\n const serverFnProviderEnv = corePluginOpts.providerEnvironmentName\n const ssrIsProvider = corePluginOpts.ssrIsProvider\n\n // When the router basepath and vite base are misaligned during dev,\n // we install a URL rewrite middleware instead of erroring.\n let needsDevBaseRewrite = false\n\n const environments: Array<{\n name: string\n type: 'client' | 'server'\n getServerFnById?: string\n }> = [\n { name: START_ENVIRONMENT_NAMES.client, type: 'client' },\n {\n name: START_ENVIRONMENT_NAMES.server,\n type: 'server',\n getServerFnById:\n corePluginOpts.ssrResolverStrategy.type === 'vite-rsc-forward'\n ? createViteRscForwarder(corePluginOpts.ssrResolverStrategy)\n : undefined,\n },\n ]\n if (\n serverFnProviderEnv !== START_ENVIRONMENT_NAMES.server &&\n !environments.find((e) => e.name === serverFnProviderEnv)\n ) {\n environments.push({\n name: serverFnProviderEnv,\n type: 'server',\n })\n }\n return [\n {\n name: 'tanstack-start-core:config',\n enforce: 'pre',\n async config(viteConfig, { command }) {\n const publicBase = normalizePublicBase(viteConfig.base)\n applyResolvedBaseAndOutput({\n resolvedStartConfig,\n root: viteConfig.root || process.cwd(),\n publicBase,\n clientOutputDirectory: getClientOutputDirectory(viteConfig),\n serverOutputDirectory: getServerOutputDirectory(viteConfig),\n })\n const { startConfig } = getConfig()\n const routerBasepath = applyResolvedRouterBasepath({\n resolvedStartConfig,\n startConfig,\n })\n\n if (\n shouldRewriteDevBasepath({\n command,\n middlewareMode: Boolean(viteConfig.server?.middlewareMode),\n routerBasepath,\n publicBase: resolvedStartConfig.basePaths.publicBase,\n })\n ) {\n // The router basepath and vite base are misaligned.\n // Instead of erroring, we install a dev-server middleware that\n // rewrites incoming request URLs to prepend the vite base prefix.\n // This allows users to have e.g. base: '/_ui/' for asset URLs\n // while keeping router basepath at '/' for page navigation.\n needsDevBaseRewrite = true\n }\n\n const TSS_SERVER_FN_BASE = createServerFnBasePath({\n routerBasepath,\n serverFnBase: startConfig.serverFns.base,\n })\n const resolvedEntryPlan = configContext.resolveEntries()\n\n const entryAliases = createViteResolvedEntryAliases({\n entryPaths: resolvedEntryPlan.entryPaths,\n })\n\n const startPackageName =\n `@tanstack/${corePluginOpts.framework}-start` as const\n\n // crawl packages that have start in \"peerDependencies\"\n // see https://github.com/svitejs/vitefu/blob/d8d82fa121e3b2215ba437107093c77bde51b63b/src/index.js#L95-L101\n\n // this is currently uncached; could be implemented similarly as vite handles lock file changes\n // see https://github.com/vitejs/vite/blob/557f797d29422027e8c451ca50dd84bf8c41b5f0/packages/vite/src/node/optimizer/index.ts#L1282\n\n const crawlFrameworkPkgsResult = await crawlFrameworkPkgs({\n root: process.cwd(),\n isBuild: command === 'build',\n isFrameworkPkgByJson(pkgJson) {\n const peerDependencies = pkgJson['peerDependencies']\n\n if (peerDependencies) {\n if (\n startPackageName in peerDependencies ||\n '@tanstack/start-client-core' in peerDependencies\n ) {\n return true\n }\n }\n\n return false\n },\n })\n\n const viteConfigPlan = createViteConfigPlan({\n viteConfig,\n framework: corePluginOpts.framework,\n entryAliases,\n clientOutputDirectory: resolvedStartConfig.outputDirectories.client,\n serverOutputDirectory: resolvedStartConfig.outputDirectories.server,\n serverFnProviderEnv,\n optimizeDepsExclude: crawlFrameworkPkgsResult.optimizeDeps.exclude,\n noExternal: crawlFrameworkPkgsResult.ssr.noExternal.sort(),\n })\n\n return {\n // see https://vite.dev/config/shared-options.html#apptype\n // this will prevent vite from injecting middlewares that we don't want\n appType: viteConfig.appType ?? 'custom',\n environments: viteConfigPlan.environments,\n resolve: viteConfigPlan.resolve,\n define: createViteDefineConfig({\n command,\n mode: viteConfig.mode,\n serverFnBase: TSS_SERVER_FN_BASE,\n routerBasepath,\n spaEnabled: startConfig.spa?.enabled,\n devSsrStylesEnabled: startConfig.dev.ssrStyles.enabled,\n devSsrStylesBasepath:\n startConfig.dev.ssrStyles.basepath ??\n resolvedStartConfig.basePaths.publicBase,\n inlineCssEnabled:\n command === 'build' && startConfig.server.build.inlineCss,\n staticNodeEnv: startConfig.server.build.staticNodeEnv,\n }),\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n await buildStartViteEnvironments({\n builder,\n providerEnvironmentName: serverFnProviderEnv,\n ssrIsProvider,\n })\n },\n },\n }\n },\n },\n createPostBuildPlugin({\n getConfig,\n postServerBuild,\n }),\n // Server function plugin handles:\n // 1. Identifying createServerFn().handler() calls\n // 2. Extracting server functions to separate modules\n // 3. Replacing call sites with RPC stubs\n // 4. Generating the server function manifest\n // Also handles createIsomorphicFn, createServerOnlyFn, createClientOnlyFn, createMiddleware\n startCompilerPlugin({\n framework: corePluginOpts.framework,\n environments,\n generateFunctionId:\n normalizedStartPluginOpts.serverFns?.generateFunctionId,\n compilerTransforms: corePluginOpts.compilerTransforms,\n serverFnProviderModuleDirectives:\n corePluginOpts.serverFnProviderModuleDirectives,\n providerEnvName: serverFnProviderEnv,\n }),\n importProtectionPlugin({\n getConfig,\n framework: corePluginOpts.framework,\n environments,\n providerEnvName: serverFnProviderEnv,\n }),\n tanStackStartRouter(normalizedStartPluginOpts, getConfig, corePluginOpts),\n loadEnvPlugin(),\n createVirtualClientEntryPlugin({\n getClientEntry: () => configContext.resolveEntries().entryPaths.client,\n }),\n startManifestPlugin({\n getConfig,\n }),\n // When the vite base and router basepath are misaligned (e.g. base: '/_ui/', basepath: '/'),\n // install a middleware that rewrites incoming request URLs to prepend the vite base prefix.\n // This allows Vite's internal base middleware to accept the requests, then strips the prefix\n // before passing to the SSR handler.\n // Registered BEFORE devServerPlugin so this middleware is added to the Connect stack first,\n // ensuring all subsequent middlewares (CSS, SSR, etc.) see the rewritten URL.\n createDevBaseRewritePlugin({\n shouldRewriteDevBase: () => needsDevBaseRewrite,\n resolvedStartConfig,\n }),\n devServerPlugin({\n getConfig,\n devSsrStylesEnabled:\n normalizedStartPluginOpts.dev?.ssrStyles?.enabled ?? true,\n installDevServerMiddleware:\n normalizedStartPluginOpts.vite?.installDevServerMiddleware,\n }),\n previewServerPlugin(),\n serializationAdaptersPlugin({\n adapters: corePluginOpts.serializationAdapters,\n }),\n ]\n}\n\nfunction createViteRscForwarder(strategy: ViteRscForwardSsrResolverStrategy) {\n return `export async function getServerFnById(id, access) {\n const m = await import.meta.viteRsc.loadModule(${JSON.stringify(strategy.sourceEnvironmentName)}, ${JSON.stringify(strategy.sourceEntry)})\n return m[${JSON.stringify(strategy.exportName)}](id, access)\n}`\n}\n"],"mappings":"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"}
|
|
@@ -224,11 +224,11 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
|
|
|
224
224
|
};
|
|
225
225
|
entry?: string | undefined;
|
|
226
226
|
}, {
|
|
227
|
-
entry?: string | undefined;
|
|
228
227
|
build?: {
|
|
229
228
|
staticNodeEnv?: boolean | undefined;
|
|
230
229
|
inlineCss?: boolean | undefined;
|
|
231
230
|
} | undefined;
|
|
231
|
+
entry?: string | undefined;
|
|
232
232
|
}>>>;
|
|
233
233
|
serverFns: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
234
234
|
base: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
@@ -2294,11 +2294,11 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
|
|
|
2294
2294
|
dev: z.ZodOptional<z.ZodEnum<["error", "mock"]>>;
|
|
2295
2295
|
build: z.ZodOptional<z.ZodEnum<["error", "mock"]>>;
|
|
2296
2296
|
}, "strip", z.ZodTypeAny, {
|
|
2297
|
-
build?: "error" | "mock" | undefined;
|
|
2298
2297
|
dev?: "error" | "mock" | undefined;
|
|
2299
|
-
}, {
|
|
2300
2298
|
build?: "error" | "mock" | undefined;
|
|
2299
|
+
}, {
|
|
2301
2300
|
dev?: "error" | "mock" | undefined;
|
|
2301
|
+
build?: "error" | "mock" | undefined;
|
|
2302
2302
|
}>]>>;
|
|
2303
2303
|
mockAccess: z.ZodOptional<z.ZodEnum<["error", "warn", "off"]>>;
|
|
2304
2304
|
onViolation: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodUnion<[z.ZodBoolean, z.ZodVoid, z.ZodPromise<z.ZodUnion<[z.ZodBoolean, z.ZodVoid]>>]>>>;
|
|
@@ -2347,8 +2347,8 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
|
|
|
2347
2347
|
exclude?: (string | RegExp)[] | undefined;
|
|
2348
2348
|
enabled?: boolean | undefined;
|
|
2349
2349
|
behavior?: "error" | "mock" | {
|
|
2350
|
-
build?: "error" | "mock" | undefined;
|
|
2351
2350
|
dev?: "error" | "mock" | undefined;
|
|
2351
|
+
build?: "error" | "mock" | undefined;
|
|
2352
2352
|
} | undefined;
|
|
2353
2353
|
mockAccess?: "error" | "warn" | "off" | undefined;
|
|
2354
2354
|
onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
|
|
@@ -2370,8 +2370,8 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
|
|
|
2370
2370
|
exclude?: (string | RegExp)[] | undefined;
|
|
2371
2371
|
enabled?: boolean | undefined;
|
|
2372
2372
|
behavior?: "error" | "mock" | {
|
|
2373
|
-
build?: "error" | "mock" | undefined;
|
|
2374
2373
|
dev?: "error" | "mock" | undefined;
|
|
2374
|
+
build?: "error" | "mock" | undefined;
|
|
2375
2375
|
} | undefined;
|
|
2376
2376
|
mockAccess?: "error" | "warn" | "off" | undefined;
|
|
2377
2377
|
onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
|
|
@@ -2400,6 +2400,12 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
|
|
|
2400
2400
|
};
|
|
2401
2401
|
entry?: string | undefined;
|
|
2402
2402
|
};
|
|
2403
|
+
dev: {
|
|
2404
|
+
ssrStyles: {
|
|
2405
|
+
enabled: boolean;
|
|
2406
|
+
basepath?: string | undefined;
|
|
2407
|
+
};
|
|
2408
|
+
};
|
|
2403
2409
|
srcDirectory: string;
|
|
2404
2410
|
start: {
|
|
2405
2411
|
entry?: string | undefined;
|
|
@@ -2525,12 +2531,6 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
|
|
|
2525
2531
|
headers?: Record<string, string> | undefined;
|
|
2526
2532
|
} | undefined;
|
|
2527
2533
|
}[];
|
|
2528
|
-
dev: {
|
|
2529
|
-
ssrStyles: {
|
|
2530
|
-
enabled: boolean;
|
|
2531
|
-
basepath?: string | undefined;
|
|
2532
|
-
};
|
|
2533
|
-
};
|
|
2534
2534
|
sitemap?: {
|
|
2535
2535
|
enabled: boolean;
|
|
2536
2536
|
outputPath: string;
|
|
@@ -2704,8 +2704,8 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
|
|
|
2704
2704
|
exclude?: (string | RegExp)[] | undefined;
|
|
2705
2705
|
enabled?: boolean | undefined;
|
|
2706
2706
|
behavior?: "error" | "mock" | {
|
|
2707
|
-
build?: "error" | "mock" | undefined;
|
|
2708
2707
|
dev?: "error" | "mock" | undefined;
|
|
2708
|
+
build?: "error" | "mock" | undefined;
|
|
2709
2709
|
} | undefined;
|
|
2710
2710
|
mockAccess?: "error" | "warn" | "off" | undefined;
|
|
2711
2711
|
onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
|
|
@@ -2723,11 +2723,17 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
|
|
|
2723
2723
|
base?: string | undefined;
|
|
2724
2724
|
} | undefined;
|
|
2725
2725
|
server?: {
|
|
2726
|
-
entry?: string | undefined;
|
|
2727
2726
|
build?: {
|
|
2728
2727
|
staticNodeEnv?: boolean | undefined;
|
|
2729
2728
|
inlineCss?: boolean | undefined;
|
|
2730
2729
|
} | undefined;
|
|
2730
|
+
entry?: string | undefined;
|
|
2731
|
+
} | undefined;
|
|
2732
|
+
dev?: {
|
|
2733
|
+
ssrStyles?: {
|
|
2734
|
+
basepath?: string | undefined;
|
|
2735
|
+
enabled?: boolean | undefined;
|
|
2736
|
+
} | undefined;
|
|
2731
2737
|
} | undefined;
|
|
2732
2738
|
srcDirectory?: string | undefined;
|
|
2733
2739
|
start?: {
|
|
@@ -2970,12 +2976,6 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
|
|
|
2970
2976
|
headers?: Record<string, string> | undefined;
|
|
2971
2977
|
} | undefined;
|
|
2972
2978
|
}[] | undefined;
|
|
2973
|
-
dev?: {
|
|
2974
|
-
ssrStyles?: {
|
|
2975
|
-
basepath?: string | undefined;
|
|
2976
|
-
enabled?: boolean | undefined;
|
|
2977
|
-
} | undefined;
|
|
2978
|
-
} | undefined;
|
|
2979
2979
|
spa?: {
|
|
2980
2980
|
enabled?: boolean | undefined;
|
|
2981
2981
|
prerender?: {
|
|
@@ -3033,8 +3033,8 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
|
|
|
3033
3033
|
exclude?: (string | RegExp)[] | undefined;
|
|
3034
3034
|
enabled?: boolean | undefined;
|
|
3035
3035
|
behavior?: "error" | "mock" | {
|
|
3036
|
-
build?: "error" | "mock" | undefined;
|
|
3037
3036
|
dev?: "error" | "mock" | undefined;
|
|
3037
|
+
build?: "error" | "mock" | undefined;
|
|
3038
3038
|
} | undefined;
|
|
3039
3039
|
mockAccess?: "error" | "warn" | "off" | undefined;
|
|
3040
3040
|
onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
|
|
@@ -3110,6 +3110,12 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartViteO
|
|
|
3110
3110
|
};
|
|
3111
3111
|
entry?: string | undefined;
|
|
3112
3112
|
};
|
|
3113
|
+
dev: {
|
|
3114
|
+
ssrStyles: {
|
|
3115
|
+
enabled: boolean;
|
|
3116
|
+
basepath?: string | undefined;
|
|
3117
|
+
};
|
|
3118
|
+
};
|
|
3113
3119
|
srcDirectory: string;
|
|
3114
3120
|
start: {
|
|
3115
3121
|
entry?: string | undefined;
|
|
@@ -3187,12 +3193,6 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartViteO
|
|
|
3187
3193
|
headers?: Record<string, string> | undefined;
|
|
3188
3194
|
} | undefined;
|
|
3189
3195
|
}[];
|
|
3190
|
-
dev: {
|
|
3191
|
-
ssrStyles: {
|
|
3192
|
-
enabled: boolean;
|
|
3193
|
-
basepath?: string | undefined;
|
|
3194
|
-
};
|
|
3195
|
-
};
|
|
3196
3196
|
sitemap?: {
|
|
3197
3197
|
enabled: boolean;
|
|
3198
3198
|
outputPath: string;
|
|
@@ -3366,8 +3366,8 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartViteO
|
|
|
3366
3366
|
exclude?: (string | RegExp)[] | undefined;
|
|
3367
3367
|
enabled?: boolean | undefined;
|
|
3368
3368
|
behavior?: "error" | "mock" | {
|
|
3369
|
-
build?: "error" | "mock" | undefined;
|
|
3370
3369
|
dev?: "error" | "mock" | undefined;
|
|
3370
|
+
build?: "error" | "mock" | undefined;
|
|
3371
3371
|
} | undefined;
|
|
3372
3372
|
mockAccess?: "error" | "warn" | "off" | undefined;
|
|
3373
3373
|
onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SERVER_FN_LOOKUP } from '../../constants.js';
|
|
2
|
-
import { CompileStartFrameworkOptions } from '../../types.js';
|
|
2
|
+
import { CompileStartFrameworkOptions, StartCompilerImportTransform } from '../../types.js';
|
|
3
3
|
import { GenerateFunctionIdFnOptional } from '../../start-compiler/types.js';
|
|
4
4
|
import { PluginOption } from 'vite';
|
|
5
5
|
export { SERVER_FN_LOOKUP };
|
|
@@ -14,6 +14,8 @@ export interface StartCompilerPluginOptions {
|
|
|
14
14
|
* Custom function ID generator (optional).
|
|
15
15
|
*/
|
|
16
16
|
generateFunctionId?: GenerateFunctionIdFnOptional;
|
|
17
|
+
compilerTransforms?: Array<StartCompilerImportTransform> | undefined;
|
|
18
|
+
serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined;
|
|
17
19
|
/**
|
|
18
20
|
* The Vite environment name for the server function provider.
|
|
19
21
|
*/
|
|
@@ -79,7 +79,9 @@ function startCompilerPlugin(opts) {
|
|
|
79
79
|
const ssrIsProvider = opts.providerEnvName === ssrEnvName;
|
|
80
80
|
const appliedResolverEnvironments = new Set(ssrIsProvider ? [opts.providerEnvName] : [ssrEnvName, opts.providerEnvName]);
|
|
81
81
|
function perEnvServerFnPlugin(environment) {
|
|
82
|
-
const
|
|
82
|
+
const compilerTransforms = environment.name === opts.providerEnvName ? opts.compilerTransforms : void 0;
|
|
83
|
+
const serverFnProviderModuleDirectives = environment.name === opts.providerEnvName ? opts.serverFnProviderModuleDirectives : void 0;
|
|
84
|
+
const transformCodeFilter = getTransformCodeFilterForEnv(environment.type, { compilerTransforms });
|
|
83
85
|
return {
|
|
84
86
|
name: `tanstack-start-core::server-fn:${environment.name}`,
|
|
85
87
|
enforce: "pre",
|
|
@@ -109,6 +111,8 @@ function startCompilerPlugin(opts) {
|
|
|
109
111
|
framework: opts.framework,
|
|
110
112
|
providerEnvName: opts.providerEnvName,
|
|
111
113
|
generateFunctionId: opts.generateFunctionId,
|
|
114
|
+
compilerTransforms,
|
|
115
|
+
serverFnProviderModuleDirectives,
|
|
112
116
|
onServerFnsById,
|
|
113
117
|
getKnownServerFns: () => serverFnsById,
|
|
114
118
|
encodeModuleSpecifierInDev: mode === "dev" ? createViteDevServerFnModuleSpecifierEncoder(root) : void 0,
|
|
@@ -134,7 +138,7 @@ function startCompilerPlugin(opts) {
|
|
|
134
138
|
});
|
|
135
139
|
compilers.set(this.environment.name, compiler);
|
|
136
140
|
}
|
|
137
|
-
const detectedKinds = detectKindsInCode(code, environment.type);
|
|
141
|
+
const detectedKinds = detectKindsInCode(code, environment.type, { compilerTransforms });
|
|
138
142
|
return await compiler.compile({
|
|
139
143
|
id,
|
|
140
144
|
code,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[],"sources":["../../../../src/vite/start-compiler-plugin/plugin.ts"],"sourcesContent":["import { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { resolve as resolvePath } from 'pathe'\nimport {\n SERVER_FN_LOOKUP,\n TRANSFORM_ID_REGEX,\n VITE_ENVIRONMENT_NAMES,\n} from '../../constants'\nimport { detectKindsInCode } from '../../start-compiler/compiler'\nimport { getTransformCodeFilterForEnv } from '../../start-compiler/config'\nimport {\n createStartCompiler,\n mergeServerFnsById,\n} from '../../start-compiler/host'\nimport { generateServerFnResolverModule } from '../../start-compiler/server-fn-resolver-module'\nimport { cleanId } from '../../start-compiler/utils'\nimport { createVirtualModule } from '../createVirtualModule'\nimport { resolveViteId } from '../../utils'\nimport {\n createViteDevServerFnModuleSpecifierEncoder,\n decodeViteDevServerModuleSpecifier,\n} from './module-specifier'\nimport { mergeHotUpdateModules } from './hot-update'\nimport type { CompileStartFrameworkOptions } from '../../types'\nimport type {\n GenerateFunctionIdFnOptional,\n ServerFn,\n} from '../../start-compiler/types'\nimport type { EnvironmentModuleNode, PluginOption } from 'vite'\n\n// Re-export from shared constants for backwards compatibility\nexport { SERVER_FN_LOOKUP }\n\nconst validateServerFnIdVirtualModule = `virtual:tanstack-start-validate-server-fn-id`\nconst TSS_SERVERFN_SPLIT_PARAM = 'tss-serverfn-split'\n\ntype ModuleInvalidationEnvironment = {\n moduleGraph: {\n getModulesByFile: (file: string) => Set<EnvironmentModuleNode> | undefined\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n}\n\nfunction invalidateMatchingFileModules(\n environment: ModuleInvalidationEnvironment,\n ids: Iterable<string>,\n shouldInvalidate: (mod: EnvironmentModuleNode) => boolean,\n) {\n const seen = new Set<EnvironmentModuleNode>()\n const invalidatedModules: Array<EnvironmentModuleNode> = []\n\n for (const id of ids) {\n const fileModules = environment.moduleGraph.getModulesByFile(cleanId(id))\n\n if (!fileModules) {\n continue\n }\n\n for (const fileModule of fileModules) {\n if (!shouldInvalidate(fileModule)) {\n continue\n }\n\n environment.moduleGraph.invalidateModule(fileModule, seen)\n invalidatedModules.push(fileModule)\n }\n }\n\n return invalidatedModules\n}\n\nfunction invalidateServerFnProviderModules(\n environment: {\n moduleGraph: {\n getModulesByFile: (file: string) => Set<EnvironmentModuleNode> | undefined\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n },\n ids: Iterable<string>,\n) {\n return invalidateMatchingFileModules(\n environment,\n ids,\n (fileModule) => fileModule.id?.includes(TSS_SERVERFN_SPLIT_PARAM) ?? false,\n )\n}\n\nfunction invalidateServerFnLookupModules(\n environment: ModuleInvalidationEnvironment,\n ids: Iterable<string>,\n) {\n invalidateMatchingFileModules(\n environment,\n ids,\n (fileModule) => fileModule.id?.includes(SERVER_FN_LOOKUP) ?? false,\n )\n}\n\nfunction getServerFnProviderIds(ids: Iterable<string>) {\n const providerIds = new Set<string>()\n\n for (const id of ids) {\n const cleanedId = cleanId(id)\n providerIds.add(`${cleanedId}?${TSS_SERVERFN_SPLIT_PARAM}`)\n }\n\n return providerIds\n}\n\nfunction invalidateModuleNodes(\n environment: {\n moduleGraph: {\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n },\n modules: Iterable<EnvironmentModuleNode>,\n) {\n const seen = new Set<EnvironmentModuleNode>()\n\n for (const mod of modules) {\n environment.moduleGraph.invalidateModule(mod, seen)\n }\n}\n\nfunction getDevServerFnValidatorModule(): string {\n return `\nexport async function getServerFnById(id, _access) {\n const validateIdImport = ${JSON.stringify(validateServerFnIdVirtualModule)} + '?id=' + id\n await import(/* @vite-ignore */ '/@id/__x00__' + validateIdImport)\n const decoded = Buffer.from(id, 'base64url').toString('utf8')\n const devServerFn = JSON.parse(decoded)\n const mod = await import(/* @vite-ignore */ devServerFn.file)\n return mod[devServerFn.export]\n}\n`\n}\n\nfunction parseIdQuery(id: string): {\n filename: string\n query: {\n [k: string]: string\n }\n} {\n if (!id.includes('?')) return { filename: id, query: {} }\n const [filename, rawQuery] = id.split(`?`, 2) as [string, string]\n const query = Object.fromEntries(new URLSearchParams(rawQuery))\n return { filename, query }\n}\n\nexport interface StartCompilerPluginOptions {\n framework: CompileStartFrameworkOptions\n environments: Array<{\n name: string\n type: 'client' | 'server'\n getServerFnById?: string\n }>\n /**\n * Custom function ID generator (optional).\n */\n generateFunctionId?: GenerateFunctionIdFnOptional\n /**\n * The Vite environment name for the server function provider.\n */\n providerEnvName: string\n}\n\nexport function startCompilerPlugin(\n opts: StartCompilerPluginOptions,\n): PluginOption {\n const compilers = new Map<string, ReturnType<typeof createStartCompiler>>()\n\n // Shared registry of server functions across all environments\n const serverFnsById: Record<string, ServerFn> = {}\n\n const onServerFnsById = (d: Record<string, ServerFn>) => {\n mergeServerFnsById(serverFnsById, d)\n }\n\n let root = process.cwd()\n // Determine which environments need the resolver (getServerFnById)\n // SSR environment always needs the resolver for server-side calls\n // Provider environment needs it for the actual implementation\n const ssrEnvName = VITE_ENVIRONMENT_NAMES.server\n\n // SSR is the provider when the provider environment is the default server environment\n const ssrIsProvider = opts.providerEnvName === ssrEnvName\n\n // Environments that need the resolver: SSR (for server calls) and provider (for implementation)\n const appliedResolverEnvironments = new Set(\n ssrIsProvider ? [opts.providerEnvName] : [ssrEnvName, opts.providerEnvName],\n )\n\n function perEnvServerFnPlugin(environment: {\n name: string\n type: 'client' | 'server'\n }): PluginOption {\n // Derive transform code filter from KindDetectionPatterns (single source of truth)\n const transformCodeFilter = getTransformCodeFilterForEnv(environment.type)\n return {\n name: `tanstack-start-core::server-fn:${environment.name}`,\n enforce: 'pre',\n applyToEnvironment(env) {\n return env.name === environment.name\n },\n configResolved(config) {\n root = config.root\n },\n transform: {\n filter: {\n id: {\n exclude: new RegExp(`${SERVER_FN_LOOKUP}$`),\n include: TRANSFORM_ID_REGEX,\n },\n code: {\n include: transformCodeFilter,\n },\n },\n async handler(code, id) {\n let compiler = compilers.get(this.environment.name)\n\n if (!compiler) {\n // Default to 'dev' mode for unknown environments (conservative: no caching)\n const mode = this.environment.mode === 'build' ? 'build' : 'dev'\n\n compiler = createStartCompiler({\n env: environment.type,\n envName: environment.name,\n root,\n mode,\n framework: opts.framework,\n providerEnvName: opts.providerEnvName,\n generateFunctionId: opts.generateFunctionId,\n onServerFnsById,\n getKnownServerFns: () => serverFnsById,\n encodeModuleSpecifierInDev:\n mode === 'dev'\n ? createViteDevServerFnModuleSpecifierEncoder(root)\n : undefined,\n loadModule: async (id: string) => {\n if (mode === 'build') {\n const loaded = await this.load({ id })\n const code = loaded.code ?? ''\n\n compiler!.ingestModule({ code, id })\n return\n }\n\n if (this.environment.mode !== 'dev') {\n this.error(\n `could not load module ${id}: unknown environment mode ${this.environment.mode}`,\n )\n }\n\n await this.environment.transformRequest(\n `${id}?${SERVER_FN_LOOKUP}`,\n )\n },\n\n resolveId: async (source: string, importer?: string) => {\n const r = await this.resolve(source, importer)\n\n if (r) {\n if (!r.external) {\n return cleanId(r.id)\n }\n }\n\n return null\n },\n })\n\n compilers.set(this.environment.name, compiler)\n }\n\n // Detect which kinds are present in this file before parsing\n const detectedKinds = detectKindsInCode(code, environment.type)\n\n const result = await compiler.compile({\n id,\n code,\n detectedKinds,\n })\n return result\n },\n },\n\n hotUpdate(ctx) {\n const compiler = compilers.get(this.environment.name)\n const idsToInvalidate = new Set<string>()\n const transitiveCompilerImportersToInvalidate = new Set<string>()\n const importerModulesToInvalidate = new Set<EnvironmentModuleNode>()\n\n ctx.modules.forEach((m) => {\n if (m.id) {\n idsToInvalidate.add(m.id)\n const deleted = compiler?.invalidateModule(m.id)\n\n if (deleted) {\n transitiveCompilerImportersToInvalidate.add(cleanId(m.id))\n }\n\n if (deleted) {\n m.importers.forEach((importer) => {\n if (importer.id) {\n idsToInvalidate.add(importer.id)\n importerModulesToInvalidate.add(importer)\n transitiveCompilerImportersToInvalidate.add(\n cleanId(importer.id),\n )\n }\n })\n }\n }\n })\n\n const finishHotUpdate = async () => {\n if (environment.type === 'server' && compiler) {\n const pendingImporters = [\n ...transitiveCompilerImportersToInvalidate,\n ]\n const seenImporters = new Set(pendingImporters)\n\n while (pendingImporters.length > 0) {\n const importerId = pendingImporters.pop()!\n const nestedImporters =\n await compiler.getTransitiveImporters(importerId)\n\n for (const nestedImporterId of nestedImporters) {\n if (seenImporters.has(nestedImporterId)) {\n continue\n }\n\n seenImporters.add(nestedImporterId)\n pendingImporters.push(nestedImporterId)\n }\n }\n\n for (const importerId of seenImporters) {\n idsToInvalidate.add(importerId)\n compiler.invalidateModule(importerId)\n }\n }\n\n invalidateModuleNodes(this.environment, importerModulesToInvalidate)\n invalidateServerFnLookupModules(this.environment, idsToInvalidate)\n\n if (environment.type !== 'server') {\n return\n }\n\n invalidateModuleNodes(this.environment, ctx.modules)\n\n const providerIdsToInvalidate =\n getServerFnProviderIds(idsToInvalidate)\n for (const providerId of providerIdsToInvalidate) {\n compiler?.invalidateModule(providerId)\n }\n\n const providerModules = invalidateServerFnProviderModules(\n this.environment,\n [...idsToInvalidate, ...providerIdsToInvalidate],\n )\n\n return mergeHotUpdateModules(ctx.modules, providerModules)\n }\n\n return finishHotUpdate()\n },\n }\n }\n\n return [\n ...opts.environments.map(perEnvServerFnPlugin),\n {\n name: 'tanstack-start-core:capture-server-fn-module-lookup',\n // we only need this plugin in dev mode\n apply: 'serve',\n applyToEnvironment(env) {\n return !!opts.environments.find((e) => e.name === env.name)\n },\n transform: {\n filter: {\n id: new RegExp(`${SERVER_FN_LOOKUP}$`),\n },\n handler(code, id) {\n const compiler = compilers.get(this.environment.name)\n compiler?.ingestModule({ code, id: cleanId(id) })\n },\n },\n },\n // Validate server function ID in dev mode\n {\n name: 'tanstack-start-core:validate-server-fn-id',\n apply: 'serve',\n load: {\n filter: {\n id: new RegExp(resolveViteId(validateServerFnIdVirtualModule)),\n },\n async handler(id) {\n const parsed = parseIdQuery(id)\n const fnId = parsed.query.id\n if (fnId && serverFnsById[fnId]) {\n return `export {}`\n }\n\n // ID not yet registered — the source file may not have been\n // transformed in this dev session yet (e.g. cold restart with\n // cached client). Try to decode the ID, discover the source\n // file, trigger its compilation, and re-check.\n if (fnId) {\n try {\n const decoded = JSON.parse(\n Buffer.from(fnId, 'base64url').toString('utf8'),\n )\n if (\n typeof decoded.file === 'string' &&\n typeof decoded.export === 'string'\n ) {\n // Use the Vite strategy to decode the module specifier\n // back to the original source file path.\n const sourceFile = decodeViteDevServerModuleSpecifier(\n decoded.file,\n )\n\n if (sourceFile) {\n // Resolve to absolute path\n const absPath = resolvePath(root, sourceFile)\n\n // Trigger transform of the source file in this environment,\n // which will compile createServerFn calls and populate\n // serverFnsById as a side effect.\n if (this.environment.mode !== 'dev') {\n this.error(\n `could not validate server function ID ${fnId}: unknown environment mode ${this.environment.mode}`,\n )\n }\n\n await this.environment.transformRequest(\n `${absPath}?${SERVER_FN_LOOKUP}`,\n )\n\n // Re-check after lazy compilation\n if (serverFnsById[fnId]) {\n return `export {}`\n }\n }\n }\n } catch {\n // Decoding or fetching failed — fall through to error\n }\n }\n\n this.error(`Invalid server function ID: ${fnId}`)\n },\n },\n },\n // Manifest plugin for server environments\n createVirtualModule({\n name: 'tanstack-start-core:server-fn-resolver',\n moduleId: VIRTUAL_MODULES.serverFnResolver,\n enforce: 'pre',\n applyToEnvironment: (env) => {\n return appliedResolverEnvironments.has(env.name)\n },\n load() {\n if (this.environment.name !== opts.providerEnvName) {\n const mod = opts.environments.find(\n (e) => e.name === this.environment.name,\n )?.getServerFnById\n if (mod) {\n return mod\n }\n\n this.error(\n `No getServerFnById implementation found for caller environment: ${this.environment.name}`,\n )\n }\n\n if (this.environment.mode !== 'build') {\n return getDevServerFnValidatorModule()\n }\n\n // When SSR is the provider, server-only-referenced functions aren't in the manifest,\n // so no isClientReferenced check is needed.\n // When SSR is NOT the provider (custom provider env), server-only-referenced\n // functions ARE in the manifest and need the isClientReferenced check to\n // block direct client HTTP requests to server-only-referenced functions.\n return generateServerFnResolverModule({\n serverFnsById,\n includeClientReferencedCheck: !ssrIsProvider,\n })\n },\n }),\n ]\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","names":[],"sources":["../../../../src/vite/start-compiler-plugin/plugin.ts"],"sourcesContent":["import { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { resolve as resolvePath } from 'pathe'\nimport {\n SERVER_FN_LOOKUP,\n TRANSFORM_ID_REGEX,\n VITE_ENVIRONMENT_NAMES,\n} from '../../constants'\nimport { detectKindsInCode } from '../../start-compiler/compiler'\nimport { getTransformCodeFilterForEnv } from '../../start-compiler/config'\nimport {\n createStartCompiler,\n mergeServerFnsById,\n} from '../../start-compiler/host'\nimport { generateServerFnResolverModule } from '../../start-compiler/server-fn-resolver-module'\nimport { cleanId } from '../../start-compiler/utils'\nimport { createVirtualModule } from '../createVirtualModule'\nimport { resolveViteId } from '../../utils'\nimport {\n createViteDevServerFnModuleSpecifierEncoder,\n decodeViteDevServerModuleSpecifier,\n} from './module-specifier'\nimport { mergeHotUpdateModules } from './hot-update'\nimport type {\n CompileStartFrameworkOptions,\n StartCompilerImportTransform,\n} from '../../types'\nimport type {\n GenerateFunctionIdFnOptional,\n ServerFn,\n} from '../../start-compiler/types'\nimport type { EnvironmentModuleNode, PluginOption } from 'vite'\n\n// Re-export from shared constants for backwards compatibility\nexport { SERVER_FN_LOOKUP }\n\nconst validateServerFnIdVirtualModule = `virtual:tanstack-start-validate-server-fn-id`\nconst TSS_SERVERFN_SPLIT_PARAM = 'tss-serverfn-split'\n\ntype ModuleInvalidationEnvironment = {\n moduleGraph: {\n getModulesByFile: (file: string) => Set<EnvironmentModuleNode> | undefined\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n}\n\nfunction invalidateMatchingFileModules(\n environment: ModuleInvalidationEnvironment,\n ids: Iterable<string>,\n shouldInvalidate: (mod: EnvironmentModuleNode) => boolean,\n) {\n const seen = new Set<EnvironmentModuleNode>()\n const invalidatedModules: Array<EnvironmentModuleNode> = []\n\n for (const id of ids) {\n const fileModules = environment.moduleGraph.getModulesByFile(cleanId(id))\n\n if (!fileModules) {\n continue\n }\n\n for (const fileModule of fileModules) {\n if (!shouldInvalidate(fileModule)) {\n continue\n }\n\n environment.moduleGraph.invalidateModule(fileModule, seen)\n invalidatedModules.push(fileModule)\n }\n }\n\n return invalidatedModules\n}\n\nfunction invalidateServerFnProviderModules(\n environment: {\n moduleGraph: {\n getModulesByFile: (file: string) => Set<EnvironmentModuleNode> | undefined\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n },\n ids: Iterable<string>,\n) {\n return invalidateMatchingFileModules(\n environment,\n ids,\n (fileModule) => fileModule.id?.includes(TSS_SERVERFN_SPLIT_PARAM) ?? false,\n )\n}\n\nfunction invalidateServerFnLookupModules(\n environment: ModuleInvalidationEnvironment,\n ids: Iterable<string>,\n) {\n invalidateMatchingFileModules(\n environment,\n ids,\n (fileModule) => fileModule.id?.includes(SERVER_FN_LOOKUP) ?? false,\n )\n}\n\nfunction getServerFnProviderIds(ids: Iterable<string>) {\n const providerIds = new Set<string>()\n\n for (const id of ids) {\n const cleanedId = cleanId(id)\n providerIds.add(`${cleanedId}?${TSS_SERVERFN_SPLIT_PARAM}`)\n }\n\n return providerIds\n}\n\nfunction invalidateModuleNodes(\n environment: {\n moduleGraph: {\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n },\n modules: Iterable<EnvironmentModuleNode>,\n) {\n const seen = new Set<EnvironmentModuleNode>()\n\n for (const mod of modules) {\n environment.moduleGraph.invalidateModule(mod, seen)\n }\n}\n\nfunction getDevServerFnValidatorModule(): string {\n return `\nexport async function getServerFnById(id, _access) {\n const validateIdImport = ${JSON.stringify(validateServerFnIdVirtualModule)} + '?id=' + id\n await import(/* @vite-ignore */ '/@id/__x00__' + validateIdImport)\n const decoded = Buffer.from(id, 'base64url').toString('utf8')\n const devServerFn = JSON.parse(decoded)\n const mod = await import(/* @vite-ignore */ devServerFn.file)\n return mod[devServerFn.export]\n}\n`\n}\n\nfunction parseIdQuery(id: string): {\n filename: string\n query: {\n [k: string]: string\n }\n} {\n if (!id.includes('?')) return { filename: id, query: {} }\n const [filename, rawQuery] = id.split(`?`, 2) as [string, string]\n const query = Object.fromEntries(new URLSearchParams(rawQuery))\n return { filename, query }\n}\n\nexport interface StartCompilerPluginOptions {\n framework: CompileStartFrameworkOptions\n environments: Array<{\n name: string\n type: 'client' | 'server'\n getServerFnById?: string\n }>\n /**\n * Custom function ID generator (optional).\n */\n generateFunctionId?: GenerateFunctionIdFnOptional\n compilerTransforms?: Array<StartCompilerImportTransform> | undefined\n serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined\n /**\n * The Vite environment name for the server function provider.\n */\n providerEnvName: string\n}\n\nexport function startCompilerPlugin(\n opts: StartCompilerPluginOptions,\n): PluginOption {\n const compilers = new Map<string, ReturnType<typeof createStartCompiler>>()\n\n // Shared registry of server functions across all environments\n const serverFnsById: Record<string, ServerFn> = {}\n\n const onServerFnsById = (d: Record<string, ServerFn>) => {\n mergeServerFnsById(serverFnsById, d)\n }\n\n let root = process.cwd()\n // Determine which environments need the resolver (getServerFnById)\n // SSR environment always needs the resolver for server-side calls\n // Provider environment needs it for the actual implementation\n const ssrEnvName = VITE_ENVIRONMENT_NAMES.server\n\n // SSR is the provider when the provider environment is the default server environment\n const ssrIsProvider = opts.providerEnvName === ssrEnvName\n\n // Environments that need the resolver: SSR (for server calls) and provider (for implementation)\n const appliedResolverEnvironments = new Set(\n ssrIsProvider ? [opts.providerEnvName] : [ssrEnvName, opts.providerEnvName],\n )\n\n function perEnvServerFnPlugin(environment: {\n name: string\n type: 'client' | 'server'\n }): PluginOption {\n const compilerTransforms =\n environment.name === opts.providerEnvName\n ? opts.compilerTransforms\n : undefined\n const serverFnProviderModuleDirectives =\n environment.name === opts.providerEnvName\n ? opts.serverFnProviderModuleDirectives\n : undefined\n // Derive transform code filter from KindDetectionPatterns (single source of truth)\n const transformCodeFilter = getTransformCodeFilterForEnv(environment.type, {\n compilerTransforms,\n })\n return {\n name: `tanstack-start-core::server-fn:${environment.name}`,\n enforce: 'pre',\n applyToEnvironment(env) {\n return env.name === environment.name\n },\n configResolved(config) {\n root = config.root\n },\n transform: {\n filter: {\n id: {\n exclude: new RegExp(`${SERVER_FN_LOOKUP}$`),\n include: TRANSFORM_ID_REGEX,\n },\n code: {\n include: transformCodeFilter,\n },\n },\n async handler(code, id) {\n let compiler = compilers.get(this.environment.name)\n\n if (!compiler) {\n // Default to 'dev' mode for unknown environments (conservative: no caching)\n const mode = this.environment.mode === 'build' ? 'build' : 'dev'\n\n compiler = createStartCompiler({\n env: environment.type,\n envName: environment.name,\n root,\n mode,\n framework: opts.framework,\n providerEnvName: opts.providerEnvName,\n generateFunctionId: opts.generateFunctionId,\n compilerTransforms,\n serverFnProviderModuleDirectives,\n onServerFnsById,\n getKnownServerFns: () => serverFnsById,\n encodeModuleSpecifierInDev:\n mode === 'dev'\n ? createViteDevServerFnModuleSpecifierEncoder(root)\n : undefined,\n loadModule: async (id: string) => {\n if (mode === 'build') {\n const loaded = await this.load({ id })\n const code = loaded.code ?? ''\n\n compiler!.ingestModule({ code, id })\n return\n }\n\n if (this.environment.mode !== 'dev') {\n this.error(\n `could not load module ${id}: unknown environment mode ${this.environment.mode}`,\n )\n }\n\n await this.environment.transformRequest(\n `${id}?${SERVER_FN_LOOKUP}`,\n )\n },\n\n resolveId: async (source: string, importer?: string) => {\n const r = await this.resolve(source, importer)\n\n if (r) {\n if (!r.external) {\n return cleanId(r.id)\n }\n }\n\n return null\n },\n })\n\n compilers.set(this.environment.name, compiler)\n }\n\n // Detect which kinds are present in this file before parsing\n const detectedKinds = detectKindsInCode(code, environment.type, {\n compilerTransforms,\n })\n\n const result = await compiler.compile({\n id,\n code,\n detectedKinds,\n })\n return result\n },\n },\n\n hotUpdate(ctx) {\n const compiler = compilers.get(this.environment.name)\n const idsToInvalidate = new Set<string>()\n const transitiveCompilerImportersToInvalidate = new Set<string>()\n const importerModulesToInvalidate = new Set<EnvironmentModuleNode>()\n\n ctx.modules.forEach((m) => {\n if (m.id) {\n idsToInvalidate.add(m.id)\n const deleted = compiler?.invalidateModule(m.id)\n\n if (deleted) {\n transitiveCompilerImportersToInvalidate.add(cleanId(m.id))\n }\n\n if (deleted) {\n m.importers.forEach((importer) => {\n if (importer.id) {\n idsToInvalidate.add(importer.id)\n importerModulesToInvalidate.add(importer)\n transitiveCompilerImportersToInvalidate.add(\n cleanId(importer.id),\n )\n }\n })\n }\n }\n })\n\n const finishHotUpdate = async () => {\n if (environment.type === 'server' && compiler) {\n const pendingImporters = [\n ...transitiveCompilerImportersToInvalidate,\n ]\n const seenImporters = new Set(pendingImporters)\n\n while (pendingImporters.length > 0) {\n const importerId = pendingImporters.pop()!\n const nestedImporters =\n await compiler.getTransitiveImporters(importerId)\n\n for (const nestedImporterId of nestedImporters) {\n if (seenImporters.has(nestedImporterId)) {\n continue\n }\n\n seenImporters.add(nestedImporterId)\n pendingImporters.push(nestedImporterId)\n }\n }\n\n for (const importerId of seenImporters) {\n idsToInvalidate.add(importerId)\n compiler.invalidateModule(importerId)\n }\n }\n\n invalidateModuleNodes(this.environment, importerModulesToInvalidate)\n invalidateServerFnLookupModules(this.environment, idsToInvalidate)\n\n if (environment.type !== 'server') {\n return\n }\n\n invalidateModuleNodes(this.environment, ctx.modules)\n\n const providerIdsToInvalidate =\n getServerFnProviderIds(idsToInvalidate)\n for (const providerId of providerIdsToInvalidate) {\n compiler?.invalidateModule(providerId)\n }\n\n const providerModules = invalidateServerFnProviderModules(\n this.environment,\n [...idsToInvalidate, ...providerIdsToInvalidate],\n )\n\n return mergeHotUpdateModules(ctx.modules, providerModules)\n }\n\n return finishHotUpdate()\n },\n }\n }\n\n return [\n ...opts.environments.map(perEnvServerFnPlugin),\n {\n name: 'tanstack-start-core:capture-server-fn-module-lookup',\n // we only need this plugin in dev mode\n apply: 'serve',\n applyToEnvironment(env) {\n return !!opts.environments.find((e) => e.name === env.name)\n },\n transform: {\n filter: {\n id: new RegExp(`${SERVER_FN_LOOKUP}$`),\n },\n handler(code, id) {\n const compiler = compilers.get(this.environment.name)\n compiler?.ingestModule({ code, id: cleanId(id) })\n },\n },\n },\n // Validate server function ID in dev mode\n {\n name: 'tanstack-start-core:validate-server-fn-id',\n apply: 'serve',\n load: {\n filter: {\n id: new RegExp(resolveViteId(validateServerFnIdVirtualModule)),\n },\n async handler(id) {\n const parsed = parseIdQuery(id)\n const fnId = parsed.query.id\n if (fnId && serverFnsById[fnId]) {\n return `export {}`\n }\n\n // ID not yet registered — the source file may not have been\n // transformed in this dev session yet (e.g. cold restart with\n // cached client). Try to decode the ID, discover the source\n // file, trigger its compilation, and re-check.\n if (fnId) {\n try {\n const decoded = JSON.parse(\n Buffer.from(fnId, 'base64url').toString('utf8'),\n )\n if (\n typeof decoded.file === 'string' &&\n typeof decoded.export === 'string'\n ) {\n // Use the Vite strategy to decode the module specifier\n // back to the original source file path.\n const sourceFile = decodeViteDevServerModuleSpecifier(\n decoded.file,\n )\n\n if (sourceFile) {\n // Resolve to absolute path\n const absPath = resolvePath(root, sourceFile)\n\n // Trigger transform of the source file in this environment,\n // which will compile createServerFn calls and populate\n // serverFnsById as a side effect.\n if (this.environment.mode !== 'dev') {\n this.error(\n `could not validate server function ID ${fnId}: unknown environment mode ${this.environment.mode}`,\n )\n }\n\n await this.environment.transformRequest(\n `${absPath}?${SERVER_FN_LOOKUP}`,\n )\n\n // Re-check after lazy compilation\n if (serverFnsById[fnId]) {\n return `export {}`\n }\n }\n }\n } catch {\n // Decoding or fetching failed — fall through to error\n }\n }\n\n this.error(`Invalid server function ID: ${fnId}`)\n },\n },\n },\n // Manifest plugin for server environments\n createVirtualModule({\n name: 'tanstack-start-core:server-fn-resolver',\n moduleId: VIRTUAL_MODULES.serverFnResolver,\n enforce: 'pre',\n applyToEnvironment: (env) => {\n return appliedResolverEnvironments.has(env.name)\n },\n load() {\n if (this.environment.name !== opts.providerEnvName) {\n const mod = opts.environments.find(\n (e) => e.name === this.environment.name,\n )?.getServerFnById\n if (mod) {\n return mod\n }\n\n this.error(\n `No getServerFnById implementation found for caller environment: ${this.environment.name}`,\n )\n }\n\n if (this.environment.mode !== 'build') {\n return getDevServerFnValidatorModule()\n }\n\n // When SSR is the provider, server-only-referenced functions aren't in the manifest,\n // so no isClientReferenced check is needed.\n // When SSR is NOT the provider (custom provider env), server-only-referenced\n // functions ARE in the manifest and need the isClientReferenced check to\n // block direct client HTTP requests to server-only-referenced functions.\n return generateServerFnResolverModule({\n serverFnsById,\n includeClientReferencedCheck: !ssrIsProvider,\n })\n },\n }),\n ]\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/start-plugin-core",
|
|
3
|
-
"version": "1.169.
|
|
3
|
+
"version": "1.169.13",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -86,12 +86,12 @@
|
|
|
86
86
|
"vitefu": "^1.1.1",
|
|
87
87
|
"xmlbuilder2": "^4.0.3",
|
|
88
88
|
"zod": "^3.24.2",
|
|
89
|
-
"@tanstack/router-core": "1.169.
|
|
90
|
-
"@tanstack/router-generator": "1.166.
|
|
91
|
-
"@tanstack/router-plugin": "1.167.
|
|
89
|
+
"@tanstack/router-core": "1.169.1",
|
|
90
|
+
"@tanstack/router-generator": "1.166.39",
|
|
91
|
+
"@tanstack/router-plugin": "1.167.31",
|
|
92
92
|
"@tanstack/router-utils": "1.161.7",
|
|
93
|
-
"@tanstack/start-client-core": "1.168.
|
|
94
|
-
"@tanstack/start-server-core": "1.167.
|
|
93
|
+
"@tanstack/start-client-core": "1.168.1",
|
|
94
|
+
"@tanstack/start-server-core": "1.167.26"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"@rsbuild/core": "^2.0.1",
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
export type { TanStackStartInputConfig } from './schema'
|
|
2
|
-
export type {
|
|
2
|
+
export type {
|
|
3
|
+
StartCompilerImportTransform,
|
|
4
|
+
StartCompilerTransformCandidate,
|
|
5
|
+
StartCompilerTransformContext,
|
|
6
|
+
TanStackStartCoreOptions,
|
|
7
|
+
} from './types'
|
|
3
8
|
export { START_ENVIRONMENT_NAMES } from './constants'
|
package/src/rsbuild/index.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export { RSBUILD_ENVIRONMENT_NAMES } from './planning'
|
|
2
2
|
export type { TanStackStartRsbuildPluginCoreOptions } from './types'
|
|
3
3
|
export type { TanStackStartRsbuildInputConfig } from './schema'
|
|
4
|
+
export type {
|
|
5
|
+
StartCompilerImportTransform,
|
|
6
|
+
StartCompilerTransformCandidate,
|
|
7
|
+
StartCompilerTransformContext,
|
|
8
|
+
} from '../types'
|
|
4
9
|
export { tanStackStartRsbuild } from './plugin'
|
package/src/rsbuild/plugin.ts
CHANGED
|
@@ -239,6 +239,9 @@ export function tanStackStartRsbuild(
|
|
|
239
239
|
root: () => resolvedStartConfig.root || process.cwd(),
|
|
240
240
|
providerEnvName: serverFnProviderEnv,
|
|
241
241
|
generateFunctionId: startPluginOpts.serverFns?.generateFunctionId,
|
|
242
|
+
compilerTransforms: corePluginOpts.compilerTransforms,
|
|
243
|
+
serverFnProviderModuleDirectives:
|
|
244
|
+
corePluginOpts.serverFnProviderModuleDirectives,
|
|
242
245
|
serverFnsById,
|
|
243
246
|
onServerFnsByIdChange: () => {
|
|
244
247
|
updateServerFnResolver?.()
|