Skip to content

Commit 2925a00

Browse files
Rich Harriskaisermann
Rich Harris
andauthored
add cssHash option (#6026)
* Allow to customize the css scope class * Pass component name to scope class generator * Move Stylesheet arguments into an object * Refactor to cssHash * Please the almighty linter * pass hash function to cssHash * update test * document cssHash option Co-authored-by: Christian Kaisermann <[email protected]>
1 parent 5c8807e commit 2925a00

File tree

8 files changed

+64
-9
lines changed

8 files changed

+64
-9
lines changed

site/content/docs/04-compile-time.md

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ The following options can be passed to the compiler. None are required:
7474
| `customElement` | `false` | If `true`, tells the compiler to generate a custom element constructor instead of a regular Svelte component.
7575
| `tag` | `null` | A `string` that tells Svelte what tag name to register the custom element with. It must be a lowercase alphanumeric string with at least one hyphen, e.g. `"my-element"`.
7676
| `css` | `true` | If `true`, styles will be included in the JavaScript class and injected at runtime. It's recommended that you set this to `false` and use the CSS that is statically generated, as it will result in smaller JavaScript bundles and better performance.
77+
| `cssHash` | See right | 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)}`
7778
| `loopGuardTimeout` | 0 | A `number` that tells Svelte to break the loop if it blocks the thread for more than `loopGuardTimeout` ms. This is useful to prevent infinite loops. **Only available when `dev: true`**
7879
| `preserveComments` | `false` | If `true`, your HTML comments will be preserved during server-side rendering. By default, they are stripped out.
7980
| `preserveWhitespace` | `false` | If `true`, whitespace inside and between elements is kept as you typed it, rather than removed or collapsed to a single space where possible.

src/compiler/compile/Component.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,14 @@ export default class Component {
133133
this.locate = getLocator(this.source, { offsetLine: 1 });
134134

135135
// styles
136-
this.stylesheet = new Stylesheet(
136+
this.stylesheet = new Stylesheet({
137137
source,
138138
ast,
139-
compile_options.filename,
140-
compile_options.dev
141-
);
139+
filename: compile_options.filename,
140+
component_name: name,
141+
dev: compile_options.dev,
142+
get_css_hash: compile_options.cssHash
143+
});
142144
this.stylesheet.validate(this);
143145

144146
this.component_options = process_component_options(

src/compiler/compile/css/Stylesheet.ts

+26-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import MagicString from 'magic-string';
22
import { walk } from 'estree-walker';
33
import Selector from './Selector';
44
import Element from '../nodes/Element';
5-
import { Ast } from '../../interfaces';
5+
import { Ast, CssHashGetter } from '../../interfaces';
66
import Component from '../Component';
77
import { CssNode } from './interfaces';
88
import hash from '../utils/hash';
@@ -275,6 +275,10 @@ class Atrule {
275275
}
276276
}
277277

278+
const get_default_css_hash: CssHashGetter = ({ css, hash }) => {
279+
return `svelte-${hash(css)}`;
280+
};
281+
278282
export default class Stylesheet {
279283
source: string;
280284
ast: Ast;
@@ -289,14 +293,33 @@ export default class Stylesheet {
289293

290294
nodes_with_css_class: Set<CssNode> = new Set();
291295

292-
constructor(source: string, ast: Ast, filename: string, dev: boolean) {
296+
constructor({
297+
source,
298+
ast,
299+
component_name,
300+
filename,
301+
dev,
302+
get_css_hash = get_default_css_hash
303+
}: {
304+
source: string;
305+
ast: Ast;
306+
filename: string | undefined;
307+
component_name: string | undefined;
308+
dev: boolean;
309+
get_css_hash: CssHashGetter;
310+
}) {
293311
this.source = source;
294312
this.ast = ast;
295313
this.filename = filename;
296314
this.dev = dev;
297315

298316
if (ast.css && ast.css.children.length) {
299-
this.id = `svelte-${hash(ast.css.content.styles)}`;
317+
this.id = get_css_hash({
318+
filename,
319+
name: component_name,
320+
css: ast.css.content.styles,
321+
hash
322+
});
300323

301324
this.has_styles = true;
302325

src/compiler/compile/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ const valid_options = [
2828
'css',
2929
'loopGuardTimeout',
3030
'preserveComments',
31-
'preserveWhitespace'
31+
'preserveWhitespace',
32+
'cssHash'
3233
];
3334

3435
function validate_options(options: CompileOptions, warnings: Warning[]) {

src/compiler/interfaces.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ export interface Warning {
104104

105105
export type ModuleFormat = 'esm' | 'cjs';
106106

107+
export type CssHashGetter = (args: {
108+
name: string;
109+
filename: string | undefined;
110+
css: string;
111+
hash: (input: string) => string;
112+
}) => string;
113+
107114
export interface CompileOptions {
108115
format?: ModuleFormat;
109116
name?: string;
@@ -125,6 +132,7 @@ export interface CompileOptions {
125132
css?: boolean;
126133
loopGuardTimeout?: number;
127134
namespace?: string;
135+
cssHash?: CssHashGetter;
128136

129137
preserveComments?: boolean;
130138
preserveWhitespace?: boolean;
@@ -166,7 +174,7 @@ export interface Var {
166174
imported?: boolean;
167175
}
168176

169-
export interface CssResult {
177+
export interface CssResult {
170178
code: string;
171179
map: SourceMap;
172180
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export default {
2+
compileOptions: {
3+
filename: 'src/components/FooSwitcher.svelte',
4+
cssHash({ hash, css, name, filename }) {
5+
const minFilename = filename
6+
.split('/')
7+
.map(i => i.charAt(0).toLowerCase())
8+
.join('');
9+
return `sv-${name}-${minFilename}-${hash(css)}`;
10+
}
11+
}
12+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
div.sv-FooSwitcher-scf-bzh57p{color:red}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<div>red</div>
2+
3+
<style>
4+
div {
5+
color: red;
6+
}
7+
</style>

0 commit comments

Comments
 (0)