diff --git a/.changeset/fast-boxes-sort.md b/.changeset/fast-boxes-sort.md new file mode 100644 index 0000000000..1edabf0582 --- /dev/null +++ b/.changeset/fast-boxes-sort.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +chore: generate CSS hash using the filename diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index 92b89c588e..de27c4623b 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -456,10 +456,19 @@ export function analyze_component(root, source, options) { const is_custom_element = !!options.customElementOptions || options.customElement; + const name = module.scope.generate(options.name ?? component_name); + + state.adjust({ + component_name: name, + dev: options.dev, + rootDir: options.rootDir, + runes + }); + // TODO remove all the ?? stuff, we don't need it now that we're validating the config /** @type {ComponentAnalysis} */ const analysis = { - name: module.scope.generate(options.name ?? component_name), + name, root: scope_root, module, instance, @@ -520,7 +529,7 @@ export function analyze_component(root, source, options) { hash: root.css ? options.cssHash({ css: root.css.content.styles, - filename: options.filename, + filename: state.filename, name: component_name, hash }) @@ -534,13 +543,6 @@ export function analyze_component(root, source, options) { async_deriveds: new Set() }; - state.adjust({ - component_name: analysis.name, - dev: options.dev, - rootDir: options.rootDir, - runes - }); - if (!runes) { // every exported `let` or `var` declaration becomes a prop, everything else becomes an export for (const node of instance.ast.body) { diff --git a/packages/svelte/src/compiler/types/index.d.ts b/packages/svelte/src/compiler/types/index.d.ts index 6211e69bd3..e13c9a9e22 100644 --- a/packages/svelte/src/compiler/types/index.d.ts +++ b/packages/svelte/src/compiler/types/index.d.ts @@ -105,7 +105,7 @@ export interface CompileOptions extends ModuleCompileOptions { css?: 'injected' | 'external'; /** * A function that takes a `{ hash, css, name, filename }` argument and returns the string that is used as a classname for scoped CSS. - * It defaults to returning `svelte-${hash(css)}`. + * It defaults to returning `svelte-${hash(filename ?? css)}`. * * @default undefined */ diff --git a/packages/svelte/src/compiler/validate-options.js b/packages/svelte/src/compiler/validate-options.js index 2b727ad093..a94a553311 100644 --- a/packages/svelte/src/compiler/validate-options.js +++ b/packages/svelte/src/compiler/validate-options.js @@ -70,8 +70,8 @@ const component_options = { return input; }), - cssHash: fun(({ css, hash }) => { - return `svelte-${hash(css)}`; + cssHash: fun(({ css, filename, hash }) => { + return `svelte-${hash(filename === '(unknown)' ? css : filename ?? css)}`; }), // TODO this is a sourcemap option, would be good to put under a sourcemap namespace diff --git a/packages/svelte/tests/html_equal.js b/packages/svelte/tests/html_equal.js index b637e4d538..76a4a957a5 100644 --- a/packages/svelte/tests/html_equal.js +++ b/packages/svelte/tests/html_equal.js @@ -32,7 +32,13 @@ function clean_children(node, opts) { return; } - node.setAttribute(attr.name, attr.value); + let value = attr.value; + + if (attr.name === 'class') { + value = value.replace(/svelte-\w+/, 'svelte-xyz123'); + } + + node.setAttribute(attr.name, value); }); for (let child of [...node.childNodes]) { diff --git a/packages/svelte/tests/runtime-browser/assert.js b/packages/svelte/tests/runtime-browser/assert.js index 9a294a48c7..e331c8b677 100644 --- a/packages/svelte/tests/runtime-browser/assert.js +++ b/packages/svelte/tests/runtime-browser/assert.js @@ -74,6 +74,7 @@ function normalize_html(window, html) { node.innerHTML = html .replace(//g, '') .replace(/>[\s\r\n]+<') + .replace(/svelte-\w+/g, 'svelte-xyz123') .trim(); normalize_children(node); diff --git a/packages/svelte/tests/runtime-legacy/samples/attribute-null-classname-with-style/_config.js b/packages/svelte/tests/runtime-legacy/samples/attribute-null-classname-with-style/_config.js index cbd0456e13..1fc15c7eda 100644 --- a/packages/svelte/tests/runtime-legacy/samples/attribute-null-classname-with-style/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/attribute-null-classname-with-style/_config.js @@ -1,43 +1,43 @@ import { ok, test } from '../../test'; export default test({ - html: '
', + html: '', test({ assert, component, target }) { const div = target.querySelector('div'); ok(div); component.testName = null; - assert.equal(div.className, 'svelte-x1o6ra'); + assert.equal(div.className, 'svelte-70s021'); component.testName = undefined; - assert.equal(div.className, 'svelte-x1o6ra'); + assert.equal(div.className, 'svelte-70s021'); component.testName = undefined + ''; - assert.equal(div.className, 'undefined svelte-x1o6ra'); + assert.equal(div.className, 'undefined svelte-70s021'); component.testName = null + ''; - assert.equal(div.className, 'null svelte-x1o6ra'); + assert.equal(div.className, 'null svelte-70s021'); component.testName = 1; - assert.equal(div.className, '1 svelte-x1o6ra'); + assert.equal(div.className, '1 svelte-70s021'); component.testName = 0; - assert.equal(div.className, '0 svelte-x1o6ra'); + assert.equal(div.className, '0 svelte-70s021'); component.testName = false; - assert.equal(div.className, 'false svelte-x1o6ra'); + assert.equal(div.className, 'false svelte-70s021'); component.testName = true; - assert.equal(div.className, 'true svelte-x1o6ra'); + assert.equal(div.className, 'true svelte-70s021'); component.testName = {}; - assert.equal(div.className, 'svelte-x1o6ra'); + assert.equal(div.className, 'svelte-70s021'); component.testName = ''; - assert.equal(div.className, 'svelte-x1o6ra'); + assert.equal(div.className, 'svelte-70s021'); component.testName = 'testClassName'; - assert.equal(div.className, 'testClassName svelte-x1o6ra'); + assert.equal(div.className, 'testClassName svelte-70s021'); } }); diff --git a/packages/svelte/tests/runtime-legacy/samples/attribute-null-classnames-with-style/_config.js b/packages/svelte/tests/runtime-legacy/samples/attribute-null-classnames-with-style/_config.js index d2511a4403..2f4b6242cb 100644 --- a/packages/svelte/tests/runtime-legacy/samples/attribute-null-classnames-with-style/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/attribute-null-classnames-with-style/_config.js @@ -10,43 +10,43 @@ export default test({ }; }, - html: '', + html: '', test({ assert, component, target }) { const div = target.querySelector('div'); ok(div); - assert.equal(div.className, 'test1test2 svelte-x1o6ra'); + assert.equal(div.className, 'test1test2 svelte-70s021'); component.testName1 = null; component.testName2 = null; - assert.equal(div.className, '0 svelte-x1o6ra'); + assert.equal(div.className, '0 svelte-70s021'); component.testName1 = null; component.testName2 = 'test'; - assert.equal(div.className, 'nulltest svelte-x1o6ra'); + assert.equal(div.className, 'nulltest svelte-70s021'); component.testName1 = undefined; component.testName2 = 'test'; - assert.equal(div.className, 'undefinedtest svelte-x1o6ra'); + assert.equal(div.className, 'undefinedtest svelte-70s021'); component.testName1 = undefined; component.testName2 = undefined; - assert.equal(div.className, 'NaN svelte-x1o6ra'); + assert.equal(div.className, 'NaN svelte-70s021'); component.testName1 = null; component.testName2 = 1; - assert.equal(div.className, '1 svelte-x1o6ra'); + assert.equal(div.className, '1 svelte-70s021'); component.testName1 = undefined; component.testName2 = 1; - assert.equal(div.className, 'NaN svelte-x1o6ra'); + assert.equal(div.className, 'NaN svelte-70s021'); component.testName1 = null; component.testName2 = 0; - assert.equal(div.className, '0 svelte-x1o6ra'); + assert.equal(div.className, '0 svelte-70s021'); component.testName1 = undefined; component.testName2 = 0; - assert.equal(div.className, 'NaN svelte-x1o6ra'); + assert.equal(div.className, 'NaN svelte-70s021'); } }); diff --git a/packages/svelte/tests/runtime-legacy/samples/attribute-null-func-classname-with-style/_config.js b/packages/svelte/tests/runtime-legacy/samples/attribute-null-func-classname-with-style/_config.js index 081fceecf2..b06103992f 100644 --- a/packages/svelte/tests/runtime-legacy/samples/attribute-null-func-classname-with-style/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/attribute-null-func-classname-with-style/_config.js @@ -8,41 +8,41 @@ export default test({ }; }, - html: '', + html: '', test({ assert, component, target }) { const div = target.querySelector('div'); ok(div); - assert.equal(div.className, 'testClassName svelte-x1o6ra'); + assert.equal(div.className, 'testClassName svelte-70s021'); component.testName = null; - assert.equal(div.className, 'svelte-x1o6ra'); + assert.equal(div.className, 'svelte-70s021'); component.testName = undefined; - assert.equal(div.className, 'svelte-x1o6ra'); + assert.equal(div.className, 'svelte-70s021'); component.testName = undefined + ''; - assert.equal(div.className, 'undefined svelte-x1o6ra'); + assert.equal(div.className, 'undefined svelte-70s021'); component.testName = null + ''; - assert.equal(div.className, 'null svelte-x1o6ra'); + assert.equal(div.className, 'null svelte-70s021'); component.testName = 1; - assert.equal(div.className, '1 svelte-x1o6ra'); + assert.equal(div.className, '1 svelte-70s021'); component.testName = 0; - assert.equal(div.className, '0 svelte-x1o6ra'); + assert.equal(div.className, '0 svelte-70s021'); component.testName = false; - assert.equal(div.className, 'false svelte-x1o6ra'); + assert.equal(div.className, 'false svelte-70s021'); component.testName = true; - assert.equal(div.className, 'true svelte-x1o6ra'); + assert.equal(div.className, 'true svelte-70s021'); component.testName = {}; - assert.equal(div.className, 'svelte-x1o6ra'); + assert.equal(div.className, 'svelte-70s021'); component.testName = ''; - assert.equal(div.className, 'svelte-x1o6ra'); + assert.equal(div.className, 'svelte-70s021'); } }); diff --git a/packages/svelte/tests/runtime-legacy/samples/attribute-null-func-classnames-with-style/_config.js b/packages/svelte/tests/runtime-legacy/samples/attribute-null-func-classnames-with-style/_config.js index d55a0079c0..7fc3dd85f4 100644 --- a/packages/svelte/tests/runtime-legacy/samples/attribute-null-func-classnames-with-style/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/attribute-null-func-classnames-with-style/_config.js @@ -10,43 +10,43 @@ export default test({ }; }, - html: '', + html: '', async test({ assert, component, target }) { const div = target.querySelector('div'); ok(div); - assert.equal(div.className, 'test1test2 svelte-x1o6ra'); + assert.equal(div.className, 'test1test2 svelte-70s021'); component.testName1 = null; component.testName2 = null; - assert.equal(div.className, '0 svelte-x1o6ra'); + assert.equal(div.className, '0 svelte-70s021'); component.testName1 = null; component.testName2 = 'test'; - assert.equal(div.className, 'nulltest svelte-x1o6ra'); + assert.equal(div.className, 'nulltest svelte-70s021'); component.testName1 = undefined; component.testName2 = 'test'; - assert.equal(div.className, 'undefinedtest svelte-x1o6ra'); + assert.equal(div.className, 'undefinedtest svelte-70s021'); component.testName1 = undefined; component.testName2 = undefined; - assert.equal(div.className, 'NaN svelte-x1o6ra'); + assert.equal(div.className, 'NaN svelte-70s021'); component.testName1 = null; component.testName2 = 1; - assert.equal(div.className, '1 svelte-x1o6ra'); + assert.equal(div.className, '1 svelte-70s021'); component.testName1 = undefined; component.testName2 = 1; - assert.equal(div.className, 'NaN svelte-x1o6ra'); + assert.equal(div.className, 'NaN svelte-70s021'); component.testName1 = null; component.testName2 = 0; - assert.equal(div.className, '0 svelte-x1o6ra'); + assert.equal(div.className, '0 svelte-70s021'); component.testName1 = undefined; component.testName2 = 0; - assert.equal(div.className, 'NaN svelte-x1o6ra'); + assert.equal(div.className, 'NaN svelte-70s021'); } }); diff --git a/packages/svelte/tests/runtime-runes/samples/custom-element-svelte-class/_config.js b/packages/svelte/tests/runtime-runes/samples/custom-element-svelte-class/_config.js index 0069a7dfd7..930de12585 100644 --- a/packages/svelte/tests/runtime-runes/samples/custom-element-svelte-class/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/custom-element-svelte-class/_config.js @@ -3,7 +3,7 @@ import { test } from '../../test'; export default test({ async test({ assert, target, logs }) { const [my_element, my_element_1] = target.querySelectorAll('my-element'); - assert.equal(my_element.classList.contains('svelte-1koh33s'), true); - assert.equal(my_element_1.classList.contains('svelte-1koh33s'), true); + assert.equal(my_element.classList.contains('svelte-70s021'), true); + assert.equal(my_element_1.classList.contains('svelte-70s021'), true); } }); diff --git a/packages/svelte/tests/runtime-runes/samples/svelte-element-custom-element-css-hash/_config.js b/packages/svelte/tests/runtime-runes/samples/svelte-element-custom-element-css-hash/_config.js index eae8101e6e..cb532b28b5 100644 --- a/packages/svelte/tests/runtime-runes/samples/svelte-element-custom-element-css-hash/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/svelte-element-custom-element-css-hash/_config.js @@ -1,14 +1,14 @@ import { ok, test } from '../../test'; export default test({ - html: `