Skip to content

Commit

Permalink
Make CSS chunk names less confusing (#8754)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy authored Oct 9, 2023
1 parent eaed844 commit 93b0922
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/sharp-insects-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Make CSS chunk names less confusing
54 changes: 46 additions & 8 deletions packages/astro/src/core/build/css-asset-name.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import type { GetModuleInfo } from 'rollup';
import type { GetModuleInfo, ModuleInfo } from 'rollup';

import crypto from 'node:crypto';
import npath from 'node:path';
import type { AstroSettings } from '../../@types/astro.js';
import { viteID } from '../util.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
// We could get rid of this and only use the createSlugger implementation, but this creates
// slightly prettier names.
export function shortHashedName(id: string, ctx: { getModuleInfo: GetModuleInfo }): string {
const parents = Array.from(getTopLevelPages(id, ctx));
const firstParentId = parents[0]?.[0].id;
const firstParentName = firstParentId ? npath.parse(firstParentId).name : 'index';
return createNameHash(
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');
for (const [page] of parents) {
hash.update(page.id, 'utf-8');
for (const id of hashIds) {
hash.update(id, 'utf-8');
}
const h = hash.digest('hex').slice(0, 8);
const proposedName = firstParentName + '.' + h;
const proposedName = baseName + '.' + h;
return proposedName;
}

Expand All @@ -34,7 +43,7 @@ export function createSlugger(settings: AstroSettings) {
.map(([page]) => page.id)
.sort()
.join('-');
const firstParentId = parents[0]?.[0].id || indexPage;
const firstParentId = getFirstParentId(parents) || indexPage;

// Use the last two segments, for ex /docs/index
let dir = firstParentId;
Expand All @@ -45,7 +54,7 @@ export function createSlugger(settings: AstroSettings) {
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;
dir = npath.dirname(dir);
i++;
Expand Down Expand Up @@ -76,3 +85,32 @@ export function createSlugger(settings: AstroSettings) {
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, '_');
}
15 changes: 1 addition & 14 deletions packages/astro/src/core/build/plugins/plugin-css.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import * as crypto from 'node:crypto';
import * as npath from 'node:path';
import type { GetModuleInfo } from 'rollup';
import { type ResolvedConfig, type Plugin as VitePlugin } from 'vite';
import { isBuildableCSSRequest } from '../../../vite-plugin-astro-server/util.js';
Expand Down Expand Up @@ -93,7 +91,7 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
if (new URL(pageInfo.id, 'file://').searchParams.has(PROPAGATED_ASSET_FLAG)) {
// Split delayed assets to separate modules
// so they can be injected where needed
const chunkId = createNameHash(id, [id]);
const chunkId = assetName.createNameHash(id, [id]);
internals.cssModuleToChunkIdMap.set(id, chunkId);
return chunkId;
}
Expand Down Expand Up @@ -272,17 +270,6 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {

/***** 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(
id: string,
ctx: { getModuleInfo: GetModuleInfo },
Expand Down

0 comments on commit 93b0922

Please sign in to comment.