Skip to content

Commit 14642a5

Browse files
committed
Merge branch '196-webpack2-query-object' of https://github.com/jane/extract-text-webpack-plugin into jane-196-webpack2-query-object
# Conflicts: # package.json
2 parents d301fd0 + 8888cff commit 14642a5

File tree

15 files changed

+216
-155
lines changed

15 files changed

+216
-155
lines changed

README.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ var ExtractTextPlugin = require("extract-text-webpack-plugin");
77
module.exports = {
88
module: {
99
loaders: [
10-
{ test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }
10+
{ test: /\.css$/, loader: ExtractTextPlugin.extract({
11+
notExtractLoader: "style-loader",
12+
loader: "css-loader"
13+
}) }
1114
]
1215
},
1316
plugins: [
@@ -37,32 +40,30 @@ Caveats:
3740
## API
3841

3942
``` javascript
40-
new ExtractTextPlugin([id: string], filename: string, [options])
43+
new ExtractTextPlugin(options: filename | object)
4144
```
4245

43-
* `id` Unique ident for this plugin instance. (For advanced usage only; by default, automatically generated)
44-
* `filename` the filename of the result file. May contain `[name]`, `[id]` and `[contenthash]`.
46+
* `options.filename: string` _(required)_ the filename of the result file. May contain `[name]`, `[id]` and `[contenthash]`
4547
* `[name]` the name of the chunk
4648
* `[id]` the number of the chunk
4749
* `[contenthash]` a hash of the content of the extracted file
48-
* `options`
49-
* `allChunks` extract from all additional chunks too (by default it extracts only from the initial chunk(s))
50-
* `disable` disables the plugin
50+
* `options.allChunks: boolean` extract from all additional chunks too (by default it extracts only from the initial chunk(s))
51+
* `options.disable: boolean` disables the plugin
52+
* `options.id: string` Unique ident for this plugin instance. (For advanced usage only, by default automatically generated)
5153

5254
The `ExtractTextPlugin` generates an output file per entry, so you must use `[name]`, `[id]` or `[contenthash]` when using multiple entries.
5355

5456
``` javascript
55-
ExtractTextPlugin.extract([notExtractLoader], loader, [options])
57+
ExtractTextPlugin.extract(options: loader | object)
5658
```
5759

58-
Creates an extracting loader from an existing loader.
60+
Creates an extracting loader from an existing loader. Supports loaders of type `{ loader: string; query: object }`.
5961

60-
* `notExtractLoader` (optional) the loader(s) that should be used when the css is not extracted (i.e. in an additional chunk when `allChunks: false`)
61-
* `loader` the loader(s) that should be used for converting the resource to a css exporting module.
62-
* `options`
63-
* `publicPath` override the `publicPath` setting for this loader.
62+
* `options.loader: string | object | loader[]` _(required)_ the loader(s) that should be used for converting the resource to a css exporting module
63+
* `options.notExtractLoader: string | object | loader[]` the loader(s) that should be used when the css is not extracted (i.e. in an additional chunk when `allChunks: false`)
64+
* `options.publicPath: string` override the `publicPath` setting for this loader
6465

65-
There is also an `extract` function on the instance. You should use this if you have more than one ExtractTextPlugin.
66+
There is also an `extract` function on the instance. You should use this if you have more than one `ExtractTextPlugin`.
6667

6768
```javascript
6869
let ExtractTextPlugin = require('extract-text-webpack-plugin');
@@ -75,8 +76,8 @@ module.exports = {
7576
...
7677
module: {
7778
loaders: [
78-
{test: /\.scss$/i, loader: extractCSS.extract(['css','sass'])},
79-
{test: /\.less$/i, loader: extractLESS.extract(['css','less'])},
79+
{ test: /\.scss$/i, loader: extractCSS.extract(['css','sass']) },
80+
{ test: /\.less$/i, loader: extractLESS.extract(['css','less']) },
8081
...
8182
]
8283
},

example/webpack.config.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,21 @@ module.exports = {
1313
},
1414
module: {
1515
loaders: [
16-
{ test: /\.css$/, loader: ExtractTextPlugin.extract(
17-
"style-loader",
18-
"css-loader?sourceMap",
19-
{
20-
publicPath: "../"
21-
}
22-
)},
16+
{ test: /\.css$/, loader: ExtractTextPlugin.extract({
17+
notExtractLoader: "style-loader",
18+
loader: "css-loader?sourceMap",
19+
publicPath: "../"
20+
}) },
2321
{ test: /\.png$/, loader: "file-loader" }
2422
]
2523
},
2624
devtool: "source-map",
2725
plugins: [
28-
new ExtractTextPlugin("css/[name].css?[hash]-[chunkhash]-[contenthash]-[name]", {
26+
new ExtractTextPlugin({
27+
filename: "css/[name].css?[hash]-[chunkhash]-[contenthash]-[name]",
2928
disable: false,
3029
allChunks: true
3130
}),
32-
new webpack.optimize.CommonsChunkPlugin("c", "c.js")
31+
new webpack.optimize.CommonsChunkPlugin({ name: "c", filename: "c.js" })
3332
]
3433
};

index.js

Lines changed: 71 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,38 @@ function getOrder(a, b) {
100100
return 0;
101101
}
102102

103-
function ExtractTextPlugin(id, filename, options) {
104-
if(typeof filename !== "string") {
105-
options = filename;
106-
filename = id;
107-
id = ++nextId;
103+
function ExtractTextPlugin(options) {
104+
if(arguments.length > 1) {
105+
throw new Error("Breaking change: ExtractTextPlugin now only takes a single argument. Either an options " +
106+
"object *or* the name of the result file.\n" +
107+
"Example: if your old code looked like this:\n" +
108+
" new ExtractTextPlugin('css/[name].css', { disable: false, allChunks: true })\n\n" +
109+
"You would change it to:\n" +
110+
" new ExtractTextPlugin({ filename: 'css/[name].css', disable: false, allChunks: true })\n\n" +
111+
"The available options are:\n" +
112+
" filename: string\n" +
113+
" allChunks: boolean\n" +
114+
" disable: boolean\n");
108115
}
109-
if(!options) options = {};
110-
this.filename = filename;
111-
this.options = options;
112-
this.id = id;
116+
if(isString(options)) {
117+
options = { filename: options };
118+
}
119+
this.filename = options.filename;
120+
this.id = options.id != null ? options.id : ++nextId;
121+
this.options = {};
122+
mergeOptions(this.options, options);
123+
delete this.options.filename;
124+
delete this.options.id;
113125
}
114126
module.exports = ExtractTextPlugin;
115127

128+
// modified from webpack/lib/LoadersList.js
129+
function getLoaderWithQuery(loader) {
130+
if(isString(loader) || !loader.query) return loader;
131+
var query = isString(loader.query) ? loader.query : JSON.stringify(loader.query);
132+
return loader.loader + "?" + query;
133+
}
134+
116135
function mergeOptions(a, b) {
117136
if(!b) return a;
118137
Object.keys(b).forEach(function(key) {
@@ -121,25 +140,12 @@ function mergeOptions(a, b) {
121140
return a;
122141
}
123142

124-
ExtractTextPlugin.loader = function(options) {
125-
return require.resolve("./loader") + (options ? "?" + JSON.stringify(options) : "");
126-
};
143+
function isString(a) {
144+
return typeof a === "string";
145+
}
127146

128-
ExtractTextPlugin.extract = function(before, loader, options) {
129-
if(typeof loader === "string" || Array.isArray(loader)) {
130-
if(typeof before === "string") {
131-
before = before.split("!");
132-
}
133-
return [
134-
ExtractTextPlugin.loader(mergeOptions({omit: before.length, extract: true, remove: true}, options))
135-
].concat(before, loader).join("!");
136-
} else {
137-
options = loader;
138-
loader = before;
139-
return [
140-
ExtractTextPlugin.loader(mergeOptions({remove: true}, options))
141-
].concat(loader).join("!");
142-
}
147+
ExtractTextPlugin.loader = function(options) {
148+
return { loader: require.resolve("./loader"), query: options };
143149
};
144150

145151
ExtractTextPlugin.prototype.applyAdditionalInformation = function(source, info) {
@@ -154,27 +160,45 @@ ExtractTextPlugin.prototype.applyAdditionalInformation = function(source, info)
154160
};
155161

156162
ExtractTextPlugin.prototype.loader = function(options) {
157-
options = JSON.parse(JSON.stringify(options || {}));
158-
options.id = this.id;
159-
return ExtractTextPlugin.loader(options);
163+
return ExtractTextPlugin.loader(mergeOptions({id: this.id}, options));
160164
};
161165

162-
ExtractTextPlugin.prototype.extract = function(before, loader, options) {
163-
if(typeof loader === "string" || Array.isArray(loader)) {
164-
if(typeof before === "string") {
165-
before = before.split("!");
166-
}
167-
return [
168-
this.loader(mergeOptions({omit: before.length, extract: true, remove: true}, options))
169-
].concat(before, loader).join("!");
170-
} else {
171-
options = loader;
172-
loader = before;
173-
return [
174-
this.loader(mergeOptions({remove: true}, options))
175-
].concat(loader).join("!");
166+
ExtractTextPlugin.prototype.extract = function(options) {
167+
if(arguments.length > 1) {
168+
throw new Error("Breaking change: extract now only takes a single argument. Either an options " +
169+
"object *or* the loader(s).\n" +
170+
"Example: if your old code looked like this:\n" +
171+
" ExtractTextPlugin.extract('style-loader', 'css-loader')\n\n" +
172+
"You would change it to:\n" +
173+
" ExtractTextPlugin.extract({ notExtractLoader: 'style-loader', loader: 'css-loader' })\n\n" +
174+
"The available options are:\n" +
175+
" loader: string | object | loader[]\n" +
176+
" notExtractLoader: string | object | loader[]\n" +
177+
" publicPath: string\n");
176178
}
177-
};
179+
if(Array.isArray(options) || isString(options) || typeof options.query === "object") {
180+
options = { loader: options };
181+
}
182+
var loader = options.loader;
183+
var before = options.notExtractLoader || [];
184+
if(isString(loader)) {
185+
loader = loader.split("!");
186+
}
187+
if(isString(before)) {
188+
before = before.split("!");
189+
} else if(!Array.isArray(before)) {
190+
before = [before];
191+
}
192+
options = mergeOptions({omit: before.length, remove: true}, options);
193+
delete options.loader;
194+
delete options.notExtractLoader;
195+
return [this.loader(options)]
196+
.concat(before, loader)
197+
.map(getLoaderWithQuery)
198+
.join("!");
199+
}
200+
201+
ExtractTextPlugin.extract = ExtractTextPlugin.prototype.extract.bind(ExtractTextPlugin);
178202

179203
ExtractTextPlugin.prototype.apply = function(compiler) {
180204
var options = this.options;
@@ -184,8 +208,8 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
184208
loaderContext[__dirname] = function(content, opt) {
185209
if(options.disable)
186210
return false;
187-
if(!Array.isArray(content) && content !== null)
188-
throw new Error("Exported value is not a string.");
211+
if(!Array.isArray(content) && content != null)
212+
throw new Error("Exported value was not extracted as an array: " + JSON.stringify(content));
189213
module.meta[__dirname] = {
190214
content: content,
191215
options: opt || {}

0 commit comments

Comments
 (0)