[feat] Compiler option css: 'none' support (#7914)

pull/8015/head
Maximiliano Ruani 2 years ago committed by GitHub
parent b05b684b95
commit 773dedf714
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -73,7 +73,7 @@ The following options can be passed to the compiler. None are required:
| `accessors` | `false` | If `true`, getters and setters will be created for the component's props. If `false`, they will only be created for readonly exported values (i.e. those declared with `const`, `class` and `function`). If compiling with `customElement: true` this option defaults to `true`.
| `customElement` | `false` | If `true`, tells the compiler to generate a custom element constructor instead of a regular Svelte component.
| `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"`.
| `css` | `true` | If `true`, styles will be included in the JavaScript class and injected at runtime for the components actually rendered. If `false`, the CSS will be returned in the `css` field of the compilation result. Most Svelte bundler plugins will set this to `false` and use the CSS that is statically generated for better performance, as it will result in smaller JavaScript bundles and the output can be served as cacheable `.css` files.
| `css` | `'injected'` | If `'injected'` (formerly `true`), styles will be included in the JavaScript class and injected at runtime for the components actually rendered. If `'external'` (formerly `false`), the CSS will be returned in the `css` field of the compilation result. Most Svelte bundler plugins will set this to `'external'` and use the CSS that is statically generated for better performance, as it will result in smaller JavaScript bundles and the output can be served as cacheable `.css` files. If `'none'`, styles are completely avoided and no CSS output is generated.
| `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)}`
| `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`**
| `preserveComments` | `false` | If `true`, your HTML comments will be preserved during server-side rendering. By default, they are stripped out.

@ -35,11 +35,19 @@ const valid_options = [
'cssHash'
];
const valid_css_values = [
true,
false,
'injected',
'external',
'none'
];
const regex_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
const regex_starts_with_lowercase_character = /^[a-z]/;
function validate_options(options: CompileOptions, warnings: Warning[]) {
const { name, filename, loopGuardTimeout, dev, namespace } = options;
const { name, filename, loopGuardTimeout, dev, namespace, css } = options;
Object.keys(options).forEach(key => {
if (!valid_options.includes(key)) {
@ -75,6 +83,21 @@ function validate_options(options: CompileOptions, warnings: Warning[]) {
});
}
if (valid_css_values.indexOf(css) === -1) {
throw new Error(`options.css must be true, false, 'injected', 'external', or 'none' (got '${css}')`);
}
if (css === true || css === false) {
options.css = css === true ? 'injected' : 'external';
const message = `options.css as a boolean is deprecated. Use '${options.css}' instead of ${css}.`;
warnings.push({
code: 'options-css-boolean-deprecated',
message,
filename,
toString: () => message
});
}
if (namespace && valid_namespaces.indexOf(namespace) === -1) {
const match = fuzzymatch(namespace, valid_namespaces);
if (match) {
@ -86,7 +109,7 @@ function validate_options(options: CompileOptions, warnings: Warning[]) {
}
export default function compile(source: string, options: CompileOptions = {}) {
options = Object.assign({ generate: 'dom', dev: false, enableSourcemap: true }, options);
options = Object.assign({ generate: 'dom', dev: false, enableSourcemap: true, css: 'injected' }, options);
const stats = new Stats();
const warnings = [];

@ -54,7 +54,7 @@ export default function dom(
const should_add_css = (
!options.customElement &&
!!styles &&
options.css !== false
options.css === 'injected'
);
if (should_add_css) {

@ -179,7 +179,7 @@ export interface CompileOptions {
legacy?: boolean;
customElement?: boolean;
tag?: string;
css?: boolean;
css?: 'injected' | 'external' | 'none' | boolean;
loopGuardTimeout?: number;
namespace?: string;
cssHash?: CssHashGetter;
@ -191,6 +191,7 @@ export interface CompileOptions {
export interface ParserOptions {
filename?: string;
customElement?: boolean;
css?: 'injected' | 'external' | 'none' | boolean;
}
export interface Visitor {

@ -21,6 +21,7 @@ export class Parser {
readonly template: string;
readonly filename?: string;
readonly customElement: boolean;
readonly css_mode: 'injected' | 'external' | 'none' | boolean;
index = 0;
stack: TemplateNode[] = [];
@ -39,6 +40,7 @@ export class Parser {
this.template = template.trimRight();
this.filename = options.filename;
this.customElement = options.customElement;
this.css_mode = options.css;
this.html = {
start: null,

@ -19,6 +19,12 @@ export default function read_style(parser: Parser, start: number, attributes: No
const content_end = parser.index;
// discard styles when css is disabled
if (parser.css_mode === 'none') {
parser.read(regex_closing_style_tag);
return null;
}
let ast;
try {
@ -71,6 +77,7 @@ export default function read_style(parser: Parser, start: number, attributes: No
});
parser.read(regex_closing_style_tag);
const end = parser.index;
return {

@ -0,0 +1,7 @@
<div>foo</div>
<style>
div {
color: red;
}
</style>

@ -0,0 +1,32 @@
{
"html": {
"start": 0,
"end": 14,
"type": "Fragment",
"children": [
{
"start": 0,
"end": 14,
"type": "Element",
"name": "div",
"attributes": [],
"children": [
{
"start": 5,
"end": 8,
"type": "Text",
"raw": "foo",
"data": "foo"
}
]
},
{
"start": 14,
"end": 16,
"type": "Text",
"raw": "\n\n",
"data": "\n\n"
}
]
}
}
Loading…
Cancel
Save