Hash styles by filename rather than contents
#16636Svelte adds svelte-xyz123
hashes to CSS rules and the corresponding elements, so that styles don't affect other components. This hash is based on the contents of the <style>
block.
This works but it means that the hashes change frequently between deployments. It might be better to default to hashing based on the filename instead. I think the reason we didn't originally do this was that not all project setups made the filename available to the compiler, but now that most people are using vite-plugin-svelte
that's probably not an issue any more.
Update this...
...to this:
cssHash: fun(({ css, filename, hash }) => {
return `svelte-${hash(filename ?? css)}`;
}),
nice to have
vite-plugin-svelte does this by default during development to avoid css changes also changing js leading to more hmr updates
a few things to keep in mind:
changing the default affects every js module in the app that contains a csshash, leading to a lot of changed chunks just from updating. not breaking but still noteworthy
using the filename should ensure that it is not an absolute path, otherwise builds are not reproducible unless executed in the exact same root dir
the hash algorithm should be evenly distributed to avoid collisions even when the input isn't ( file paths are very similar )
Hi @Rich-Harris ,
looking at this for the cssHash function and had few questions after reviewing the docs and the proposed type defs.
Conflicts with live document vs current Code
saw that document has already been updated with the new cssHash API https://svelte.dev/docs/svelte/svelte-compiler
, which includes a name parameter. However, since the that supportng code isn't yet in the main branch, this creates a temporary confusions for users. should we edit the document first until this feat is merged to avoid confusion?
Proposal seems this is your propsed solution
cssHash: fun(({ css, filename, hash }) => {
return svelte-${hash(filename ?? css)}
;
}),
but the code CssHashGetter in main branch says export type CssHashGetter = (args: { name: string; // <-- What's the intent here? filename: string; css: string; hash: (input: string) => string; }) => string;
am just trying to understand the intended use case for name. wass the idea to provide the components name to make the hash more semantic
my initial thought for an implementation was similar to your example but potentially adding name
js
cssHash: ({ name, filename, css, hash }) => {
return svelte-${name}-${hash(filename ?? css)}
;
})
whats your thought on this ? Just trying to make myself clear before jumping onto this task