Skip to content

Commit cdfccb4

Browse files
committed
Squashed commit of the following:
commit e2631af Author: David Heidrich <[email protected]> Date: Mon Jun 19 19:08:13 2017 +0200 removed dead code, cleanup commit d8943d7 Author: David Heidrich <[email protected]> Date: Mon Jun 19 15:48:51 2017 +0200 restored console log commit 0d7c94a Author: David Heidrich <[email protected]> Date: Mon Jun 19 00:30:34 2017 +0200 fixed async loading (keep original style loader in async chunks) commit 950d7ef Author: David Heidrich <[email protected]> Date: Sun Jun 18 15:52:41 2017 +0200 fixed exporting module informations commit 8b97ee5 Author: David Heidrich <[email protected]> Date: Sun Jun 18 14:27:51 2017 +0200 fixed line length commit 6898aa4 Author: David Heidrich <[email protected]> Date: Sun Jun 18 14:26:34 2017 +0200 respect all chunks commit bbc93ab Author: David Heidrich <[email protected]> Date: Sun Jun 18 12:33:09 2017 +0200 adjusted test to be env agnostic commit 3eba627 Author: David Heidrich <[email protected]> Date: Sun Jun 18 12:25:16 2017 +0200 adjusted tests to use css-loader, added tests for allChunks, remove module from initial chunk commit 09ac8cb Author: David Heidrich <[email protected]> Date: Sat Jun 17 22:36:09 2017 +0200 adjusted tests, remove module from base if extracted commit 1791796 Author: David Heidrich <[email protected]> Date: Sat Jun 17 21:23:58 2017 +0200 added testcase for issue webpack-contrib#120
1 parent dd43832 commit cdfccb4

29 files changed

+402
-45
lines changed

index.js

+66-16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var ConcatSource = require("webpack-sources").ConcatSource;
77
var async = require("async");
88
var ExtractedModule = require("./ExtractedModule");
99
var Chunk = require("webpack/lib/Chunk");
10+
var NormalModule = require("webpack/lib/NormalModule");
1011
var OrderUndefinedError = require("./OrderUndefinedError");
1112
var loaderUtils = require("loader-utils");
1213
var validateOptions = require('schema-utils');
@@ -186,15 +187,15 @@ ExtractTextPlugin.prototype.loader = function(options) {
186187
ExtractTextPlugin.prototype.extract = function(options) {
187188
if(arguments.length > 1) {
188189
throw new Error("Breaking change: extract now only takes a single argument. Either an options " +
189-
"object *or* the loader(s).\n" +
190-
"Example: if your old code looked like this:\n" +
191-
" ExtractTextPlugin.extract('style-loader', 'css-loader')\n\n" +
192-
"You would change it to:\n" +
193-
" ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })\n\n" +
194-
"The available options are:\n" +
195-
" use: string | object | loader[]\n" +
196-
" fallback: string | object | loader[]\n" +
197-
" publicPath: string\n");
190+
"object *or* the loader(s).\n" +
191+
"Example: if your old code looked like this:\n" +
192+
" ExtractTextPlugin.extract('style-loader', 'css-loader')\n\n" +
193+
"You would change it to:\n" +
194+
" ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })\n\n" +
195+
"The available options are:\n" +
196+
" use: string | object | loader[]\n" +
197+
" fallback: string | object | loader[]\n" +
198+
" publicPath: string\n");
198199
}
199200
if(options.fallbackLoader) {
200201
console.warn('fallbackLoader option has been deprecated - replace with "fallback"');
@@ -225,14 +226,15 @@ ExtractTextPlugin.prototype.extract = function(options) {
225226
return [this.loader(options)]
226227
.concat(before, loader)
227228
.map(getLoaderObject);
228-
}
229+
};
229230

230231
ExtractTextPlugin.extract = ExtractTextPlugin.prototype.extract.bind(ExtractTextPlugin);
231232

232233
ExtractTextPlugin.prototype.apply = function(compiler) {
233234
var options = this.options;
234235
compiler.plugin("this-compilation", function(compilation) {
235236
var extractCompilation = new ExtractTextPluginCompilation();
237+
var toRemoveModules = {};
236238
compilation.plugin("normal-module-loader", function(loaderContext, module) {
237239
loaderContext[NS] = function(content, opt) {
238240
if(options.disable)
@@ -274,21 +276,43 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
274276
if(meta && (!meta.options.id || meta.options.id === id)) {
275277
var wasExtracted = Array.isArray(meta.content);
276278
if(shouldExtract !== wasExtracted) {
277-
module[NS + "/extract"] = shouldExtract; // eslint-disable-line no-path-concat
278-
compilation.rebuildModule(module, function(err) {
279+
var newModule = new NormalModule(
280+
module.request,
281+
module.userRequest,
282+
module.rawRequest,
283+
module.loaders,
284+
module.resource,
285+
module.parser
286+
);
287+
newModule[NS + "/extract"] = shouldExtract; // eslint-disable-line no-path-concat
288+
// build a new module and save result to extracted compilations
289+
compilation.buildModule(newModule, false, newModule, null, function(err) {
279290
if(err) {
280291
compilation.errors.push(err);
281292
return callback();
282293
}
283-
meta = module[NS];
294+
meta = newModule[NS];
284295
// Error out if content is not an array and is not null
285296
if(!Array.isArray(meta.content) && meta.content != null) {
286-
err = new Error(module.identifier() + " doesn't export content");
297+
err = new Error(newModule.identifier() + " doesn't export content");
287298
compilation.errors.push(err);
288299
return callback();
289300
}
290-
if(meta.content)
291-
extractCompilation.addResultToChunk(module.identifier(), meta.content, module, extractedChunk);
301+
if(meta.content) {
302+
var ident = module.identifier();
303+
extractCompilation.addResultToChunk(ident, meta.content, module, extractedChunk);
304+
// remove generated result from chunk
305+
if(toRemoveModules[ident]) {
306+
toRemoveModules[ident].chunks.push(chunk)
307+
} else {
308+
toRemoveModules[ident] = {
309+
module: newModule,
310+
moduleToRemove: module,
311+
chunks: [chunk]
312+
};
313+
}
314+
315+
}
292316
callback();
293317
});
294318
} else {
@@ -318,6 +342,32 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
318342
callback();
319343
}.bind(this));
320344
}.bind(this));
345+
compilation.plugin("optimize-module-ids", function(modules){
346+
modules.forEach(function (module) {
347+
var data = toRemoveModules[module.identifier()];
348+
if (data) {
349+
var id = module.id;
350+
var newModule = new NormalModule(
351+
module.request,
352+
module.userRequest,
353+
module.rawRequest,
354+
module.loaders,
355+
module.resource,
356+
module.parser
357+
);
358+
newModule.id = id;
359+
newModule._source = data.module._source;
360+
data.chunks.forEach(function (chunk) {
361+
chunk.removeModule(data.moduleToRemove);
362+
var deps = data.moduleToRemove.dependencies;
363+
deps.forEach(d => {
364+
chunk.removeModule(d.module);
365+
});
366+
chunk.addModule(newModule);
367+
});
368+
}
369+
});
370+
});
321371
compilation.plugin("additional-assets", function(callback) {
322372
extractedChunks.forEach(function(extractedChunk) {
323373
if(extractedChunk.modules.length) {

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"mocha": "^3.2.0",
3333
"mocha-lcov-reporter": "1.3.0",
3434
"raw-loader": "^0.5.1",
35+
"rimraf": "^2.6.1",
3536
"should": "^11.1.2",
3637
"standard-version": "^4.1.0",
3738
"style-loader": "^0.18.2",

test/TestCases.test.js

+33-29
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var vm = require("vm");
33
var path = require("path");
44
var webpack = require("webpack");
55
var should = require("should");
6+
var rimraf = require('rimraf');
67
var ExtractTextPlugin = require("../");
78

89
var cases = process.env.CASES ? process.env.CASES.split(",") : fs.readdirSync(path.join(__dirname, "cases"));
@@ -12,36 +13,39 @@ describe("TestCases", function() {
1213
it(testCase, function(done) {
1314
var testDirectory = path.join(__dirname, "cases", testCase);
1415
var outputDirectory = path.join(__dirname, "js", testCase);
15-
var options = { entry: { test: "./index.js" } };
16-
var configFile = path.join(testDirectory, "webpack.config.js");
17-
if(fs.existsSync(configFile))
18-
options = require(configFile);
19-
options.context = testDirectory;
20-
if(!options.module) options.module = {};
21-
if(!options.module.loaders) options.module.loaders = [
22-
{ test: /\.txt$/, loader: ExtractTextPlugin.extract("raw-loader") }
23-
];
24-
if(!options.output) options.output = { filename: "[name].js" };
25-
if(!options.output.path) options.output.path = outputDirectory;
26-
if(process.env.CASES) {
27-
console.log("\nwebpack." + testCase + ".config.js " + JSON.stringify(options, null, 2));
28-
}
29-
webpack(options, function(err, stats) {
30-
if(err) return done(err);
31-
if(stats.hasErrors()) return done(new Error(stats.toString()));
32-
var testFile = path.join(outputDirectory, "test.js");
33-
if(fs.existsSync(testFile))
34-
require(testFile)(suite);
35-
var expectedDirectory = path.join(testDirectory, "expected");
36-
fs.readdirSync(expectedDirectory).forEach(function(file) {
37-
var filePath = path.join(expectedDirectory, file);
38-
var actualPath = path.join(outputDirectory, file);
39-
readFileOrEmpty(actualPath).should.be.eql(
40-
readFileOrEmpty(filePath),
41-
file + " should be correct");
16+
function test() {
17+
var options = { entry: { test: "./index.js" } };
18+
var configFile = path.join(testDirectory, "webpack.config.js");
19+
if (fs.existsSync(configFile))
20+
options = require(configFile);
21+
options.context = testDirectory;
22+
if (!options.module) options.module = {};
23+
if (!options.module.loaders) options.module.loaders = [
24+
{ test: /\.txt$/, loader: ExtractTextPlugin.extract("raw-loader") }
25+
];
26+
if (!options.output) options.output = { filename: "[name].js" };
27+
if (!options.output.path) options.output.path = outputDirectory;
28+
if (process.env.CASES) {
29+
console.log("\nwebpack." + testCase + ".config.js " + JSON.stringify(options, null, 2));
30+
}
31+
webpack(options, function (err, stats) {
32+
if (err) return done(err);
33+
if (stats.hasErrors()) return done(new Error(stats.toString()));
34+
var testFile = path.join(outputDirectory, "test.js");
35+
if (fs.existsSync(testFile))
36+
require(testFile)(suite);
37+
var expectedDirectory = path.join(testDirectory, "expected");
38+
fs.readdirSync(expectedDirectory).forEach(function (file) {
39+
var filePath = path.join(expectedDirectory, file);
40+
var actualPath = path.join(outputDirectory, file);
41+
readFileOrEmpty(actualPath).should.be.eql(
42+
readFileOrEmpty(filePath),
43+
file + " should be correct");
44+
});
45+
done();
4246
});
43-
done();
44-
});
47+
}
48+
rimraf(outputDirectory, test);
4549
});
4650
});
4751
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
background: red;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require('../router');
2+
require('../routes/contact');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require('../router');
2+
require('../routes/homepage');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
webpackJsonp([0],{
2+
3+
/***/ 2:
4+
/***/ (function(module, exports, __webpack_require__) {
5+
6+
__webpack_require__(7);
7+
8+
modules.export = function() {
9+
return 'Route Homepage';
10+
};
11+
12+
13+
/***/ }),
14+
15+
/***/ 7:
16+
/***/ (function(module, exports) {
17+
18+
// removed by extract-text-webpack-plugin
19+
20+
/***/ })
21+
22+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
webpackJsonp([1],{
2+
3+
/***/ 1:
4+
/***/ (function(module, exports, __webpack_require__) {
5+
6+
__webpack_require__(6);
7+
8+
modules.export = function() {
9+
return 'Route Contact';
10+
};
11+
12+
13+
/***/ }),
14+
15+
/***/ 6:
16+
/***/ (function(module, exports) {
17+
18+
// removed by extract-text-webpack-plugin
19+
20+
/***/ })
21+
22+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
body {
2+
background: red;
3+
}
4+
.contact {
5+
color: black;
6+
}
7+
.homepage {
8+
color: black;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
body {
2+
background: red;
3+
}
4+
.contact {
5+
color: black;
6+
}
7+
.homepage {
8+
color: black;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
require('./default-styles.css');
2+
module.export = function (route) {
3+
return import(/* webpackChunkName: "route-[request]" */ './routes/' + route + 'index.js').then(function (route) {
4+
return route;
5+
});
6+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
require('./styles.css');
2+
3+
modules.export = function() {
4+
return 'Route Contact';
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.contact {
2+
color: black;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
require('./styles.css');
2+
3+
modules.export = function() {
4+
return 'Route Homepage';
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.homepage {
2+
color: black;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
var ExtractTextPlugin = require("../../../");
2+
module.exports = {
3+
entry: {
4+
'homepage': "./entries/homepage.js",
5+
'contact': "./entries/contact.js"
6+
},
7+
module: {
8+
loaders: [
9+
{ test: /\.css$/, use: ExtractTextPlugin.extract({
10+
fallback: "style-loader",
11+
use: { loader: "css-loader", options: {
12+
sourceMap: false
13+
} }
14+
}) }
15+
]
16+
},
17+
plugins: [
18+
new ExtractTextPlugin({
19+
filename: '[name].css',
20+
allChunks: true
21+
})
22+
]
23+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
background: red;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require('../router');
2+
require('../routes/contact');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require('../router');
2+
require('../routes/homepage');

0 commit comments

Comments
 (0)