Make CSS chunk names less confusing (#8754)
This commit is contained in:
parent
eaed844ea8
commit
93b092266f
3 changed files with 52 additions and 22 deletions
5
.changeset/sharp-insects-yawn.md
Normal file
5
.changeset/sharp-insects-yawn.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Make CSS chunk names less confusing
|
|
@ -1,4 +1,4 @@
|
||||||
import type { GetModuleInfo } from 'rollup';
|
import type { GetModuleInfo, ModuleInfo } from 'rollup';
|
||||||
|
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
import npath from 'node:path';
|
import npath from 'node:path';
|
||||||
|
@ -6,20 +6,29 @@ import type { AstroSettings } from '../../@types/astro.js';
|
||||||
import { viteID } from '../util.js';
|
import { viteID } from '../util.js';
|
||||||
import { getTopLevelPages } from './graph.js';
|
import { getTopLevelPages } from './graph.js';
|
||||||
|
|
||||||
|
// These pages could be used as base names for the chunk hashed name, but they are confusing
|
||||||
|
// and should be avoided it possible
|
||||||
|
const confusingBaseNames = ['404', '500'];
|
||||||
|
|
||||||
// The short name for when the hash can be included
|
// The short name for when the hash can be included
|
||||||
// We could get rid of this and only use the createSlugger implementation, but this creates
|
// We could get rid of this and only use the createSlugger implementation, but this creates
|
||||||
// slightly prettier names.
|
// slightly prettier names.
|
||||||
export function shortHashedName(id: string, ctx: { getModuleInfo: GetModuleInfo }): string {
|
export function shortHashedName(id: string, ctx: { getModuleInfo: GetModuleInfo }): string {
|
||||||
const parents = Array.from(getTopLevelPages(id, ctx));
|
const parents = Array.from(getTopLevelPages(id, ctx));
|
||||||
const firstParentId = parents[0]?.[0].id;
|
return createNameHash(
|
||||||
const firstParentName = firstParentId ? npath.parse(firstParentId).name : 'index';
|
getFirstParentId(parents),
|
||||||
|
parents.map(([page]) => page.id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createNameHash(baseId: string | undefined, hashIds: string[]): string {
|
||||||
|
const baseName = baseId ? prettifyBaseName(npath.parse(baseId).name) : 'index';
|
||||||
const hash = crypto.createHash('sha256');
|
const hash = crypto.createHash('sha256');
|
||||||
for (const [page] of parents) {
|
for (const id of hashIds) {
|
||||||
hash.update(page.id, 'utf-8');
|
hash.update(id, 'utf-8');
|
||||||
}
|
}
|
||||||
const h = hash.digest('hex').slice(0, 8);
|
const h = hash.digest('hex').slice(0, 8);
|
||||||
const proposedName = firstParentName + '.' + h;
|
const proposedName = baseName + '.' + h;
|
||||||
return proposedName;
|
return proposedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +43,7 @@ export function createSlugger(settings: AstroSettings) {
|
||||||
.map(([page]) => page.id)
|
.map(([page]) => page.id)
|
||||||
.sort()
|
.sort()
|
||||||
.join('-');
|
.join('-');
|
||||||
const firstParentId = parents[0]?.[0].id || indexPage;
|
const firstParentId = getFirstParentId(parents) || indexPage;
|
||||||
|
|
||||||
// Use the last two segments, for ex /docs/index
|
// Use the last two segments, for ex /docs/index
|
||||||
let dir = firstParentId;
|
let dir = firstParentId;
|
||||||
|
@ -45,7 +54,7 @@ export function createSlugger(settings: AstroSettings) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = npath.parse(npath.basename(dir)).name;
|
const name = prettifyBaseName(npath.parse(npath.basename(dir)).name);
|
||||||
key = key.length ? name + sep + key : name;
|
key = key.length ? name + sep + key : name;
|
||||||
dir = npath.dirname(dir);
|
dir = npath.dirname(dir);
|
||||||
i++;
|
i++;
|
||||||
|
@ -76,3 +85,32 @@ export function createSlugger(settings: AstroSettings) {
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the first parent id from `parents` where its name is not confusing.
|
||||||
|
* Returns undefined if there's no parents.
|
||||||
|
*/
|
||||||
|
function getFirstParentId(parents: [ModuleInfo, number, number][]) {
|
||||||
|
for (const parent of parents) {
|
||||||
|
const id = parent[0].id;
|
||||||
|
const baseName = npath.parse(id).name;
|
||||||
|
if (!confusingBaseNames.includes(baseName)) {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If all parents are confusing, just use the first one. Or if there's no
|
||||||
|
// parents, this will return undefined.
|
||||||
|
return parents[0]?.[0].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const charsToReplaceRe = /[.\[\]]/g;
|
||||||
|
const underscoresRe = /_+/g;
|
||||||
|
/**
|
||||||
|
* Prettify base names so they're easier to read:
|
||||||
|
* - index -> index
|
||||||
|
* - [slug] -> _slug_
|
||||||
|
* - [...spread] -> _spread_
|
||||||
|
*/
|
||||||
|
function prettifyBaseName(str: string) {
|
||||||
|
return str.replace(charsToReplaceRe, '_').replace(underscoresRe, '_');
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import * as crypto from 'node:crypto';
|
|
||||||
import * as npath from 'node:path';
|
|
||||||
import type { GetModuleInfo } from 'rollup';
|
import type { GetModuleInfo } from 'rollup';
|
||||||
import { type ResolvedConfig, type Plugin as VitePlugin } from 'vite';
|
import { type ResolvedConfig, type Plugin as VitePlugin } from 'vite';
|
||||||
import { isBuildableCSSRequest } from '../../../vite-plugin-astro-server/util.js';
|
import { isBuildableCSSRequest } from '../../../vite-plugin-astro-server/util.js';
|
||||||
|
@ -93,7 +91,7 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
|
||||||
if (new URL(pageInfo.id, 'file://').searchParams.has(PROPAGATED_ASSET_FLAG)) {
|
if (new URL(pageInfo.id, 'file://').searchParams.has(PROPAGATED_ASSET_FLAG)) {
|
||||||
// Split delayed assets to separate modules
|
// Split delayed assets to separate modules
|
||||||
// so they can be injected where needed
|
// so they can be injected where needed
|
||||||
const chunkId = createNameHash(id, [id]);
|
const chunkId = assetName.createNameHash(id, [id]);
|
||||||
internals.cssModuleToChunkIdMap.set(id, chunkId);
|
internals.cssModuleToChunkIdMap.set(id, chunkId);
|
||||||
return chunkId;
|
return chunkId;
|
||||||
}
|
}
|
||||||
|
@ -272,17 +270,6 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
|
||||||
|
|
||||||
/***** UTILITY FUNCTIONS *****/
|
/***** UTILITY FUNCTIONS *****/
|
||||||
|
|
||||||
function createNameHash(baseId: string, hashIds: string[]): string {
|
|
||||||
const baseName = baseId ? npath.parse(baseId).name : 'index';
|
|
||||||
const hash = crypto.createHash('sha256');
|
|
||||||
for (const id of hashIds) {
|
|
||||||
hash.update(id, 'utf-8');
|
|
||||||
}
|
|
||||||
const h = hash.digest('hex').slice(0, 8);
|
|
||||||
const proposedName = baseName + '.' + h;
|
|
||||||
return proposedName;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* getParentClientOnlys(
|
function* getParentClientOnlys(
|
||||||
id: string,
|
id: string,
|
||||||
ctx: { getModuleInfo: GetModuleInfo },
|
ctx: { getModuleInfo: GetModuleInfo },
|
||||||
|
|
Loading…
Reference in a new issue