Skip to content

Commit 202b58d

Browse files
author
Zhicheng Wang
committed
feat: Include the sourceMappingURL & sourceURL when toString()
This feature is useful when you need to pass the result of css-loader to angular: call to require('to-string-loader!css-loader? sourceMap!sass-loader?sourceMap!./ test.scss') will include source mapping, And finally assigned to the component's styles metadata
1 parent 199897f commit 202b58d

File tree

3 files changed

+74
-45
lines changed

3 files changed

+74
-45
lines changed

lib/css-base.js

+56-44
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,62 @@
11
/*
2-
MIT License http://www.opensource.org/licenses/mit-license.php
3-
Author Tobias Koppers @sokra
4-
*/
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
55
// css base code, injected by the css-loader
66
module.exports = function() {
7-
var list = [];
7+
var list = [];
88

9-
// return the list of modules as css string
10-
list.toString = function toString() {
11-
var result = [];
12-
for(var i = 0; i < this.length; i++) {
13-
var item = this[i];
14-
if(item[2]) {
15-
result.push("@media " + item[2] + "{" + item[1] + "}");
16-
} else {
17-
result.push(item[1]);
18-
}
19-
}
20-
return result.join("");
21-
};
9+
// return the list of modules as css string
10+
list.toString = function toString() {
11+
return this.map(function(item){
12+
const content = cssWithMappingToString(item);
13+
if(item[2]) {
14+
return "@media " + item[2] + "{" + content + "}";
15+
} else {
16+
return content;
17+
}
18+
}).join("");
19+
};
2220

23-
// import a list of modules into the list
24-
list.i = function(modules, mediaQuery) {
25-
if(typeof modules === "string")
26-
modules = [[null, modules, ""]];
27-
var alreadyImportedModules = {};
28-
for(var i = 0; i < this.length; i++) {
29-
var id = this[i][0];
30-
if(typeof id === "number")
31-
alreadyImportedModules[id] = true;
32-
}
33-
for(i = 0; i < modules.length; i++) {
34-
var item = modules[i];
35-
// skip already imported module
36-
// this implementation is not 100% perfect for weird media query combinations
37-
// when a module is imported multiple times with different media queries.
38-
// I hope this will never occur (Hey this way we have smaller bundles)
39-
if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
40-
if(mediaQuery && !item[2]) {
41-
item[2] = mediaQuery;
42-
} else if(mediaQuery) {
43-
item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
44-
}
45-
list.push(item);
46-
}
47-
}
48-
};
49-
return list;
21+
// import a list of modules into the list
22+
list.i = function(modules, mediaQuery) {
23+
if(typeof modules === "string")
24+
modules = [[null, modules, ""]];
25+
var alreadyImportedModules = {};
26+
for(var i = 0; i < this.length; i++) {
27+
var id = this[i][0];
28+
if(typeof id === "number")
29+
alreadyImportedModules[id] = true;
30+
}
31+
for(i = 0; i < modules.length; i++) {
32+
var item = modules[i];
33+
// skip already imported module
34+
// this implementation is not 100% perfect for weird media query combinations
35+
// when a module is imported multiple times with different media queries.
36+
// I hope this will never occur (Hey this way we have smaller bundles)
37+
if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
38+
if(mediaQuery && !item[2]) {
39+
item[2] = mediaQuery;
40+
} else if(mediaQuery) {
41+
item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
42+
}
43+
list.push(item);
44+
}
45+
}
46+
};
47+
return list;
5048
};
49+
50+
function cssWithMappingToString(item) {
51+
var content = item[1] || '';
52+
var cssMapping = item[3];
53+
if (!cssMapping) {
54+
return content;
55+
}
56+
var convertSourceMap = require('convert-source-map');
57+
var sourceMapping = convertSourceMap.fromObject(cssMapping).toComment({multiline: true});
58+
var sourceURLs = cssMapping.sources.map(function (source) {
59+
return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'
60+
});
61+
return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
62+
}

package.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
"engines": {
77
"node": ">=0.12.0 || >=4.3.0 <5.0.0 || >=5.10"
88
},
9-
"files": ["index.js", "locals.js", "lib"],
9+
"files": [
10+
"index.js",
11+
"locals.js",
12+
"lib"
13+
],
1014
"dependencies": {
1115
"babel-code-frame": "^6.11.0",
16+
"convert-source-map": "^1.3.0",
1217
"css-selector-tokenizer": "^0.7.0",
1318
"cssnano": ">=2.6.1 <4",
1419
"loader-utils": "~0.2.2",

test/cssBaseTest.js

+12
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,16 @@ describe("css-base", function() {
3434
"@media print{body { d: 4; }}" +
3535
"@media screen{body { a: 1; }}");
3636
});
37+
it("should toString with source mapping", function() {
38+
var m = base();
39+
m.push([1, "body { a: 1; }", "", {
40+
file: "test.scss",
41+
sources: [
42+
'./path/to/test.scss'
43+
],
44+
mappings: "AAAA;",
45+
sourceRoot: "webpack://"
46+
}]);
47+
m.toString().should.be.eql("body { a: 1; }\n/*# sourceURL=webpack://./path/to/test.scss */\n/*# sourceMappingURL=data:application/json;base64,eyJmaWxlIjoidGVzdC5zY3NzIiwic291cmNlcyI6WyIuL3BhdGgvdG8vdGVzdC5zY3NzIl0sIm1hcHBpbmdzIjoiQUFBQTsiLCJzb3VyY2VSb290Ijoid2VicGFjazovLyJ9 */");
48+
});
3749
});

0 commit comments

Comments
 (0)