Skip to content

Commit 1b541b3

Browse files
committed
Add back in css option
1 parent eadfcaf commit 1b541b3

File tree

1 file changed

+121
-13
lines changed

1 file changed

+121
-13
lines changed

src/index.js

+121-13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import path from 'path';
33
import relative from 'require-relative';
44
import { compile, preprocess } from 'svelte';
55
import { createFilter } from 'rollup-pluginutils';
6+
import { encode, decode } from 'sourcemap-codec';
67

78
function sanitize(input) {
89
return path
@@ -52,6 +53,59 @@ function exists(file) {
5253
}
5354
}
5455

56+
function mkdirp(dir) {
57+
const parent = path.dirname(dir);
58+
if (parent === dir) return;
59+
60+
mkdirp(parent);
61+
62+
try {
63+
fs.mkdirSync(dir);
64+
} catch (err) {
65+
if (err.code !== 'EEXIST') throw err;
66+
}
67+
}
68+
69+
class CssWriter {
70+
constructor (code, map) {
71+
this.code = code;
72+
this.map = {
73+
version: 3,
74+
file: null,
75+
sources: map.sources,
76+
sourcesContent: map.sourcesContent,
77+
names: [],
78+
mappings: map.mappings
79+
};
80+
}
81+
82+
write(dest, map) {
83+
dest = path.resolve(dest);
84+
mkdirp(path.dirname(dest));
85+
86+
const basename = path.basename(dest);
87+
88+
if (map !== false) {
89+
fs.writeFileSync(dest, `${this.code}\n/*# sourceMappingURL=${basename}.map */`);
90+
fs.writeFileSync(`${dest}.map`, JSON.stringify({
91+
version: 3,
92+
file: basename,
93+
sources: this.map.sources.map(source => path.relative(path.dirname(dest), source)),
94+
sourcesContent: this.map.sourcesContent,
95+
names: [],
96+
mappings: this.map.mappings
97+
}, null, ' '));
98+
} else {
99+
fs.writeFileSync(dest, this.code);
100+
}
101+
}
102+
103+
toString() {
104+
console.log('[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'); // eslint-disable-line no-console
105+
return this.code;
106+
}
107+
}
108+
55109
export default function svelte(options = {}) {
56110
const filter = createFilter(options.include, options.exclude);
57111

@@ -69,12 +123,21 @@ export default function svelte(options = {}) {
69123
fixedOptions.shared = require.resolve(options.shared || 'svelte/shared.js');
70124

71125
// handle CSS extraction
72-
if ('emitCss' in options) {
73-
if (typeof options.emitCss !== 'boolean') {
74-
throw new Error('options.emitCss must be a boolean');
126+
if ('css' in options) {
127+
if (typeof options.css !== 'function' && typeof options.css !== 'boolean') {
128+
throw new Error('options.css must be a boolean or a function');
75129
}
76130
}
77-
let cssBuffer = new Map();
131+
132+
let css = options.css && typeof options.css === 'function'
133+
? options.css
134+
: null;
135+
136+
const cssLookup = new Map();
137+
138+
if (css || options.emitCss) {
139+
fixedOptions.css = false;
140+
}
78141

79142
if (options.onwarn) {
80143
fixedOptions.onwarn = options.onwarn;
@@ -84,12 +147,12 @@ export default function svelte(options = {}) {
84147
name: 'svelte',
85148

86149
load(id) {
87-
if (!cssBuffer.has(id)) return null;
88-
return cssBuffer.get(id);
150+
if (!cssLookup.has(id)) return null;
151+
return cssLookup.get(id);
89152
},
90153

91154
resolveId(importee, importer) {
92-
if (cssBuffer.has(importee)) { return importee; }
155+
if (cssLookup.has(importee)) { return importee; }
93156
if (!importer || importee[0] === '.' || importee[0] === '\0' || path.isAbsolute(importee))
94157
return null;
95158

@@ -130,7 +193,7 @@ export default function svelte(options = {}) {
130193
code.toString(),
131194
Object.assign({}, {
132195
onwarn: warning => {
133-
if (!options.emitCss && warning.code === 'css-unused-selector') return;
196+
if ((options.css || !options.emitCss) && warning.code === 'css-unused-selector') return;
134197
this.warn(warning);
135198
},
136199
onerror: error => this.error(error)
@@ -145,18 +208,63 @@ export default function svelte(options = {}) {
145208
map: compiled.js ? compiled.js.map : compiled.map
146209
};
147210

148-
if (options.emitCss) {
211+
if (css || options.emitCss) {
149212
// handle pre- and post-1.60 signature
150-
const css_code = typeof compiled.css === 'string' ? compiled.css : compiled.css && compiled.css.code;
151-
const css_map = compiled.css && compiled.css.map || compiled.cssMap;
213+
let code = typeof compiled.css === 'string' ? compiled.css : compiled.css && compiled.css.code;
214+
let map = compiled.css && compiled.css.map || compiled.cssMap;
152215

153216
let fname = id.replace('.html', '.scss');
154-
cssBuffer.set(fname, { code: css_code, map: css_map });
155-
bundle.code += `\nimport '${fname}';\n`;
217+
cssLookup.set(fname, { code, map });
218+
if (options.emitCss) {
219+
bundle.code += `\nimport '${fname}';\n`;
220+
}
221+
156222
}
157223

158224
return bundle;
159225
});
226+
},
227+
ongenerate() {
228+
if (css) {
229+
// write out CSS file. TODO would be nice if there was a
230+
// a more idiomatic way to do this in Rollup
231+
let result = '';
232+
233+
const mappings = [];
234+
const sources = [];
235+
const sourcesContent = [];
236+
237+
for (let chunk of cssLookup.values()) {
238+
if (!chunk.code) continue;
239+
result += chunk.code + '\n';
240+
241+
if (chunk.map) {
242+
const i = sources.length;
243+
sources.push(chunk.map.sources[0]);
244+
sourcesContent.push(chunk.map.sourcesContent[0]);
245+
246+
const decoded = decode(chunk.map.mappings);
247+
248+
if (i > 0) {
249+
decoded.forEach(line => {
250+
line.forEach(segment => {
251+
segment[1] = i;
252+
});
253+
});
254+
}
255+
256+
mappings.push(...decoded);
257+
}
258+
}
259+
260+
const writer = new CssWriter(result, {
261+
sources,
262+
sourcesContent,
263+
mappings: encode(mappings)
264+
});
265+
266+
css(writer);
267+
}
160268
}
161269
};
162270
}

0 commit comments

Comments
 (0)