Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/four-olives-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/start-plugin-core': patch
---

Omit build-only route file paths from the production Start manifest so identical builds do not depend on their checkout directory.
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,10 @@ export function buildStartManifest(options: {

dedupeNestedRouteManifestEntries(rootRouteId, routes[rootRouteId]!, routes)

// Prune routes with no manifest data
// Remove build-only paths and prune routes with no manifest data
for (const routeId in routes) {
const route = routes[routeId]!
delete route.filePath
const hasScripts = route.scripts && route.scripts.length > 0
const hasCssLinks = route.css && route.css.length > 0
const hasPreloads = route.preloads && route.preloads.length > 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,57 @@ describe('createChunkCssAssetCollector', () => {
})

describe('buildStartManifest', () => {
// https://github.com/TanStack/router/commit/49b01ffea0304938d5ec9a9822c8bb8ea5c18091
test('production manifests are independent of the checkout path', () => {
const outputs = ['/checkout/app', '/another/location/app'].map((root) => {
const rootPath = `${root}/src/routes/__root.tsx`
const aboutPath = `${root}/src/routes/about.tsx`
const routeTreeRoutes = {
__root__: Object.freeze({
filePath: rootPath,
children: ['/about'],
}),
'/about': Object.freeze({ filePath: aboutPath }),
}
const manifest = buildStartManifest({
clientBuild: normalizeTestBuild({
'entry.js': makeChunk({
fileName: 'entry.js',
isEntry: true,
importedCss: ['entry.css'],
moduleIds: [`${rootPath}?tsr-split=component`],
}),
'about.js': makeChunk({
fileName: 'about.js',
importedCss: ['about.css'],
moduleIds: [`${aboutPath}?tsr-split=component`],
}),
}),
routeTreeRoutes,
basePath: '/assets',
})
const serialized = serializeStartManifest(manifest)
const emitted = deserializeSerializedManifest(serialized)

expect(routeTreeRoutes.__root__).toEqual({
filePath: rootPath,
children: ['/about'],
})
expect(routeTreeRoutes['/about']).toEqual({ filePath: aboutPath })
expect(emitted.routes.__root__?.preloads).toEqual(['/assets/entry.js'])
expect(emitted.routes.__root__?.scripts).toEqual([
{ attrs: { type: 'module', async: true, src: '/assets/entry.js' } },
])
expect(emitted.routes.__root__?.css).toEqual(['/assets/entry.css'])
expect(emitted.routes['/about']?.preloads).toEqual(['/assets/about.js'])
expect(emitted.routes['/about']?.css).toEqual(['/assets/about.css'])

return serialized
})

expect(outputs[0]).toBe(outputs[1])
})

test('skips inline CSS transforms when no relative URLs need rebasing', () => {
expect(shouldRebaseInlineCssUrls('.root {\n color: red;\n}')).toBe(false)
expect(shouldRebaseInlineCssUrls('.root{background:url(/dot.svg)}')).toBe(
Expand Down