Skip to content

Commit

Permalink
Merge pull request #15 from rollup/css-sourcemaps
Browse files Browse the repository at this point in the history
generate CSS sourcemaps
  • Loading branch information
Rich-Harris authored Jul 22, 2017
2 parents c0dc482 + 57d1483 commit e4f8218
Show file tree
Hide file tree
Showing 8 changed files with 828 additions and 107 deletions.
728 changes: 627 additions & 101 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,18 @@
"homepage": "https://github.com/rollup/rollup-plugin-svelte#README",
"devDependencies": {
"eslint": "^3.10.2",
"locate-character": "^2.0.1",
"mocha": "^3.1.2",
"rollup": "^0.41.5",
"rollup-plugin-buble": "^0.15.0",
"rollup-watch": "^3.2.2"
"rollup-watch": "^3.2.2",
"sander": "^0.6.0",
"source-map": "^0.5.6",
"svelte": "^1.25.1"
},
"dependencies": {
"require-relative": "^0.8.7",
"rollup-pluginutils": "^2.0.1",
"svelte": "^1.11.2"
"sourcemap-codec": "^1.3.1"
}
}
98 changes: 94 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'path';
import relative from 'require-relative';
import { compile } from 'svelte';
import { createFilter } from 'rollup-pluginutils';
import { encode, decode } from 'sourcemap-codec';

function sanitize(input) {
return path
Expand Down Expand Up @@ -51,6 +52,59 @@ function exists(file) {
}
}

function mkdirp(dir) {
const parent = path.dirname(dir);
if (parent === dir) return;

mkdirp(parent);

try {
fs.mkdirSync(dir);
} catch (err) {
if (err.code !== 'EEXIST') throw err;
}
}

class CssWriter {
constructor (code, map) {
this.code = code;
this.map = {
version: 3,
file: null,
sources: map.sources,
sourcesContent: map.sourcesContent,
names: [],
mappings: map.mappings
};
}

write(dest, map) {
dest = path.resolve(dest);
mkdirp(path.dirname(dest));

const basename = path.basename(dest);

if (map !== false) {
fs.writeFileSync(dest, `${this.code}\n/*# sourceMappingURL=${basename}.map */`);
fs.writeFileSync(`${dest}.map`, JSON.stringify({
version: 3,
file: basename,
sources: this.map.sources.map(source => path.relative(path.dirname(dest), source)),
sourcesContent: this.map.sourcesContent,
names: [],
mappings: this.map.mappings
}, null, ' '));
} else {
fs.writeFileSync(dest, this.code);
}
}

toString() {
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
return this.code;
}
}

export default function svelte(options = {}) {
const filter = createFilter(options.include, options.exclude);

Expand Down Expand Up @@ -140,7 +194,12 @@ export default function svelte(options = {}) {
})
);

if (css) cssLookup.set(id, compiled.css);
if (css) {
cssLookup.set(id, {
code: compiled.css,
map: compiled.cssMap
});
}

return {
code: compiled.code,
Expand All @@ -153,12 +212,43 @@ export default function svelte(options = {}) {
// write out CSS file. TODO would be nice if there was a
// a more idiomatic way to do this in Rollup
let result = '';

const mappings = [];
const sources = [];
const sourcesContent = [];

for (let chunk of cssLookup.values()) {
result += chunk || '';
if (!chunk.code) continue;

result += chunk.code + '\n';

if (chunk.map) {
const i = sources.length;
sources.push(chunk.map.sources[0]);
sourcesContent.push(chunk.map.sourcesContent[0]);

const decoded = decode(chunk.map.mappings);

if (i > 0) {
decoded.forEach(line => {
line.forEach(segment => {
segment[1] = i;
});
});
}

mappings.push(...decoded);
}
}

css(result);
const writer = new CssWriter(result, {
sources,
sourcesContent,
mappings: encode(mappings)
});

css(writer);
}
}
};
}
}
2 changes: 2 additions & 0 deletions test/sourcemap-test/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<link rel='stylesheet' href='dist/bundle.css'>
<body><script src='dist/bundle.js'></script></body>
7 changes: 7 additions & 0 deletions test/sourcemap-test/src/Bar.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<p class='bar'>blue</p>

<style>
.bar {
color: blue;
}
</style>
16 changes: 16 additions & 0 deletions test/sourcemap-test/src/Foo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<p class='foo'>red</p>
<Bar/>

<style>
.foo {
color: red;
}
</style>

<script>
import Bar from './Bar.html';

export default {
components: { Bar }
};
</script>
5 changes: 5 additions & 0 deletions test/sourcemap-test/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Foo from './Foo.html';

new Foo({
target: document.body
});
71 changes: 71 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
const path = require('path');
const sander = require('sander');
const assert = require('assert');
const rollup = require('rollup');
const { SourceMapConsumer } = require('source-map');
const { getLocator } = require('locate-character');

const plugin = require('../dist/rollup-plugin-svelte.cjs.js');

Expand Down Expand Up @@ -41,4 +45,71 @@ describe('rollup-plugin-svelte', () => {
const compiled = transform('', 'test.html');
assert.deepEqual(Object.keys(compiled), ['code', 'map']);
});

it('generates a CSS sourcemap', () => {
sander.rimrafSync('test/sourcemap-test/dist');
sander.mkdirSync('test/sourcemap-test/dist');

return rollup.rollup({
entry: 'test/sourcemap-test/src/main.js',
plugins: [
plugin({
cascade: false,
css: css => {
css.write('test/sourcemap-test/dist/bundle.css');

const smc = new SourceMapConsumer(css.map);
const locator = getLocator(css.code);

const generatedFooLoc = locator('.foo');
const originalFooLoc = smc.originalPositionFor({
line: generatedFooLoc.line + 1,
column: generatedFooLoc.column
});

assert.deepEqual(
{
source: originalFooLoc.source.replace(/\//g, path.sep),
line: originalFooLoc.line,
column: originalFooLoc.column,
name: originalFooLoc.name
},
{
source: path.resolve('test/sourcemap-test/src/Foo.html'),
line: 5,
column: 1,
name: null
}
);

const generatedBarLoc = locator('.bar');
const originalBarLoc = smc.originalPositionFor({
line: generatedBarLoc.line + 1,
column: generatedBarLoc.column
});

assert.deepEqual(
{
source: originalBarLoc.source.replace(/\//g, path.sep),
line: originalBarLoc.line,
column: originalBarLoc.column,
name: originalBarLoc.name
},
{
source: path.resolve('test/sourcemap-test/src/Bar.html'),
line: 4,
column: 1,
name: null
}
);
}
})
]
}).then(bundle => {
return bundle.write({
format: 'iife',
dest: 'test/sourcemap-test/dist/bundle.js'
});
});
});
});

0 comments on commit e4f8218

Please sign in to comment.