Separate runtime manifest inputs from directly served files

This commit is contained in:
Jonathan Sykes
2026-10-09 14:40:46 +08:00
parent 0b8e398469
commit dd09f66578
5 changed files with 88 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
import { test, expect } from 'bun:test';
import { mkdtempSync, writeFileSync, rmSync } from 'node:fs';
import { mkdtempSync, writeFileSync, rmSync, mkdirSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { createHash } from 'node:crypto';
@@ -88,3 +88,32 @@ test('index embeds build-local group hashes without recursively embedding index/
const legacy=JSON.parse(off.index.match(/id="ytp-assets">([^<]+)<\/script>/)[1]);
expect(legacy.files['/app.js'].h).toBe(off.manifest.buildTag);
}));
test('non-runtime files stay deliverable but never affect manifest or build identity in either mode', () => fixture(dir => {
for (const hashing of [true, false]) {
const first = createAssetManifest(dir, { hashing });
mkdirSync(join(dir, 'perf'), { recursive: true });
for (const name of ['app.test.js', 'app.test.mjs', 'README.md', 'license.txt', 'admin.html', 'perf/fixture.js']) {
writeFileSync(join(dir, name), 'non-runtime');
const next = createAssetManifest(dir, { hashing });
expect(next.manifest.buildTag).toBe(first.manifest.buildTag);
expect(next.manifest.files['/' + name]).toBeUndefined();
expect(next.deliveryFiles['/' + name].h).toBe(hash('non-runtime'));
expect(next.bytes.get('/' + name).toString()).toBe('non-runtime');
writeFileSync(join(dir, name), 'edited non-runtime');
expect(createAssetManifest(dir, { hashing }).manifest.buildTag).toBe(first.manifest.buildTag);
}
writeFileSync(join(dir, 'app.js'), 'changed runtime ' + hashing);
expect(createAssetManifest(dir, { hashing }).manifest.buildTag).not.toBe(first.manifest.buildTag);
}
}));
test('explicit runtime includes override exclusions and excluded group members fail visibly', () => fixture(dir => {
writeFileSync(join(dir, 'runtime.txt'), 'required at runtime');
const groups = { core: { contract: 1, eager: true, files: ['/index.html', '/app.js', '/runtime.txt'] } };
writeFileSync(join(dir, 'assets.json'), JSON.stringify({ groups }));
expect(() => createAssetManifest(dir)).toThrow('excluded');
writeFileSync(join(dir, 'assets.json'), JSON.stringify({ groups, include: ['/runtime.txt'] }));
expect(createAssetManifest(dir).manifest.files['/runtime.txt'].h).toBe(hash('required at runtime'));
}));