diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 8aab2b4898dd..bf22e0e6b0ae 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -133,12 +133,14 @@ export default class Component { this.locate = getLocator(this.source, { offsetLine: 1 }); // styles - this.stylesheet = new Stylesheet( + this.stylesheet = new Stylesheet({ source, ast, - compile_options.filename, - compile_options.dev - ); + filename: compile_options.filename, + component_name: name, + dev: compile_options.dev, + get_css_hash: compile_options.cssHash + }); this.stylesheet.validate(this); this.component_options = process_component_options( diff --git a/src/compiler/compile/css/Stylesheet.ts b/src/compiler/compile/css/Stylesheet.ts index b730079a8998..312890ad0fc5 100644 --- a/src/compiler/compile/css/Stylesheet.ts +++ b/src/compiler/compile/css/Stylesheet.ts @@ -2,7 +2,7 @@ import MagicString from 'magic-string'; import { walk } from 'estree-walker'; import Selector from './Selector'; import Element from '../nodes/Element'; -import { Ast } from '../../interfaces'; +import { Ast, CssHashGetter } from '../../interfaces'; import Component from '../Component'; import { CssNode } from './interfaces'; import hash from '../utils/hash'; @@ -275,6 +275,10 @@ class Atrule { } } +const get_default_css_hash: CssHashGetter = ({ hash }) => { + return `svelte-${hash}`; +}; + export default class Stylesheet { source: string; ast: Ast; @@ -289,14 +293,32 @@ export default class Stylesheet { nodes_with_css_class: Set = new Set(); - constructor(source: string, ast: Ast, filename: string, dev: boolean) { + constructor({ + source, + ast, + component_name, + filename, + dev, + get_css_hash = get_default_css_hash + }: { + source: string; + ast: Ast; + filename: string | undefined; + component_name: string | undefined; + dev: boolean; + get_css_hash: CssHashGetter; + }) { this.source = source; this.ast = ast; this.filename = filename; this.dev = dev; if (ast.css && ast.css.children.length) { - this.id = `svelte-${hash(ast.css.content.styles)}`; + this.id = get_css_hash({ + filename, + name: component_name, + hash: hash(ast.css.content.styles) + }); this.has_styles = true; diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index 9f9b31917e38..c9b594dbe3dc 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -28,7 +28,8 @@ const valid_options = [ 'css', 'loopGuardTimeout', 'preserveComments', - 'preserveWhitespace' + 'preserveWhitespace', + 'cssHash' ]; function validate_options(options: CompileOptions, warnings: Warning[]) { diff --git a/src/compiler/interfaces.ts b/src/compiler/interfaces.ts index b9c95ae06db4..c86aed0e061c 100644 --- a/src/compiler/interfaces.ts +++ b/src/compiler/interfaces.ts @@ -104,6 +104,12 @@ export interface Warning { export type ModuleFormat = 'esm' | 'cjs'; +export type CssHashGetter = (args: { + name: string; + filename: string | undefined; + hash: string; +}) => string; + export interface CompileOptions { format?: ModuleFormat; name?: string; @@ -125,6 +131,7 @@ export interface CompileOptions { css?: boolean; loopGuardTimeout?: number; namespace?: string; + cssHash?: CssHashGetter; preserveComments?: boolean; preserveWhitespace?: boolean; @@ -166,7 +173,7 @@ export interface Var { imported?: boolean; } -export interface CssResult { +export interface CssResult { code: string; map: SourceMap; } diff --git a/test/css/samples/custom-css-hash/_config.js b/test/css/samples/custom-css-hash/_config.js new file mode 100644 index 000000000000..0739cc9d8bde --- /dev/null +++ b/test/css/samples/custom-css-hash/_config.js @@ -0,0 +1,12 @@ +export default { + compileOptions: { + filename: 'src/components/FooSwitcher.svelte', + cssHash({ hash, name, filename }) { + const minFilename = filename + .split('/') + .map(i => i.charAt(0).toLowerCase()) + .join(''); + return `sv-${name}-${minFilename}-${hash}`; + } + } +}; diff --git a/test/css/samples/custom-css-hash/expected.css b/test/css/samples/custom-css-hash/expected.css new file mode 100644 index 000000000000..fe710597ea2f --- /dev/null +++ b/test/css/samples/custom-css-hash/expected.css @@ -0,0 +1 @@ +div.sv-FooSwitcher-scf-bzh57p{color:red} \ No newline at end of file diff --git a/test/css/samples/custom-css-hash/input.svelte b/test/css/samples/custom-css-hash/input.svelte new file mode 100644 index 000000000000..bfe5a232140e --- /dev/null +++ b/test/css/samples/custom-css-hash/input.svelte @@ -0,0 +1,7 @@ +
red
+ +