Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit 7fc7957

Browse files
committed
accept an array of items with ids and SourceMap
fixes webpack-contrib/css-loader#13
1 parent d161f5d commit 7fc7957

File tree

9 files changed

+83
-26
lines changed

9 files changed

+83
-26
lines changed

.npmignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
./node_modules
2+
./example

example/base.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
border: 1px solid black;
3+
}

example/index.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8"/>
5+
<link rel="stylesheet" href="assets/styles.css" />
6+
</head>
7+
<body>
8+
<script type="text/javascript" charset="utf-8" src="/assets/bundle.js"></script>
9+
</body>
10+
</html>

example/style.css

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
@import "base.css";
12
body {
23
background: url(image.png);
34
}

example/style2.css

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
@import "base.css";
12
body {
23
color: red;
34
}

example/webpack.config.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ module.exports = {
44
output: {
55
filename: "bundle.js",
66
path: __dirname + "/assets",
7-
publicPath: "assets/"
7+
publicPath: "/assets/"
88
},
99
module: {
1010
loaders: [
11-
{ test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader")},
11+
{ test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader?sourceMap")},
1212
{ test: /\.png$/, loader: "file-loader" }
1313
]
1414
},
1515
plugins: [
16-
new ExtractTextPlugin("styles-[hash]-[chunkhash]-[name].css")
16+
new ExtractTextPlugin("styles.css?[hash]-[chunkhash]-[name]")
1717
]
1818
};

index.js

+50-20
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
MIT License http://www.opensource.org/licenses/mit-license.php
33
Author Tobias Koppers @sokra
44
*/
5-
var RawSource = require("webpack/lib/RawSource");
5+
var SourceMapSource = require("webpack/lib/SourceMapSource");
66
var Template = require("webpack/lib/Template");
77
var async = require("async");
8+
var SourceNode = require("source-map").SourceNode;
9+
var SourceMapConsumer = require("source-map").SourceMapConsumer;
10+
var ModuleFilenameHelpers = require("webpack/lib/ModuleFilenameHelpers");
811

912
var nextId = 0;
1013

@@ -41,6 +44,17 @@ ExtractTextPlugin.extract = function(before, loader) {
4144
}
4245
};
4346

47+
ExtractTextPlugin.prototype.applyAdditionalInformation = function(node, info) {
48+
if(info.length === 1 && info[0]) {
49+
node = new SourceNode(null, null, null, [
50+
"@media " + info[0] + " {",
51+
node,
52+
"}"
53+
]);
54+
}
55+
return node;
56+
};
57+
4458
ExtractTextPlugin.prototype.loader = function(options) {
4559
options = JSON.parse(JSON.stringify(options || {}));
4660
options.id = this.id;
@@ -67,28 +81,28 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
6781
var options = this.options;
6882
compiler.plugin("this-compilation", function(compilation) {
6983
compilation.plugin("normal-module-loader", function(loaderContext, module) {
70-
loaderContext[__dirname] = function(text, opt) {
71-
if(typeof text !== "string" && text !== null)
84+
loaderContext[__dirname] = function(content, opt) {
85+
if(!Array.isArray(content) && content !== null)
7286
throw new Error("Exported value is not a string.");
7387
module.meta[__dirname] = {
74-
text: text,
88+
content: content,
7589
options: opt
7690
};
7791
return options.allChunks || module.meta[__dirname + "/extract"];
7892
};
7993
}.bind(this));
80-
var texts;
94+
var contents;
8195
var filename = this.filename;
8296
var id = this.id;
8397
compilation.plugin("optimize-tree", function(chunks, modules, callback) {
84-
texts = [];
98+
contents = [];
8599
async.forEach(chunks, function(chunk, callback) {
86100
var shouldExtract = !!(options.allChunks || chunk.initial);
87-
var text = [];
101+
var content = [];
88102
async.forEach(chunk.modules.slice(), function(module, callback) {
89103
var meta = module.meta && module.meta[__dirname];
90104
if(meta) {
91-
var wasExtracted = typeof meta.text === "string";
105+
var wasExtracted = Array.isArray(meta.content);
92106
if(shouldExtract !== wasExtracted) {
93107
module.meta[__dirname + "/extract"] = shouldExtract
94108
compilation.rebuildModule(module, function(err) {
@@ -97,25 +111,25 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
97111
return callback();
98112
}
99113
meta = module.meta[__dirname];
100-
if(typeof meta.text !== "string") {
101-
var err = new Error(module.identifier() + " doesn't export text");
114+
if(!Array.isArray(meta.content)) {
115+
var err = new Error(module.identifier() + " doesn't export content");
102116
compilation.errors.push(err);
103117
return callback();
104118
}
105-
if(meta.text) text.push(meta.text);
119+
if(meta.content) content.push(meta.content);
106120
callback();
107121
});
108122
} else {
109-
if(meta.text) text.push(meta.text);
123+
if(meta.content) content.push(meta.content);
110124
callback();
111125
}
112126
} else callback();
113127
}, function(err) {
114128
if(err) return callback(err);
115-
if(text.length > 0) {
116-
texts.push({
129+
if(content.length > 0) {
130+
contents.push({
117131
chunk: chunk,
118-
text: text
132+
content: content
119133
});
120134
}
121135
callback();
@@ -127,19 +141,35 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
127141
});
128142
compilation.plugin("additional-assets", function(callback) {
129143
var assetContents = {};
130-
texts.forEach(function(item) {
144+
contents.forEach(function(item) {
131145
var chunk = item.chunk;
132146
var file = filename
133147
.replace(Template.REGEXP_NAME, chunk.name || chunk.id)
134148
.replace(Template.REGEXP_HASH, compilation.hash)
135149
.replace(Template.REGEXP_CHUNKHASH, chunk.renderedHash);
136-
assetContents[file] = (assetContents[file] || []).concat(item.text);
150+
assetContents[file] = (assetContents[file] || []).concat(item.content);
151+
chunk.files.push(file);
137152
});
138153
Object.keys(assetContents).forEach(function(file) {
139-
var text = assetContents[file].join("");
140-
this.assets[file] = new RawSource(text);
154+
var contained = {};
155+
var content = assetContents[file].reduce(function(arr, items) {
156+
return arr.concat(items);
157+
}, []).filter(function(item) {
158+
if(contained[item[0]]) return false;
159+
contained[item[0]] = true;
160+
return true;
161+
}).map(function(item) {
162+
var css = item[1];
163+
var contents = item.slice(1).filter(function(i) { return typeof i === "string"; });
164+
var sourceMap = typeof item[item.length-1] === "object" ? item[item.length-1] : undefined;
165+
var text = contents.shift();
166+
var node = sourceMap ? SourceNode.fromStringWithSourceMap(text, new SourceMapConsumer(sourceMap)) : new SourceNode(null, null, null, text);
167+
return this.applyAdditionalInformation(node, contents);
168+
}.bind(this));
169+
var strAndMap = new SourceNode(null, null, null, content).toStringWithSourceMap();
170+
compilation.assets[file] = new SourceMapSource(strAndMap.code, file, strAndMap.map.toJSON());
141171
}.bind(this));
142172
callback();
143-
});
173+
}.bind(this));
144174
}.bind(this));
145175
};

loader.js

+9
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ module.exports.pitch = function(request, preReq, data) {
7575
}, this);
7676
try {
7777
var text = this.exec(source, request);
78+
if(typeof text === "string")
79+
text = [[0, text]];
80+
text.forEach(function(item) {
81+
var id = item[0];
82+
compilation.modules.forEach(function(module) {
83+
if(module.id === id)
84+
item[0] = module.identifier();
85+
});
86+
});
7887
this[__dirname](text, query);
7988
} catch(e) {
8089
return callback(e);

package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
"author": "Tobias Koppers @sokra",
55
"description": "Extract text from bundle into a file.",
66
"peerDependencies": {
7-
"webpack": "^1.3"
7+
"webpack": "^1.4"
88
},
99
"dependencies": {
10-
"async": "0.2.x",
11-
"loader-utils": "0.2.x"
10+
"async": "~0.2.10",
11+
"source-map": "~0.1.38",
12+
"loader-utils": "~0.2.3"
1213
},
1314
"devDependencies": {
1415
"file-loader": "*",

0 commit comments

Comments
 (0)