Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Commit 14802b0

Browse files
Augmented chunk hashes based on imported css code
1 parent f4cecc4 commit 14802b0

File tree

1 file changed

+54
-5
lines changed

1 file changed

+54
-5
lines changed

src/core/create_compilers/RollupCompiler.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { createHash, Hash } from 'crypto';
12
import * as path from 'path';
23
import color from 'kleur';
34
import relative from 'require-relative';
@@ -9,6 +10,7 @@ import {
910
OutputChunk,
1011
Plugin,
1112
PluginContext,
13+
PreRenderedChunk,
1214
RenderedChunk,
1315
RollupError
1416
} from 'rollup';
@@ -154,11 +156,52 @@ export default class RollupCompiler {
154156

155157
const that = this;
156158

157-
// TODO this is hacky. refactor out into an external rollup plugin
158-
(mod.plugins || (mod.plugins = [])).push(css_chunks({ injectImports: true }));
159-
if (!/[\\/]client\./.test(entry_point)) {
160-
return mod;
161-
}
159+
/**
160+
* Track css code hashes for proper chunk hashing
161+
*/
162+
const css_hashing = () => {
163+
const css_hashes: Record<string, string> = {};
164+
return <Plugin>{
165+
name: 'sapper-css-hashing',
166+
augmentChunkHash(this: PluginContext, chunk: PreRenderedChunk) {
167+
let hash: Hash;
168+
169+
const module_files = Object.keys(chunk.modules).map(module_id => {
170+
/**
171+
* Save `module_file` which represents the id without file extension. This way it's easy to determine
172+
* svelte generated css files as this will be the same for the svelte and corresponding css ids
173+
*/
174+
const modulePath = path.parse(module_id);
175+
return { module_id, module_file: `${modulePath.dir}/${modulePath.name}` };
176+
});
177+
module_files.forEach(({ module_id, module_file }) => {
178+
if (css_hashes[module_id]) {
179+
/**
180+
* Ignore svelte css files created with `emitCss` enabled. These css files are generated out
181+
* of svelte's `<style>` and already part of the code that was used to generate the chunk hash
182+
*/
183+
const is_svelte_css = module_files.some(({ module_id: id, module_file: file }) => id !== module_id && file === module_file);
184+
if (!is_svelte_css) {
185+
if (!hash) {
186+
hash = createHash('sha256');
187+
}
188+
hash.update(css_hashes[module_id]);
189+
}
190+
}
191+
});
192+
if (hash) {
193+
return hash.digest('hex');
194+
}
195+
},
196+
transform(this: PluginContext, code: string, id: string) {
197+
if (path.extname(id) === '.css') {
198+
// save css code based hashes before `rollup-plugin-css-chunks` clears the code
199+
css_hashes[id] = createHash('sha256').update(code).digest('hex');
200+
}
201+
return { code, map: null };
202+
}
203+
};
204+
};
162205

163206
/**
164207
* Finds dynamic imports and rewrites them to import the component and its CSS in parallel
@@ -300,6 +343,12 @@ export default class RollupCompiler {
300343
}
301344
};
302345

346+
// TODO this is hacky. refactor out into an external rollup plugin
347+
(mod.plugins || (mod.plugins = [])).push(css_hashing());
348+
mod.plugins.push(css_chunks({ injectImports: true }));
349+
if (!/[\\/]client\./.test(entry_point)) {
350+
return mod;
351+
}
303352
mod.plugins.push(css_injection);
304353
mod.plugins.push(sapper_internal);
305354

0 commit comments

Comments
 (0)