@tanstack/start-plugin-core 1.132.0-alpha.8 → 1.132.0

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.
Files changed (85) hide show
  1. package/dist/esm/constants.d.ts +2 -1
  2. package/dist/esm/constants.js +3 -2
  3. package/dist/esm/constants.js.map +1 -1
  4. package/dist/esm/create-server-fn-plugin/compiler.d.ts +64 -0
  5. package/dist/esm/create-server-fn-plugin/compiler.js +364 -0
  6. package/dist/esm/create-server-fn-plugin/compiler.js.map +1 -0
  7. package/dist/esm/create-server-fn-plugin/handleCreateMiddleware.d.ts +5 -0
  8. package/dist/esm/{start-compiler-plugin/middleware.js → create-server-fn-plugin/handleCreateMiddleware.js} +11 -11
  9. package/dist/esm/create-server-fn-plugin/handleCreateMiddleware.js.map +1 -0
  10. package/dist/esm/create-server-fn-plugin/handleCreateServerFn.d.ts +6 -0
  11. package/dist/esm/{start-compiler-plugin/serverFn.js → create-server-fn-plugin/handleCreateServerFn.js} +15 -17
  12. package/dist/esm/create-server-fn-plugin/handleCreateServerFn.js.map +1 -0
  13. package/dist/esm/create-server-fn-plugin/plugin.d.ts +3 -0
  14. package/dist/esm/create-server-fn-plugin/plugin.js +128 -0
  15. package/dist/esm/create-server-fn-plugin/plugin.js.map +1 -0
  16. package/dist/esm/dev-server-plugin/plugin.d.ts +4 -2
  17. package/dist/esm/dev-server-plugin/plugin.js +6 -2
  18. package/dist/esm/dev-server-plugin/plugin.js.map +1 -1
  19. package/dist/esm/plugin.d.ts +12 -6
  20. package/dist/esm/plugin.js +56 -68
  21. package/dist/esm/plugin.js.map +1 -1
  22. package/dist/esm/resolve-entries.d.ts +0 -1
  23. package/dist/esm/resolve-entries.js +1 -1
  24. package/dist/esm/resolve-entries.js.map +1 -1
  25. package/dist/esm/schema.d.ts +375 -308
  26. package/dist/esm/schema.js +23 -11
  27. package/dist/esm/schema.js.map +1 -1
  28. package/dist/esm/start-compiler-plugin/compilers.js +17 -55
  29. package/dist/esm/start-compiler-plugin/compilers.js.map +1 -1
  30. package/dist/esm/start-compiler-plugin/constants.d.ts +1 -1
  31. package/dist/esm/start-compiler-plugin/constants.js +1 -6
  32. package/dist/esm/start-compiler-plugin/constants.js.map +1 -1
  33. package/dist/esm/start-compiler-plugin/plugin.d.ts +1 -8
  34. package/dist/esm/start-compiler-plugin/plugin.js +6 -13
  35. package/dist/esm/start-compiler-plugin/plugin.js.map +1 -1
  36. package/dist/esm/start-router-plugin/constants.d.ts +1 -0
  37. package/dist/esm/start-router-plugin/constants.js +5 -0
  38. package/dist/esm/start-router-plugin/constants.js.map +1 -0
  39. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js +3 -9
  40. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js.map +1 -1
  41. package/dist/esm/start-router-plugin/plugin.d.ts +3 -2
  42. package/dist/esm/start-router-plugin/plugin.js +191 -31
  43. package/dist/esm/start-router-plugin/plugin.js.map +1 -1
  44. package/dist/esm/start-router-plugin/pruneServerOnlySubtrees.d.ts +8 -0
  45. package/dist/esm/start-router-plugin/pruneServerOnlySubtrees.js +34 -0
  46. package/dist/esm/start-router-plugin/pruneServerOnlySubtrees.js.map +1 -0
  47. package/package.json +8 -8
  48. package/src/constants.ts +3 -2
  49. package/src/create-server-fn-plugin/compiler.ts +498 -0
  50. package/src/{start-compiler-plugin/middleware.ts → create-server-fn-plugin/handleCreateMiddleware.ts} +15 -12
  51. package/src/{start-compiler-plugin/serverFn.ts → create-server-fn-plugin/handleCreateServerFn.ts} +32 -39
  52. package/src/create-server-fn-plugin/plugin.ts +153 -0
  53. package/src/dev-server-plugin/plugin.ts +6 -3
  54. package/src/plugin.ts +78 -87
  55. package/src/resolve-entries.ts +1 -2
  56. package/src/schema.ts +31 -14
  57. package/src/start-compiler-plugin/compilers.ts +18 -57
  58. package/src/start-compiler-plugin/constants.ts +0 -5
  59. package/src/start-compiler-plugin/plugin.ts +7 -22
  60. package/src/start-router-plugin/constants.ts +1 -0
  61. package/src/start-router-plugin/generator-plugins/routes-manifest-plugin.ts +3 -9
  62. package/src/start-router-plugin/plugin.ts +233 -45
  63. package/src/start-router-plugin/pruneServerOnlySubtrees.ts +51 -0
  64. package/dist/esm/debug.js +0 -5
  65. package/dist/esm/debug.js.map +0 -1
  66. package/dist/esm/start-compiler-plugin/middleware.d.ts +0 -4
  67. package/dist/esm/start-compiler-plugin/middleware.js.map +0 -1
  68. package/dist/esm/start-compiler-plugin/serverFileRoute.d.ts +0 -4
  69. package/dist/esm/start-compiler-plugin/serverFileRoute.js +0 -38
  70. package/dist/esm/start-compiler-plugin/serverFileRoute.js.map +0 -1
  71. package/dist/esm/start-compiler-plugin/serverFn.d.ts +0 -4
  72. package/dist/esm/start-compiler-plugin/serverFn.js.map +0 -1
  73. package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.d.ts +0 -2
  74. package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.js +0 -119
  75. package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.js.map +0 -1
  76. package/dist/esm/start-router-plugin/route-tree-client-plugin.d.ts +0 -6
  77. package/dist/esm/start-router-plugin/route-tree-client-plugin.js +0 -56
  78. package/dist/esm/start-router-plugin/route-tree-client-plugin.js.map +0 -1
  79. package/dist/esm/start-router-plugin/virtual-route-tree-plugin.d.ts +0 -3
  80. package/dist/esm/start-router-plugin/virtual-route-tree-plugin.js +0 -29
  81. package/dist/esm/start-router-plugin/virtual-route-tree-plugin.js.map +0 -1
  82. package/src/start-compiler-plugin/serverFileRoute.ts +0 -59
  83. package/src/start-router-plugin/generator-plugins/server-routes-plugin.ts +0 -138
  84. package/src/start-router-plugin/route-tree-client-plugin.ts +0 -77
  85. package/src/start-router-plugin/virtual-route-tree-plugin.ts +0 -29
@@ -1,39 +1,32 @@
1
1
  import * as t from '@babel/types'
2
- import { codeFrameError, getRootCallExpression } from './utils'
2
+ import {
3
+ codeFrameError,
4
+ getRootCallExpression,
5
+ } from '../start-compiler-plugin/utils'
3
6
  import type * as babel from '@babel/core'
4
7
 
5
- import type { CompileOptions } from './compilers'
6
-
7
- export function handleCreateServerFnCallExpression(
8
+ export function handleCreateServerFn(
8
9
  path: babel.NodePath<t.CallExpression>,
9
- opts: CompileOptions,
10
+ opts: {
11
+ env: 'client' | 'server'
12
+ code: string
13
+ },
10
14
  ) {
11
15
  // Traverse the member expression and find the call expressions for
12
16
  // the validator, handler, and middleware methods. Check to make sure they
13
17
  // are children of the createServerFn call expression.
14
18
 
15
- const calledOptions = path.node.arguments[0]
16
- ? (path.get('arguments.0') as babel.NodePath<t.ObjectExpression>)
17
- : null
18
-
19
- const shouldValidateClient = !!calledOptions?.node.properties.find((prop) => {
20
- return (
21
- t.isObjectProperty(prop) &&
22
- t.isIdentifier(prop.key) &&
23
- prop.key.name === 'validateClient' &&
24
- t.isBooleanLiteral(prop.value) &&
25
- prop.value.value === true
26
- )
27
- })
28
-
29
- const callExpressionPaths = {
30
- middleware: null as babel.NodePath<t.CallExpression> | null,
31
- validator: null as babel.NodePath<t.CallExpression> | null,
32
- handler: null as babel.NodePath<t.CallExpression> | null,
19
+ const validMethods = ['middleware', 'inputValidator', 'handler'] as const
20
+ type ValidMethods = (typeof validMethods)[number]
21
+ const callExpressionPaths: Record<
22
+ ValidMethods,
23
+ babel.NodePath<t.CallExpression> | null
24
+ > = {
25
+ middleware: null,
26
+ inputValidator: null,
27
+ handler: null,
33
28
  }
34
29
 
35
- const validMethods = Object.keys(callExpressionPaths)
36
-
37
30
  const rootCallExpression = getRootCallExpression(path)
38
31
 
39
32
  // if (debug)
@@ -54,8 +47,7 @@ export function handleCreateServerFnCallExpression(
54
47
  rootCallExpression.traverse({
55
48
  MemberExpression(memberExpressionPath) {
56
49
  if (t.isIdentifier(memberExpressionPath.node.property)) {
57
- const name = memberExpressionPath.node.property
58
- .name as keyof typeof callExpressionPaths
50
+ const name = memberExpressionPath.node.property.name as ValidMethods
59
51
 
60
52
  if (
61
53
  validMethods.includes(name) &&
@@ -67,24 +59,25 @@ export function handleCreateServerFnCallExpression(
67
59
  },
68
60
  })
69
61
 
70
- if (callExpressionPaths.validator) {
71
- const innerInputExpression = callExpressionPaths.validator.node.arguments[0]
62
+ if (callExpressionPaths.inputValidator) {
63
+ const innerInputExpression =
64
+ callExpressionPaths.inputValidator.node.arguments[0]
72
65
 
73
66
  if (!innerInputExpression) {
74
67
  throw new Error(
75
- 'createServerFn().validator() must be called with a validator!',
68
+ 'createServerFn().inputValidator() must be called with a validator!',
76
69
  )
77
70
  }
78
71
 
79
- // If we're on the client, and we're not validating the client, remove the validator call expression
80
- if (
81
- opts.env === 'client' &&
82
- !shouldValidateClient &&
83
- t.isMemberExpression(callExpressionPaths.validator.node.callee)
84
- ) {
85
- callExpressionPaths.validator.replaceWith(
86
- callExpressionPaths.validator.node.callee.object,
87
- )
72
+ // If we're on the client, remove the validator call expression
73
+ if (opts.env === 'client') {
74
+ if (
75
+ t.isMemberExpression(callExpressionPaths.inputValidator.node.callee)
76
+ ) {
77
+ callExpressionPaths.inputValidator.replaceWith(
78
+ callExpressionPaths.inputValidator.node.callee.object,
79
+ )
80
+ }
88
81
  }
89
82
  }
90
83
 
@@ -0,0 +1,153 @@
1
+ import { VITE_ENVIRONMENT_NAMES } from '../constants'
2
+ import { ServerFnCompiler } from './compiler'
3
+ import type { CompileStartFrameworkOptions } from '../start-compiler-plugin/compilers'
4
+ import type { ViteEnvironmentNames } from '../constants'
5
+ import type { PluginOption } from 'vite'
6
+
7
+ function cleanId(id: string): string {
8
+ return id.split('?')[0]!
9
+ }
10
+
11
+ export function createServerFnPlugin(
12
+ framework: CompileStartFrameworkOptions,
13
+ ): PluginOption {
14
+ const SERVER_FN_LOOKUP = 'server-fn-module-lookup'
15
+
16
+ const compilers: Partial<Record<ViteEnvironmentNames, ServerFnCompiler>> = {}
17
+ return [
18
+ {
19
+ name: 'tanstack-start-core:capture-server-fn-module-lookup',
20
+ // we only need this plugin in dev mode
21
+ apply: 'serve',
22
+ applyToEnvironment(env) {
23
+ return [
24
+ VITE_ENVIRONMENT_NAMES.client,
25
+ VITE_ENVIRONMENT_NAMES.server,
26
+ ].includes(env.name as ViteEnvironmentNames)
27
+ },
28
+ transform: {
29
+ filter: {
30
+ id: new RegExp(`${SERVER_FN_LOOKUP}$`),
31
+ },
32
+ handler(code, id) {
33
+ const compiler =
34
+ compilers[this.environment.name as ViteEnvironmentNames]
35
+ compiler?.ingestModule({ code, id: cleanId(id) })
36
+ },
37
+ },
38
+ },
39
+ {
40
+ name: 'tanstack-start-core::server-fn',
41
+ enforce: 'pre',
42
+
43
+ applyToEnvironment(env) {
44
+ return [
45
+ VITE_ENVIRONMENT_NAMES.client,
46
+ VITE_ENVIRONMENT_NAMES.server,
47
+ ].includes(env.name as ViteEnvironmentNames)
48
+ },
49
+ transform: {
50
+ filter: {
51
+ id: {
52
+ exclude: new RegExp(`${SERVER_FN_LOOKUP}$`),
53
+ },
54
+ code: {
55
+ // only scan files that mention `.handler(` | `.server(` | `.client(`
56
+ include: [/\.handler\(/, /\.server\(/, /\.client\(/],
57
+ },
58
+ },
59
+ async handler(code, id) {
60
+ let compiler =
61
+ compilers[this.environment.name as ViteEnvironmentNames]
62
+ if (!compiler) {
63
+ const env =
64
+ this.environment.name === VITE_ENVIRONMENT_NAMES.client
65
+ ? 'client'
66
+ : this.environment.name === VITE_ENVIRONMENT_NAMES.server
67
+ ? 'server'
68
+ : (() => {
69
+ throw new Error(
70
+ `Environment ${this.environment.name} not configured`,
71
+ )
72
+ })()
73
+
74
+ compiler = new ServerFnCompiler({
75
+ env,
76
+ lookupConfigurations: [
77
+ {
78
+ libName: `@tanstack/${framework}-start`,
79
+ rootExport: 'createMiddleware',
80
+ },
81
+
82
+ {
83
+ libName: `@tanstack/${framework}-start`,
84
+ rootExport: 'createServerFn',
85
+ },
86
+ {
87
+ libName: `@tanstack/${framework}-start`,
88
+ rootExport: 'createStart',
89
+ },
90
+ ],
91
+ loadModule: async (id: string) => {
92
+ if (this.environment.mode === 'build') {
93
+ const loaded = await this.load({ id })
94
+ if (!loaded.code) {
95
+ throw new Error(`could not load module ${id}`)
96
+ }
97
+ compiler!.ingestModule({ code: loaded.code, id })
98
+ } else if (this.environment.mode === 'dev') {
99
+ /**
100
+ * in dev, vite does not return code from `ctx.load()`
101
+ * so instead, we need to take a different approach
102
+ * we must force vite to load the module and run it through the vite plugin pipeline
103
+ * we can do this by using the `fetchModule` method
104
+ * the `captureServerFnModuleLookupPlugin` captures the module code via its transform hook and invokes analyzeModuleAST
105
+ */
106
+ await this.environment.fetchModule(
107
+ id + '?' + SERVER_FN_LOOKUP,
108
+ )
109
+ } else {
110
+ throw new Error(
111
+ `could not load module ${id}: unknown environment mode ${this.environment.mode}`,
112
+ )
113
+ }
114
+ },
115
+ resolveId: async (source: string, importer?: string) => {
116
+ const r = await this.resolve(source, importer)
117
+ if (r) {
118
+ if (!r.external) {
119
+ return cleanId(r.id)
120
+ }
121
+ }
122
+ return null
123
+ },
124
+ })
125
+ compilers[this.environment.name as ViteEnvironmentNames] = compiler
126
+ }
127
+
128
+ id = cleanId(id)
129
+ const result = await compiler.compile({ id, code })
130
+ return result
131
+ },
132
+ },
133
+
134
+ hotUpdate(ctx) {
135
+ const compiler =
136
+ compilers[this.environment.name as ViteEnvironmentNames]
137
+
138
+ ctx.modules.forEach((m) => {
139
+ if (m.id) {
140
+ const deleted = compiler?.invalidateModule(m.id)
141
+ if (deleted) {
142
+ m.importers.forEach((importer) => {
143
+ if (importer.id) {
144
+ compiler?.invalidateModule(importer.id)
145
+ }
146
+ })
147
+ }
148
+ }
149
+ })
150
+ },
151
+ },
152
+ ]
153
+ }
@@ -8,9 +8,9 @@ import type { Connect, DevEnvironment, PluginOption } from 'vite'
8
8
  import type { TanStackStartOutputConfig } from '../schema'
9
9
 
10
10
  export function devServerPlugin({
11
- startConfig,
11
+ getConfig,
12
12
  }: {
13
- startConfig: TanStackStartOutputConfig
13
+ getConfig: () => { startConfig: TanStackStartOutputConfig }
14
14
  }): PluginOption {
15
15
  let isTest = false
16
16
 
@@ -48,6 +48,7 @@ export function devServerPlugin({
48
48
  `Server environment ${VITE_ENVIRONMENT_NAMES.server} not found`,
49
49
  )
50
50
  }
51
+ const { startConfig } = getConfig()
51
52
  const installMiddleware = startConfig.vite?.installDevServerMiddleware
52
53
  if (installMiddleware === false) {
53
54
  return
@@ -98,7 +99,9 @@ export function devServerPlugin({
98
99
  return sendNodeResponse(res, webRes)
99
100
  } catch (e) {
100
101
  console.error(e)
101
- viteDevServer.ssrFixStacktrace(e as Error)
102
+ try {
103
+ viteDevServer.ssrFixStacktrace(e as Error)
104
+ } catch (_e) {}
102
105
 
103
106
  if (
104
107
  webReq.headers.get('content-type')?.includes('application/json')
package/src/plugin.ts CHANGED
@@ -18,8 +18,12 @@ import {
18
18
  getServerOutputDirectory,
19
19
  } from './output-directory'
20
20
  import { postServerBuild } from './post-server-build'
21
+ import { createServerFnPlugin } from './create-server-fn-plugin/plugin'
21
22
  import type { ViteEnvironmentNames } from './constants'
22
- import type { TanStackStartInputConfig } from './schema'
23
+ import type {
24
+ TanStackStartInputConfig,
25
+ TanStackStartOutputConfig,
26
+ } from './schema'
23
27
  import type { PluginOption } from 'vite'
24
28
  import type { CompileStartFrameworkOptions } from './start-compiler-plugin/compilers'
25
29
 
@@ -28,19 +32,46 @@ export interface TanStackStartVitePluginCoreOptions {
28
32
  defaultEntryPaths: {
29
33
  client: string
30
34
  server: string
35
+ start: string
31
36
  }
32
- crawlPackages?: (opts: {
33
- name: string
34
- peerDependencies: Record<string, any>
35
- exports?: Record<string, any> | string
36
- }) => 'include' | 'exclude' | undefined
37
37
  }
38
38
 
39
+ export interface ResolvedStartConfig {
40
+ root: string
41
+ startFilePath: string | undefined
42
+ routerFilePath: string
43
+ srcDirectory: string
44
+ }
45
+
46
+ export type GetConfigFn = () => {
47
+ startConfig: TanStackStartOutputConfig
48
+ resolvedStartConfig: ResolvedStartConfig
49
+ }
39
50
  export function TanStackStartVitePluginCore(
40
51
  corePluginOpts: TanStackStartVitePluginCoreOptions,
41
52
  startPluginOpts: TanStackStartInputConfig,
42
53
  ): Array<PluginOption> {
43
- const startConfig = parseStartConfig(startPluginOpts)
54
+ const resolvedStartConfig: ResolvedStartConfig = {
55
+ root: '',
56
+ startFilePath: undefined,
57
+ routerFilePath: '',
58
+ srcDirectory: '',
59
+ }
60
+
61
+ let startConfig: TanStackStartOutputConfig | null
62
+ const getConfig: GetConfigFn = () => {
63
+ if (!resolvedStartConfig.root) {
64
+ throw new Error(`Cannot get config before root is resolved`)
65
+ }
66
+ if (!startConfig) {
67
+ startConfig = parseStartConfig(
68
+ startPluginOpts,
69
+ corePluginOpts,
70
+ resolvedStartConfig.root,
71
+ )
72
+ }
73
+ return { startConfig, resolvedStartConfig }
74
+ }
44
75
 
45
76
  const capturedBundle: Partial<
46
77
  Record<ViteEnvironmentNames, vite.Rollup.OutputBundle>
@@ -55,33 +86,42 @@ export function TanStackStartVitePluginCore(
55
86
  }
56
87
 
57
88
  return [
58
- tanStackStartRouter({
59
- ...startConfig.router,
60
- target: corePluginOpts.framework,
61
- autoCodeSplitting: true,
62
- }),
63
89
  {
64
90
  name: 'tanstack-start-core:config',
91
+ enforce: 'pre',
65
92
  async config(viteConfig, { command }) {
66
93
  const viteAppBase = trimPathRight(viteConfig.base || '/')
67
94
  globalThis.TSS_APP_BASE = viteAppBase
68
95
 
69
96
  const root = viteConfig.root || process.cwd()
97
+ resolvedStartConfig.root = root
98
+
99
+ const { startConfig } = getConfig()
70
100
  const resolvedSrcDirectory = join(root, startConfig.srcDirectory)
101
+ resolvedStartConfig.srcDirectory = resolvedSrcDirectory
102
+
103
+ const startFilePath = resolveEntry({
104
+ type: 'start entry',
105
+ configuredEntry: startConfig.start.entry,
106
+ defaultEntry: 'start',
107
+ resolvedSrcDirectory,
108
+ required: false,
109
+ })
110
+ resolvedStartConfig.startFilePath = startFilePath
71
111
 
72
112
  const routerFilePath = resolveEntry({
73
113
  type: 'router entry',
74
114
  configuredEntry: startConfig.router.entry,
75
115
  defaultEntry: 'router',
76
- root,
77
116
  resolvedSrcDirectory,
78
117
  required: true,
79
118
  })
119
+ resolvedStartConfig.routerFilePath = routerFilePath
120
+
80
121
  const clientEntryPath = resolveEntry({
81
122
  type: 'client entry',
82
123
  configuredEntry: startConfig.client.entry,
83
124
  defaultEntry: 'client',
84
- root,
85
125
  resolvedSrcDirectory,
86
126
  required: false,
87
127
  })
@@ -90,7 +130,6 @@ export function TanStackStartVitePluginCore(
90
130
  type: 'server entry',
91
131
  configuredEntry: startConfig.server.entry,
92
132
  defaultEntry: 'server',
93
- root,
94
133
  resolvedSrcDirectory,
95
134
  required: false,
96
135
  })
@@ -103,42 +142,33 @@ export function TanStackStartVitePluginCore(
103
142
  } else {
104
143
  clientAlias = corePluginOpts.defaultEntryPaths.client
105
144
  }
145
+
106
146
  let serverAlias: string
107
147
  if (serverEntryPath) {
108
148
  serverAlias = vite.normalizePath(path.resolve(root, serverEntryPath))
109
149
  } else {
110
150
  serverAlias = corePluginOpts.defaultEntryPaths.server
111
151
  }
152
+
153
+ let startAlias: string
154
+ if (startFilePath) {
155
+ startAlias = vite.normalizePath(path.resolve(root, startFilePath))
156
+ } else {
157
+ startAlias = corePluginOpts.defaultEntryPaths.start
158
+ }
159
+
112
160
  const entryAliasConfiguration: Record<
113
161
  (typeof ENTRY_POINTS)[keyof typeof ENTRY_POINTS],
114
162
  string
115
163
  > = {
164
+ [ENTRY_POINTS.start]: startAlias,
116
165
  [ENTRY_POINTS.router]: routerFilePath,
117
166
  [ENTRY_POINTS.client]: clientAlias,
118
167
  [ENTRY_POINTS.server]: serverAlias,
119
168
  }
120
169
 
121
- // TODO
122
- /* const nitroOutputPublicDir = await (async () => {
123
- // Create a dummy nitro app to get the resolved public output path
124
- const dummyNitroApp = await createNitro({
125
- preset: startConfig.target,
126
- compatibilityDate: '2024-12-01',
127
- })
128
-
129
- const nitroOutputPublicDir = dummyNitroApp.options.output.publicDir
130
- await dummyNitroApp.close()
131
-
132
- return nitroOutputPublicDir
133
- })()*/
134
-
135
- const startPackageName = `@tanstack/${corePluginOpts.framework}-start`
136
- const routerPackageName = `@tanstack/${corePluginOpts.framework}-router`
137
-
138
- const additionalOptimizeDeps = {
139
- include: new Set<string>(),
140
- exclude: new Set<string>(),
141
- }
170
+ const startPackageName =
171
+ `@tanstack/${corePluginOpts.framework}-start` as const
142
172
 
143
173
  // crawl packages that have start in "peerDependencies"
144
174
  // see https://github.com/svitejs/vitefu/blob/d8d82fa121e3b2215ba437107093c77bde51b63b/src/index.js#L95-L101
@@ -146,34 +176,16 @@ export function TanStackStartVitePluginCore(
146
176
  // this is currently uncached; could be implemented similarly as vite handles lock file changes
147
177
  // see https://github.com/vitejs/vite/blob/557f797d29422027e8c451ca50dd84bf8c41b5f0/packages/vite/src/node/optimizer/index.ts#L1282
148
178
 
149
- const result = await crawlFrameworkPkgs({
179
+ const crawlFrameworkPkgsResult = await crawlFrameworkPkgs({
150
180
  root: process.cwd(),
151
181
  isBuild: command === 'build',
152
182
  isFrameworkPkgByJson(pkgJson) {
153
- if ([routerPackageName, startPackageName].includes(pkgJson.name)) {
154
- return false
155
- }
156
-
157
183
  const peerDependencies = pkgJson['peerDependencies']
158
184
 
159
185
  if (peerDependencies) {
160
- const internalResult = corePluginOpts.crawlPackages?.({
161
- name: pkgJson.name,
162
- peerDependencies,
163
- exports: pkgJson.exports,
164
- })
165
- if (internalResult) {
166
- if (internalResult === 'exclude') {
167
- additionalOptimizeDeps.exclude.add(pkgJson.name)
168
- } else {
169
- additionalOptimizeDeps.include.add(pkgJson.name)
170
- }
171
- }
172
- return (
173
- startPackageName in peerDependencies ||
174
- routerPackageName in peerDependencies
175
- )
186
+ return startPackageName in peerDependencies
176
187
  }
188
+
177
189
  return false
178
190
  },
179
191
  })
@@ -197,6 +209,7 @@ export function TanStackStartVitePluginCore(
197
209
  },
198
210
  [VITE_ENVIRONMENT_NAMES.server]: {
199
211
  consumer: 'server',
212
+
200
213
  build: {
201
214
  ssr: true,
202
215
  rollupOptions: {
@@ -212,42 +225,20 @@ export function TanStackStartVitePluginCore(
212
225
  viteConfig.environments?.[VITE_ENVIRONMENT_NAMES.server]
213
226
  ?.build?.copyPublicDir ?? false,
214
227
  },
215
- optimizeDeps: {
216
- exclude: [
217
- ...Object.values(VIRTUAL_MODULES),
218
- ...result.optimizeDeps.exclude.sort(),
219
- ...additionalOptimizeDeps.exclude,
220
- `@tanstack/${corePluginOpts.framework}-start/server`,
221
- ],
222
- include: [
223
- ...additionalOptimizeDeps.include,
224
- ...result.optimizeDeps.include.sort(),
225
- ],
226
- },
227
228
  },
228
229
  },
230
+
229
231
  resolve: {
230
232
  noExternal: [
233
+ // ENTRY_POINTS.start,
231
234
  '@tanstack/start**',
232
235
  `@tanstack/${corePluginOpts.framework}-start**`,
233
- ...Object.values(VIRTUAL_MODULES),
234
- startPackageName,
235
- ...result.ssr.noExternal.sort(),
236
+ ...crawlFrameworkPkgsResult.ssr.noExternal.sort(),
236
237
  ],
237
- dedupe: [startPackageName],
238
238
  alias: {
239
239
  ...entryAliasConfiguration,
240
240
  },
241
241
  },
242
- optimizeDeps: {
243
- exclude: [
244
- ...Object.values(VIRTUAL_MODULES),
245
- startPackageName,
246
- ...result.optimizeDeps.exclude.sort(),
247
- ...additionalOptimizeDeps.exclude,
248
- ],
249
- include: [...additionalOptimizeDeps.include],
250
- },
251
242
  /* prettier-ignore */
252
243
  define: {
253
244
  // define is an esbuild function that replaces the any instances of given keys with the given values
@@ -289,11 +280,11 @@ export function TanStackStartVitePluginCore(
289
280
  }
290
281
  },
291
282
  },
283
+ tanStackStartRouter(startPluginOpts, getConfig, corePluginOpts),
292
284
  // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv
293
- startCompilerPlugin(corePluginOpts.framework, {
294
- client: { envName: VITE_ENVIRONMENT_NAMES.client },
295
- server: { envName: VITE_ENVIRONMENT_NAMES.server },
296
- }),
285
+ startCompilerPlugin(corePluginOpts.framework),
286
+ createServerFnPlugin(corePluginOpts.framework),
287
+
297
288
  TanStackServerFnPluginEnv({
298
289
  // This is the ID that will be available to look up and import
299
290
  // our server function manifest and resolve its module
@@ -315,7 +306,7 @@ export function TanStackStartVitePluginCore(
315
306
  startManifestPlugin({
316
307
  getClientBundle: () => getBundle(VITE_ENVIRONMENT_NAMES.client),
317
308
  }),
318
- devServerPlugin({ startConfig }),
309
+ devServerPlugin({ getConfig }),
319
310
  {
320
311
  name: 'tanstack-start:core:capture-bundle',
321
312
  applyToEnvironment(e) {
@@ -24,7 +24,6 @@ export function resolveEntry<
24
24
  configuredEntry?: string
25
25
  defaultEntry: string
26
26
  resolvedSrcDirectory: string
27
- root: string
28
27
  required: TRequired
29
28
  }): TReturn {
30
29
  let resolveOptions: ResolveModuleOptions
@@ -38,7 +37,7 @@ export function resolveEntry<
38
37
  } else {
39
38
  resolveOptions = {
40
39
  baseName: opts.configuredEntry,
41
- from: opts.root,
40
+ from: opts.resolvedSrcDirectory,
42
41
  }
43
42
  }
44
43
 
package/src/schema.ts CHANGED
@@ -1,32 +1,44 @@
1
1
  import path from 'node:path'
2
2
  import { z } from 'zod'
3
- import { configSchema, getConfig } from '@tanstack/router-generator'
3
+ import { configSchema, getConfig } from '@tanstack/router-plugin'
4
+ import type { TanStackStartVitePluginCoreOptions } from './plugin'
4
5
 
5
- const tsrConfig = configSchema.omit({ autoCodeSplitting: true }).partial()
6
+ const tsrConfig = configSchema
7
+ .omit({ autoCodeSplitting: true, target: true, verboseFileRoutes: true })
8
+ .partial()
6
9
 
7
10
  export function parseStartConfig(
8
- opts?: z.input<typeof tanstackStartOptionsSchema>,
11
+ opts: z.input<typeof tanstackStartOptionsSchema>,
12
+ corePluginOpts: TanStackStartVitePluginCoreOptions,
13
+ root: string,
9
14
  ) {
10
15
  const options = tanstackStartOptionsSchema.parse(opts)
11
16
 
12
17
  const srcDirectory = options.srcDirectory
13
18
 
14
- const routesDirectory =
15
- options.router.routesDirectory ?? path.join(srcDirectory, 'routes')
19
+ const routesDirectory = path.resolve(
20
+ srcDirectory,
21
+ options.router.routesDirectory ?? 'routes',
22
+ )
16
23
 
17
- const generatedRouteTree =
18
- options.router.generatedRouteTree ??
19
- path.join(srcDirectory, 'routeTree.gen.ts')
24
+ const generatedRouteTree = path.resolve(
25
+ srcDirectory,
26
+ options.router.generatedRouteTree ?? 'routeTree.gen.ts',
27
+ )
20
28
 
21
29
  return {
22
30
  ...options,
23
31
  router: {
24
32
  ...options.router,
25
- ...getConfig({
26
- ...options.router,
27
- routesDirectory,
28
- generatedRouteTree,
29
- }),
33
+ ...getConfig(
34
+ {
35
+ ...options.router,
36
+ routesDirectory,
37
+ generatedRouteTree,
38
+ },
39
+ root,
40
+ ),
41
+ target: corePluginOpts.framework,
30
42
  },
31
43
  }
32
44
  }
@@ -115,9 +127,14 @@ const pageSchema = pageBaseSchema.extend({
115
127
  const tanstackStartOptionsSchema = z
116
128
  .object({
117
129
  srcDirectory: z.string().optional().default('src'),
130
+ start: z
131
+ .object({
132
+ entry: z.string().optional(),
133
+ })
134
+ .optional()
135
+ .default({}),
118
136
  router: z
119
137
  .object({
120
- // TODO this will move to 'start' once we have `createStart`
121
138
  entry: z.string().optional(),
122
139
  })
123
140
  .and(tsrConfig.optional().default({}))