@tanstack/start-plugin-core 1.167.33 → 1.167.35

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.
@@ -1,53 +1,136 @@
1
1
  import { joinURL } from 'ufo'
2
2
  import { VIRTUAL_MODULES } from '@tanstack/start-server-core'
3
+ import { rootRouteId } from '@tanstack/router-core'
3
4
  import { ENTRY_POINTS, START_ENVIRONMENT_NAMES } from '../../constants'
4
5
  import {
5
6
  buildStartManifest,
7
+ createManifestAssetResolvers,
8
+ normalizeViteClientBuild,
6
9
  serializeStartManifest,
7
10
  } from '../../start-manifest-plugin/manifestBuilder'
8
11
  import { createVirtualModule } from '../createVirtualModule'
9
12
  import type { GetConfigFn, NormalizedClientBuild } from '../../types'
10
- import type { PluginOption } from 'vite'
13
+ import type { PluginOption, Rollup } from 'vite'
11
14
 
12
15
  export function startManifestPlugin(opts: {
13
- getClientBuild: () => NormalizedClientBuild | undefined
14
16
  getConfig: GetConfigFn
15
17
  }): PluginOption {
16
- return createVirtualModule({
17
- name: 'tanstack-start:start-manifest-plugin',
18
- moduleId: VIRTUAL_MODULES.startManifest,
19
- enforce: 'pre',
20
- load() {
21
- const { resolvedStartConfig } = opts.getConfig()
22
- if (this.environment.name !== START_ENVIRONMENT_NAMES.server) {
23
- return 'export default {}'
24
- }
25
-
26
- if (this.environment.config.command === 'serve') {
27
- return `export const tsrStartManifest = () => ({
28
- routes: {},
29
- clientEntry: '${joinURL(resolvedStartConfig.basePaths.publicBase, '@id', ENTRY_POINTS.client)}',
30
- })`
31
- }
32
-
33
- const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST
34
- const clientBuild = opts.getClientBuild()
35
- // TODO this needs further discussion with vite-rsc, this is a temporary workaround
36
- // If the client bundle isn't available yet (e.g., during RSC scan builds),
37
- // return a dummy manifest. The real manifest will be generated in the actual build.
38
- if (!clientBuild) {
39
- return `export const tsrStartManifest = () => ({
40
- routes: {},
41
- clientEntry: '${joinURL(resolvedStartConfig.basePaths.publicBase, '@id', ENTRY_POINTS.client)}',
42
- })`
43
- }
44
- const startManifest = buildStartManifest({
45
- clientBuild,
46
- routeTreeRoutes,
47
- basePath: resolvedStartConfig.basePaths.publicBase,
48
- })
49
-
50
- return `export const tsrStartManifest = () => (${serializeStartManifest(startManifest)})`
18
+ let clientBuild: NormalizedClientBuild | undefined
19
+ let cssCodeSplitDisabledFileName: string | undefined
20
+
21
+ return [
22
+ {
23
+ name: 'tanstack-start:start-manifest-capture-client-build',
24
+ applyToEnvironment(environment) {
25
+ return environment.name === START_ENVIRONMENT_NAMES.client
26
+ },
27
+ enforce: 'post',
28
+ generateBundle(_options, bundle) {
29
+ if (this.environment.name !== START_ENVIRONMENT_NAMES.client) {
30
+ throw new Error(
31
+ `Unexpected environment for client build capture: ${this.environment.name}`,
32
+ )
33
+ }
34
+
35
+ clientBuild = normalizeViteClientBuild(bundle)
36
+ cssCodeSplitDisabledFileName = getAssetFileNameByName(
37
+ bundle,
38
+ 'style.css',
39
+ )
40
+ },
51
41
  },
52
- })
42
+ createVirtualModule({
43
+ name: 'tanstack-start:start-manifest-plugin',
44
+ moduleId: VIRTUAL_MODULES.startManifest,
45
+ enforce: 'pre',
46
+ load() {
47
+ const { resolvedStartConfig } = opts.getConfig()
48
+ const clientEntry = joinURL(
49
+ resolvedStartConfig.basePaths.publicBase,
50
+ '@id',
51
+ ENTRY_POINTS.client,
52
+ )
53
+
54
+ if (this.environment.name !== START_ENVIRONMENT_NAMES.server) {
55
+ return getEmptyStartManifestModule(clientEntry)
56
+ }
57
+
58
+ if (this.environment.config.command === 'serve') {
59
+ return getEmptyStartManifestModule(clientEntry)
60
+ }
61
+
62
+ const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST
63
+ // TODO this needs further discussion with vite-rsc, this is a temporary workaround
64
+ // If the client bundle isn't available yet (e.g., during RSC scan builds),
65
+ // return a dummy manifest. The real manifest will be generated in the actual build.
66
+ if (!clientBuild) {
67
+ return getEmptyStartManifestModule(clientEntry)
68
+ }
69
+ const startManifest = buildStartManifest({
70
+ clientBuild,
71
+ routeTreeRoutes,
72
+ basePath: resolvedStartConfig.basePaths.publicBase,
73
+ additionalRouteAssets: getViteAdditionalRouteAssets({
74
+ cssCodeSplitDisabledFileName,
75
+ basePath: resolvedStartConfig.basePaths.publicBase,
76
+ cssCodeSplit: this.environment.config.build.cssCodeSplit,
77
+ }),
78
+ })
79
+
80
+ return `export const tsrStartManifest = () => (${serializeStartManifest(startManifest)})`
81
+ },
82
+ }),
83
+ ]
84
+ }
85
+
86
+ function getViteAdditionalRouteAssets(options: {
87
+ cssCodeSplitDisabledFileName: string | undefined
88
+ basePath: string
89
+ cssCodeSplit: boolean | undefined
90
+ }) {
91
+ if (options.cssCodeSplit !== false) {
92
+ return undefined
93
+ }
94
+
95
+ if (!options.cssCodeSplitDisabledFileName) {
96
+ throw new Error(
97
+ "TanStack Start could not find Vite's generated `style.css` manifest entry while `build.cssCodeSplit` is disabled",
98
+ )
99
+ }
100
+
101
+ const { getStylesheetAsset } = createManifestAssetResolvers(options.basePath)
102
+
103
+ return {
104
+ [rootRouteId]: [getStylesheetAsset(options.cssCodeSplitDisabledFileName)],
105
+ }
106
+ }
107
+
108
+ function getAssetFileNameByName(
109
+ bundle: Rollup.OutputBundle,
110
+ assetName: string,
111
+ ) {
112
+ for (const fileName in bundle) {
113
+ const bundleEntry = bundle[fileName]!
114
+
115
+ if (bundleEntry.type !== 'asset') {
116
+ continue
117
+ }
118
+
119
+ if (bundleEntry.name === assetName) {
120
+ return fileName
121
+ }
122
+
123
+ if ('names' in bundleEntry && bundleEntry.names.includes(assetName)) {
124
+ return fileName
125
+ }
126
+ }
127
+
128
+ return undefined
129
+ }
130
+
131
+ function getEmptyStartManifestModule(clientEntry: string) {
132
+ return `export const tsrStartManifest = () => ({
133
+ routes: {},
134
+ clientEntry: '${clientEntry}',
135
+ })`
53
136
  }