mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Rewrite source map composition for CSS files
The previous implementation had a run time quadratic in the number of CSS files with an associated source map. This new implementation has a linear run time because it iterates only once through all mappings of each CSS file.
This commit is contained in:
@@ -119,26 +119,73 @@ var mergeCss = Profile("mergeCss", function (css) {
|
||||
|
||||
var newMap;
|
||||
|
||||
// Compose the concatenated file's source map with source maps from the
|
||||
// previous build step if necessary.
|
||||
Profile.time("composing source maps", function () {
|
||||
// If any input files had source maps, apply them.
|
||||
// Ex.: less -> css source map should be composed with css -> css source map
|
||||
newMap = sourcemap.SourceMapGenerator.fromSourceMap(
|
||||
new sourcemap.SourceMapConsumer(stringifiedCss.map));
|
||||
var concatConsumer;
|
||||
|
||||
Object.keys(originals).forEach(function (name) {
|
||||
newMap = new sourcemap.SourceMapGenerator();
|
||||
concatConsumer = new sourcemap.SourceMapConsumer(stringifiedCss.map);
|
||||
|
||||
// Create a dictionary of source map consumers for fast access
|
||||
var consumers = Object.keys(originals).reduce(function (consumers, name) {
|
||||
var file = originals[name];
|
||||
if (! file.getSourceMap())
|
||||
return;
|
||||
try {
|
||||
newMap.applySourceMap(
|
||||
new sourcemap.SourceMapConsumer(file.getSourceMap()), name);
|
||||
} catch (err) {
|
||||
// If we can't apply the source map, silently drop it.
|
||||
//
|
||||
// XXX This is here because there are some less files that
|
||||
// produce source maps that throw when consumed. We should
|
||||
// figure out exactly why and fix it, but this will do for now.
|
||||
var sourceMap = file.getSourceMap();
|
||||
|
||||
if (sourceMap) {
|
||||
try {
|
||||
consumers[name] = new sourcemap.SourceMapConsumer(sourceMap);
|
||||
} catch (err) {
|
||||
// If we can't apply the source map, silently drop it.
|
||||
//
|
||||
// XXX This is here because there are some less files that
|
||||
// produce source maps that throw when consumed. We should
|
||||
// figure out exactly why and fix it, but this will do for now.
|
||||
}
|
||||
}
|
||||
|
||||
return consumers;
|
||||
}, Object.create(null));
|
||||
|
||||
// Find mappings from the concatenated file back to the original files
|
||||
concatConsumer.eachMapping(function (mapping) {
|
||||
var consumer = consumers[mapping.source];
|
||||
var source;
|
||||
|
||||
// If there is a source map for the original file, e.g., if it has been
|
||||
// compiled from Less to CSS, find the source location in the original's
|
||||
// original file. Otherwise, use the mapping of the concatenated file's
|
||||
// source map.
|
||||
var original = {
|
||||
line: mapping.originalLine,
|
||||
column: mapping.originalColumn
|
||||
};
|
||||
|
||||
if (consumer) {
|
||||
original = consumer.originalPositionFor(original);
|
||||
source = original.source;
|
||||
} else {
|
||||
source = mapping.source;
|
||||
}
|
||||
|
||||
// Add a new mapping to the final source map
|
||||
newMap.addMapping({
|
||||
generated: {
|
||||
line: mapping.generatedLine,
|
||||
column: mapping.generatedColumn
|
||||
},
|
||||
original: {
|
||||
line: original.line,
|
||||
column: original.column
|
||||
},
|
||||
source: source
|
||||
});
|
||||
|
||||
// Set the correct content for the mapping's source
|
||||
newMap.setSourceContent(
|
||||
source,
|
||||
(consumer || concatConsumer).sourceContentFor(source)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user