Skip to content

Commit e3b370e

Browse files
lukeedbenmccann
andauthored
break: remove css option (#147)
* break: remove `css` option * windows * Do not inline sourcemap * Default emitCss to true * chore: purge unused test files * chore: add quotes in test name * fix: define `emitCss` default on assignment Co-authored-by: Ben McCann <[email protected]>
1 parent 2a41681 commit e3b370e

File tree

15 files changed

+56
-574
lines changed

15 files changed

+56
-574
lines changed

README.md

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,13 @@ export default {
4949
}
5050
},
5151

52-
// Emit CSS as "files" for other plugins to process
53-
emitCss: true,
52+
// Emit CSS as "files" for other plugins to process. default is true
53+
emitCss: false,
5454

5555
// You can optionally set 'customElement' to 'true' to compile
5656
// your components to custom elements (aka web elements)
5757
customElement: false,
5858

59-
// Extract CSS into a single bundled file (recommended).
60-
// See note below
61-
css: function (css) {
62-
console.log(css.code); // the concatenated CSS
63-
console.log(css.map); // a sourcemap
64-
65-
// creates `main.css` and `main.css.map`
66-
// using a falsy name will default to the bundle name
67-
// — pass `false` as the second argument if you don't want the sourcemap
68-
css.write('main.css');
69-
},
70-
7159
// Warnings are normally passed straight to Rollup. You can
7260
// optionally handle them here, for example to squelch
7361
// warnings with a particular code
@@ -118,14 +106,9 @@ and so on. Then, in `package.json`, set the `svelte` property to point to this `
118106

119107
## Extracting CSS
120108

121-
If your Svelte components contain `<style>` tags, by default the compiler will add JavaScript that injects those styles into the page when the component is rendered. That's not ideal, because it adds weight to your JavaScript, prevents styles from being fetched in parallel with your code, and can even cause CSP violations.
122-
123-
A better option is to extract the CSS into a separate file. Using the `css` option as shown above would cause a `public/main.css` file to be generated each time the bundle is built (or rebuilt, if you're using rollup-watch), with the normal scoping rules applied.
124-
125-
If you have other plugins processing your CSS (e.g. rollup-plugin-scss), and want your styles passed through to them to be bundled together, you can use `emitCss: true`.
126-
127-
Alternatively, if you're handling styles in some other way and just want to prevent the CSS being added to your JavaScript bundle, use `css: false`.
109+
By default (when `emitCss: true`) the CSS styles will be emitted into a virtual file, allowing another Rollup plugin – for example, [`rollup-plugin-css-only`](https://www.npmjs.com/package/rollup-plugin-css-only), [`rollup-plugin-postcss`](https://www.npmjs.com/package/rollup-plugin-postcss), etc. – to take responsibility for the new stylesheet. In fact, emitting CSS files _requires_ that you use a Rollup plugin to handle the CSS. Otherwise, your build(s) will fail! This is because this plugin will add an `import` statement to import the emitted CSS file. It's not valid JS to import a CSS file into a JS file, but it allows the CSS to be linked to its respective JS file and is a common pattern that other Rollup CSS plugins know how to handle.
128110

111+
If you set `emitCss: false` and your Svelte components contain `<style>` tags, the compiler will add JavaScript that injects those styles into the page when the component is rendered. That's not the default, because it adds weight to your JavaScript, prevents styles from being fetched in parallel with your code, and can even cause CSP violations.
129112

130113
## License
131114

index.d.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,9 @@ interface Options {
4444
// }
4545
// },
4646

47-
/** Emit CSS as "files" for other plugins to process */
47+
/** Emit Svelte styles as virtual CSS files for other plugins to process. */
4848
emitCss: boolean;
4949

50-
/** Extract CSS into a separate file (recommended) */
51-
css: false | CssEmitter;
52-
5350
/** Options passed to `svelte.compile` method. */
5451
compilerOptions: CompileOptions;
5552

index.js

Lines changed: 18 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -2,84 +2,15 @@ const path = require('path');
22
const relative = require('require-relative');
33
const { createFilter } = require('rollup-pluginutils');
44
const { compile, preprocess } = require('svelte/compiler');
5-
const { encode, decode } = require('sourcemap-codec');
65

76
const PREFIX = '[rollup-plugin-svelte]';
87
const pkg_export_errors = new Set();
98

109
const plugin_options = new Set([
1110
'include', 'exclude', 'extensions',
12-
'preprocess', 'onwarn',
13-
'emitCss', 'css',
11+
'preprocess', 'onwarn', 'emitCss',
1412
]);
1513

16-
function to_entry_css(bundle) {
17-
for (let file in bundle) {
18-
let { name } = path.parse(file);
19-
return name + '.css';
20-
}
21-
}
22-
23-
class CssWriter {
24-
constructor(context, bundle, isDev, code, map) {
25-
this.code = code;
26-
this.filename = to_entry_css(bundle);
27-
28-
this.map = map && {
29-
version: 3,
30-
file: null,
31-
sources: map.sources,
32-
sourcesContent: map.sourcesContent,
33-
names: [],
34-
mappings: encode(map.mappings)
35-
};
36-
37-
this.warn = context.warn;
38-
this.emit = (name, source) => context.emitFile({
39-
type: 'asset', name, source
40-
});
41-
42-
this.sourcemap = (file, mapping) => {
43-
const ref = this.emit(file, this.code);
44-
const filename = context.getFileName(ref); // may be "assets/[name][ext]"
45-
46-
const mapfile = `${filename}.map`; // may be "assets/[name][ext]"
47-
const toRelative = src => path.relative(path.dirname(file), src);
48-
49-
if (bundle[filename]) {
50-
// use `basename` because files are siblings
51-
// aka, avoid `sourceMappingURL=assets/bundle.css.map` from `assets/bundle.css`
52-
bundle[filename].source += `\n/*# sourceMappingURL=${path.basename(mapfile)} */`;
53-
} else {
54-
// This should not ever happen, but just in case...
55-
return this.warn(`Missing "${filename}" ("${file}") in bundle; skipping sourcemap!`);
56-
}
57-
58-
const source = JSON.stringify({
59-
...mapping,
60-
file: path.basename(filename), //=> sibling file
61-
sources: mapping.sources.map(toRelative),
62-
}, null, isDev ? 2 : 0);
63-
64-
// use `fileName` to prevent additional Rollup hashing
65-
context.emitFile({ type: 'asset', fileName: mapfile, source });
66-
};
67-
}
68-
69-
write(dest = this.filename, map = !!this.map) {
70-
if (map && this.map) {
71-
this.sourcemap(dest, this.map);
72-
} else {
73-
this.emit(dest, this.code);
74-
}
75-
}
76-
77-
toString() {
78-
this.warn('[DEPRECATION] As of rollup-plugin-svelte@3, the argument to the `css` function is an object, not a string — use `css.write(file)`. Consult the documentation for more information: https://github.com/rollup/rollup-plugin-svelte');
79-
return this.code;
80-
}
81-
}
82-
8314
/**
8415
* @param [options] {Partial<import('.').Options>}
8516
* @returns {import('rollup').Plugin}
@@ -90,34 +21,31 @@ module.exports = function (options = {}) {
9021
const filter = createFilter(rest.include, rest.exclude);
9122

9223
compilerOptions.format = 'esm';
93-
const isDev = !!compilerOptions.dev;
9424

9525
for (let key in rest) {
9626
if (plugin_options.has(key)) continue;
9727
console.warn(`${PREFIX} Unknown "${key}" option. Please use "compilerOptions" for any Svelte compiler configuration.`);
9828
}
9929

100-
const css_cache = new Map(); // [filename]:[chunk]
101-
const { css, emitCss, onwarn } = rest;
30+
// [filename]:[chunk]
31+
const cache_emit = new Map;
32+
const { onwarn, emitCss=true } = rest;
10233

103-
const ctype = typeof css;
104-
const toWrite = ctype === 'function' && css;
105-
if (css != null && !toWrite && ctype !== 'boolean') {
106-
throw new Error('options.css must be a boolean or a function');
34+
if (emitCss) {
35+
if (compilerOptions.css) {
36+
console.warn(`${PREFIX} Forcing \`"compilerOptions.css": false\` because "emitCss" was truthy.`);
37+
}
38+
compilerOptions.css = false;
10739
}
10840

109-
// block svelte's inline CSS if writer
110-
const external_css = !!(toWrite || emitCss);
111-
if (external_css) compilerOptions.css = false;
112-
11341
return {
11442
name: 'svelte',
11543

11644
/**
11745
* Resolve an import's full filepath.
11846
*/
11947
resolveId(importee, importer) {
120-
if (css_cache.has(importee)) return importee;
48+
if (cache_emit.has(importee)) return importee;
12149
if (!importer || importee[0] === '.' || importee[0] === '\0' || path.isAbsolute(importee)) return null;
12250

12351
// if this is a bare import, see if there's a valid pkg.svelte
@@ -152,12 +80,12 @@ module.exports = function (options = {}) {
15280
* Returns CSS contents for a file, if ours
15381
*/
15482
load(id) {
155-
return css_cache.get(id) || null;
83+
return cache_emit.get(id) || null;
15684
},
15785

15886
/**
15987
* Transforms a `.svelte` file into a `.js` file.
160-
* NOTE: If `emitCss: true`, appends a static `import` for virtual CSS file.
88+
* NOTE: If `emitCss`, append static `import` to virtual CSS file.
16189
*/
16290
async transform(code, id) {
16391
if (!filter(id)) return null;
@@ -177,20 +105,15 @@ module.exports = function (options = {}) {
177105
const compiled = compile(code, { ...compilerOptions, filename });
178106

179107
(compiled.warnings || []).forEach(warning => {
180-
if (!css && !emitCss && warning.code === 'css-unused-selector') return;
108+
if (!emitCss && warning.code === 'css-unused-selector') return;
181109
if (onwarn) onwarn(warning, this.warn);
182110
else this.warn(warning);
183111
});
184112

185-
if (external_css && compiled.css.code) {
113+
if (emitCss && compiled.css.code) {
186114
const fname = id.replace(new RegExp(`\\${extension}$`), '.css');
187-
188-
if (emitCss) {
189-
compiled.js.code += `\nimport ${JSON.stringify(fname)};\n`;
190-
compiled.css.code += `\n/*# sourceMappingURL=${compiled.css.map.toUrl()} */`;
191-
}
192-
193-
css_cache.set(fname, compiled.css);
115+
compiled.js.code += `\nimport ${JSON.stringify(fname)};\n`;
116+
cache_emit.set(fname, compiled.css);
194117
}
195118

196119
if (this.addWatchFile) {
@@ -203,49 +126,13 @@ module.exports = function (options = {}) {
203126
},
204127

205128
/**
206-
* Write to CSS file if given `options.css` function.
207-
* TODO: is there a better way to concat/append into Rollup asset?
129+
* All resolutions done; display warnings wrt `package.json` access.
208130
*/
209-
generateBundle(config, bundle) {
131+
generateBundle() {
210132
if (pkg_export_errors.size > 0) {
211133
console.warn(`\n${PREFIX} The following packages did not export their \`package.json\` file so we could not check the "svelte" field. If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.\n`);
212134
console.warn(Array.from(pkg_export_errors, s => `- ${s}`).join('\n') + '\n');
213135
}
214-
215-
if (!toWrite) return;
216-
217-
let result = '';
218-
const sources = [];
219-
const sourcesContent = config.sourcemapExcludeSources ? null : [];
220-
const mappings = [];
221-
222-
[...css_cache.keys()].sort().forEach(file => {
223-
const chunk = css_cache.get(file);
224-
if (!chunk.code) return;
225-
226-
result += chunk.code + '\n';
227-
228-
if (config.sourcemap && chunk.map) {
229-
const len = sources.length;
230-
sources.push(...chunk.map.sources);
231-
if (sourcesContent) sourcesContent.push(...chunk.map.sourcesContent);
232-
233-
const decoded = decode(chunk.map.mappings);
234-
235-
if (len > 0) {
236-
decoded.forEach(line => {
237-
line.forEach(segment => {
238-
segment[1] += len;
239-
});
240-
});
241-
}
242-
243-
mappings.push(...decoded);
244-
}
245-
});
246-
247-
const sourceMap = config.sourcemap && { sources, sourcesContent, mappings };
248-
toWrite(new CssWriter(this, bundle, isDev, result, sourceMap));
249136
}
250137
};
251138
};

package-lock.json

Lines changed: 0 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,14 @@
2626
},
2727
"dependencies": {
2828
"require-relative": "^0.8.7",
29-
"rollup-pluginutils": "^2.8.2",
30-
"sourcemap-codec": "^1.4.8"
29+
"rollup-pluginutils": "^2.8.2"
3130
},
3231
"peerDependencies": {
3332
"svelte": ">=3.5.0",
3433
"rollup": ">=2.0.0"
3534
},
3635
"devDependencies": {
3736
"eslint": "^6.8.0",
38-
"locate-character": "^2.0.5",
3937
"rollup": "^2.30.0",
4038
"sander": "^0.6.0",
4139
"source-map": "^0.7.3",

test/deterministic-css/expected/bundle.css

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/deterministic-css/src/A.svelte

Lines changed: 0 additions & 7 deletions
This file was deleted.

test/deterministic-css/src/App.svelte

Lines changed: 0 additions & 9 deletions
This file was deleted.

test/deterministic-css/src/B.svelte

Lines changed: 0 additions & 7 deletions
This file was deleted.

test/deterministic-css/src/C.svelte

Lines changed: 0 additions & 7 deletions
This file was deleted.

test/deterministic-css/src/main.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/filename-test/expected/bundle.css

Lines changed: 0 additions & 3 deletions
This file was deleted.

test/filename-test/expected/bundle.css.map

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)