Skip to content

Commit 9252206

Browse files
fix: asset sorting (#7251)
1 parent bd01585 commit 9252206

3 files changed

Lines changed: 57 additions & 14 deletions

File tree

.changeset/start-asset-sorting.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tanstack/start-plugin-core': patch
3+
---
4+
5+
Fix CSS asset ordering so styles from imported chunks are emitted before route chunk styles.

packages/start-plugin-core/src/start-manifest-plugin/manifestBuilder.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,6 @@ export function createChunkCssAssetCollector(options: {
323323
const assets: Array<RouterManagedTag> = []
324324
const seenAssets = new Set<RouterManagedTag>()
325325

326-
for (const cssFile of chunk.css) {
327-
appendAsset(assets, seenAssets, options.getStylesheetAsset(cssFile))
328-
}
329-
330326
for (let i = 0; i < chunk.imports.length; i++) {
331327
const importedChunk = options.chunksByFileName.get(chunk.imports[i]!)
332328
if (!importedChunk) {
@@ -339,6 +335,10 @@ export function createChunkCssAssetCollector(options: {
339335
}
340336
}
341337

338+
for (const cssFile of chunk.css) {
339+
appendAsset(assets, seenAssets, options.getStylesheetAsset(cssFile))
340+
}
341+
342342
stateByChunk.delete(chunk)
343343
assetsByChunk.set(chunk, assets)
344344
return assets

packages/start-plugin-core/tests/start-manifest-plugin/manifestBuilder.test.ts

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,15 @@ describe('createManifestAssetResolvers + createChunkCssAssetCollector', () => {
289289
tag: 'link',
290290
attrs: {
291291
rel: 'stylesheet',
292-
href: '/assets/entry.css',
292+
href: '/assets/shared.css',
293293
type: 'text/css',
294294
},
295295
},
296296
{
297297
tag: 'link',
298298
attrs: {
299299
rel: 'stylesheet',
300-
href: '/assets/shared.css',
300+
href: '/assets/entry.css',
301301
type: 'text/css',
302302
},
303303
},
@@ -348,10 +348,10 @@ describe('createChunkCssAssetCollector', () => {
348348
const assets = getChunkCssAssets(chunksByFileName.get('a.js')!)
349349

350350
expect(assets.map((asset: any) => asset.attrs.href)).toEqual([
351-
'/a.css',
352-
'/b.css',
353351
'/shared.css',
352+
'/b.css',
354353
'/c.css',
354+
'/a.css',
355355
])
356356
})
357357

@@ -497,15 +497,15 @@ describe('buildStartManifest', () => {
497497
tag: 'link',
498498
attrs: {
499499
rel: 'stylesheet',
500-
href: '/assets/branch-a.css',
500+
href: '/assets/shared.css',
501501
type: 'text/css',
502502
},
503503
},
504504
{
505505
tag: 'link',
506506
attrs: {
507507
rel: 'stylesheet',
508-
href: '/assets/shared.css',
508+
href: '/assets/branch-a.css',
509509
type: 'text/css',
510510
},
511511
},
@@ -520,6 +520,44 @@ describe('buildStartManifest', () => {
520520
])
521521
})
522522

523+
test('orders imported chunk css before route chunk css', () => {
524+
const entryChunk = makeChunk({
525+
fileName: 'entry.js',
526+
isEntry: true,
527+
})
528+
const routeChunk = makeChunk({
529+
fileName: 'field-detail-panel.js',
530+
imports: ['tabs.js'],
531+
importedCss: ['field-detail-panel.css'],
532+
moduleIds: ['/routes/field-detail-panel.tsx?tsr-split=component'],
533+
})
534+
const tabsChunk = makeChunk({
535+
fileName: 'tabs.js',
536+
importedCss: ['tabs.css'],
537+
})
538+
539+
const manifest = buildStartManifest({
540+
clientBuild: normalizeViteClientBuild({
541+
'entry.js': entryChunk,
542+
'field-detail-panel.js': routeChunk,
543+
'tabs.js': tabsChunk,
544+
}),
545+
routeTreeRoutes: {
546+
__root__: { children: ['/field-detail-panel'] } as any,
547+
'/field-detail-panel': {
548+
filePath: '/routes/field-detail-panel.tsx',
549+
},
550+
},
551+
basePath: '/assets',
552+
})
553+
554+
expect(
555+
manifest.routes['/field-detail-panel']!.assets!.map(
556+
(asset: any) => asset.attrs.href,
557+
),
558+
).toEqual(['/assets/tabs.css', '/assets/field-detail-panel.css'])
559+
})
560+
523561
test('dedupes route css already owned by ancestor routes', () => {
524562
const entryChunk = makeChunk({
525563
fileName: 'entry.js',
@@ -725,15 +763,15 @@ describe('route tree dedupe in buildStartManifest', () => {
725763
tag: 'link',
726764
attrs: {
727765
rel: 'stylesheet',
728-
href: '/assets/root.css',
766+
href: '/assets/shared.css',
729767
type: 'text/css',
730768
},
731769
},
732770
{
733771
tag: 'link',
734772
attrs: {
735773
rel: 'stylesheet',
736-
href: '/assets/shared.css',
774+
href: '/assets/root.css',
737775
type: 'text/css',
738776
},
739777
},
@@ -952,15 +990,15 @@ describe('route tree dedupe in buildStartManifest', () => {
952990
tag: 'link',
953991
attrs: {
954992
rel: 'stylesheet',
955-
href: '/assets/root.css',
993+
href: '/assets/shared-root.css',
956994
type: 'text/css',
957995
},
958996
},
959997
{
960998
tag: 'link',
961999
attrs: {
9621000
rel: 'stylesheet',
963-
href: '/assets/shared-root.css',
1001+
href: '/assets/root.css',
9641002
type: 'text/css',
9651003
},
9661004
},

0 commit comments

Comments
 (0)