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

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit e2631af
Author: David Heidrich <me@bowlingx.com>
Date:   Mon Jun 19 19:08:13 2017 +0200

    removed dead code, cleanup

commit d8943d7
Author: David Heidrich <me@bowlingx.com>
Date:   Mon Jun 19 15:48:51 2017 +0200

    restored console log

commit 0d7c94a
Author: David Heidrich <me@bowlingx.com>
Date:   Mon Jun 19 00:30:34 2017 +0200

    fixed async loading (keep original style loader in async chunks)

commit 950d7ef
Author: David Heidrich <me@bowlingx.com>
Date:   Sun Jun 18 15:52:41 2017 +0200

    fixed exporting module informations

commit 8b97ee5
Author: David Heidrich <me@bowlingx.com>
Date:   Sun Jun 18 14:27:51 2017 +0200

    fixed line length

commit 6898aa4
Author: David Heidrich <me@bowlingx.com>
Date:   Sun Jun 18 14:26:34 2017 +0200

    respect all chunks

commit bbc93ab
Author: David Heidrich <me@bowlingx.com>
Date:   Sun Jun 18 12:33:09 2017 +0200

    adjusted test to be env agnostic

commit 3eba627
Author: David Heidrich <me@bowlingx.com>
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 <me@bowlingx.com>
Date:   Sat Jun 17 22:36:09 2017 +0200

    adjusted tests, remove module from base if extracted

commit 1791796
Author: David Heidrich <me@bowlingx.com>
Date:   Sat Jun 17 21:23:58 2017 +0200

    added testcase for issue #120
  • Loading branch information
BowlingX committed Jun 20, 2017
1 parent dd43832 commit cdfccb4
Show file tree
Hide file tree
Showing 29 changed files with 402 additions and 45 deletions.
82 changes: 66 additions & 16 deletions index.js
Expand Up @@ -7,6 +7,7 @@ var ConcatSource = require("webpack-sources").ConcatSource;
var async = require("async");
var ExtractedModule = require("./ExtractedModule");
var Chunk = require("webpack/lib/Chunk");
var NormalModule = require("webpack/lib/NormalModule");
var OrderUndefinedError = require("./OrderUndefinedError");
var loaderUtils = require("loader-utils");
var validateOptions = require('schema-utils');
Expand Down Expand Up @@ -186,15 +187,15 @@ ExtractTextPlugin.prototype.loader = function(options) {
ExtractTextPlugin.prototype.extract = function(options) {
if(arguments.length > 1) {
throw new Error("Breaking change: extract now only takes a single argument. Either an options " +
"object *or* the loader(s).\n" +
"Example: if your old code looked like this:\n" +
" ExtractTextPlugin.extract('style-loader', 'css-loader')\n\n" +
"You would change it to:\n" +
" ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })\n\n" +
"The available options are:\n" +
" use: string | object | loader[]\n" +
" fallback: string | object | loader[]\n" +
" publicPath: string\n");
"object *or* the loader(s).\n" +
"Example: if your old code looked like this:\n" +
" ExtractTextPlugin.extract('style-loader', 'css-loader')\n\n" +
"You would change it to:\n" +
" ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })\n\n" +
"The available options are:\n" +
" use: string | object | loader[]\n" +
" fallback: string | object | loader[]\n" +
" publicPath: string\n");
}
if(options.fallbackLoader) {
console.warn('fallbackLoader option has been deprecated - replace with "fallback"');
Expand Down Expand Up @@ -225,14 +226,15 @@ ExtractTextPlugin.prototype.extract = function(options) {
return [this.loader(options)]
.concat(before, loader)
.map(getLoaderObject);
}
};

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

ExtractTextPlugin.prototype.apply = function(compiler) {
var options = this.options;
compiler.plugin("this-compilation", function(compilation) {
var extractCompilation = new ExtractTextPluginCompilation();
var toRemoveModules = {};
compilation.plugin("normal-module-loader", function(loaderContext, module) {
loaderContext[NS] = function(content, opt) {
if(options.disable)
Expand Down Expand Up @@ -274,21 +276,43 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
if(meta && (!meta.options.id || meta.options.id === id)) {
var wasExtracted = Array.isArray(meta.content);
if(shouldExtract !== wasExtracted) {
module[NS + "/extract"] = shouldExtract; // eslint-disable-line no-path-concat
compilation.rebuildModule(module, function(err) {
var newModule = new NormalModule(
module.request,
module.userRequest,
module.rawRequest,
module.loaders,
module.resource,
module.parser
);
newModule[NS + "/extract"] = shouldExtract; // eslint-disable-line no-path-concat
// build a new module and save result to extracted compilations
compilation.buildModule(newModule, false, newModule, null, function(err) {
if(err) {
compilation.errors.push(err);
return callback();
}
meta = module[NS];
meta = newModule[NS];
// Error out if content is not an array and is not null
if(!Array.isArray(meta.content) && meta.content != null) {
err = new Error(module.identifier() + " doesn't export content");
err = new Error(newModule.identifier() + " doesn't export content");
compilation.errors.push(err);
return callback();
}
if(meta.content)
extractCompilation.addResultToChunk(module.identifier(), meta.content, module, extractedChunk);
if(meta.content) {
var ident = module.identifier();
extractCompilation.addResultToChunk(ident, meta.content, module, extractedChunk);
// remove generated result from chunk
if(toRemoveModules[ident]) {
toRemoveModules[ident].chunks.push(chunk)
} else {
toRemoveModules[ident] = {
module: newModule,
moduleToRemove: module,
chunks: [chunk]
};
}

}
callback();
});
} else {
Expand Down Expand Up @@ -318,6 +342,32 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
callback();
}.bind(this));
}.bind(this));
compilation.plugin("optimize-module-ids", function(modules){
modules.forEach(function (module) {
var data = toRemoveModules[module.identifier()];
if (data) {
var id = module.id;
var newModule = new NormalModule(
module.request,
module.userRequest,
module.rawRequest,
module.loaders,
module.resource,
module.parser
);
newModule.id = id;
newModule._source = data.module._source;
data.chunks.forEach(function (chunk) {
chunk.removeModule(data.moduleToRemove);
var deps = data.moduleToRemove.dependencies;
deps.forEach(d => {
chunk.removeModule(d.module);
});
chunk.addModule(newModule);
});
}
});
});
compilation.plugin("additional-assets", function(callback) {
extractedChunks.forEach(function(extractedChunk) {
if(extractedChunk.modules.length) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -32,6 +32,7 @@
"mocha": "^3.2.0",
"mocha-lcov-reporter": "1.3.0",
"raw-loader": "^0.5.1",
"rimraf": "^2.6.1",
"should": "^11.1.2",
"standard-version": "^4.1.0",
"style-loader": "^0.18.2",
Expand Down
62 changes: 33 additions & 29 deletions test/TestCases.test.js
Expand Up @@ -3,6 +3,7 @@ var vm = require("vm");
var path = require("path");
var webpack = require("webpack");
var should = require("should");
var rimraf = require('rimraf');
var ExtractTextPlugin = require("../");

var cases = process.env.CASES ? process.env.CASES.split(",") : fs.readdirSync(path.join(__dirname, "cases"));
Expand All @@ -12,36 +13,39 @@ describe("TestCases", function() {
it(testCase, function(done) {
var testDirectory = path.join(__dirname, "cases", testCase);
var outputDirectory = path.join(__dirname, "js", testCase);
var options = { entry: { test: "./index.js" } };
var configFile = path.join(testDirectory, "webpack.config.js");
if(fs.existsSync(configFile))
options = require(configFile);
options.context = testDirectory;
if(!options.module) options.module = {};
if(!options.module.loaders) options.module.loaders = [
{ test: /\.txt$/, loader: ExtractTextPlugin.extract("raw-loader") }
];
if(!options.output) options.output = { filename: "[name].js" };
if(!options.output.path) options.output.path = outputDirectory;
if(process.env.CASES) {
console.log("\nwebpack." + testCase + ".config.js " + JSON.stringify(options, null, 2));
}
webpack(options, function(err, stats) {
if(err) return done(err);
if(stats.hasErrors()) return done(new Error(stats.toString()));
var testFile = path.join(outputDirectory, "test.js");
if(fs.existsSync(testFile))
require(testFile)(suite);
var expectedDirectory = path.join(testDirectory, "expected");
fs.readdirSync(expectedDirectory).forEach(function(file) {
var filePath = path.join(expectedDirectory, file);
var actualPath = path.join(outputDirectory, file);
readFileOrEmpty(actualPath).should.be.eql(
readFileOrEmpty(filePath),
file + " should be correct");
function test() {
var options = { entry: { test: "./index.js" } };
var configFile = path.join(testDirectory, "webpack.config.js");
if (fs.existsSync(configFile))
options = require(configFile);
options.context = testDirectory;
if (!options.module) options.module = {};
if (!options.module.loaders) options.module.loaders = [
{ test: /\.txt$/, loader: ExtractTextPlugin.extract("raw-loader") }
];
if (!options.output) options.output = { filename: "[name].js" };
if (!options.output.path) options.output.path = outputDirectory;
if (process.env.CASES) {
console.log("\nwebpack." + testCase + ".config.js " + JSON.stringify(options, null, 2));
}
webpack(options, function (err, stats) {
if (err) return done(err);
if (stats.hasErrors()) return done(new Error(stats.toString()));
var testFile = path.join(outputDirectory, "test.js");
if (fs.existsSync(testFile))
require(testFile)(suite);
var expectedDirectory = path.join(testDirectory, "expected");
fs.readdirSync(expectedDirectory).forEach(function (file) {
var filePath = path.join(expectedDirectory, file);
var actualPath = path.join(outputDirectory, file);
readFileOrEmpty(actualPath).should.be.eql(
readFileOrEmpty(filePath),
file + " should be correct");
});
done();
});
done();
});
}
rimraf(outputDirectory, test);
});
});
});
Expand Down
3 changes: 3 additions & 0 deletions test/cases/multiple-entries-all-async/default-styles.css
@@ -0,0 +1,3 @@
body {
background: red;
}
2 changes: 2 additions & 0 deletions test/cases/multiple-entries-all-async/entries/contact.js
@@ -0,0 +1,2 @@
require('../router');
require('../routes/contact');
2 changes: 2 additions & 0 deletions test/cases/multiple-entries-all-async/entries/homepage.js
@@ -0,0 +1,2 @@
require('../router');
require('../routes/homepage');
22 changes: 22 additions & 0 deletions test/cases/multiple-entries-all-async/expected/0.js
@@ -0,0 +1,22 @@
webpackJsonp([0],{

/***/ 2:
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(7);

modules.export = function() {
return 'Route Homepage';
};


/***/ }),

/***/ 7:
/***/ (function(module, exports) {

// removed by extract-text-webpack-plugin

/***/ })

});
22 changes: 22 additions & 0 deletions test/cases/multiple-entries-all-async/expected/1.js
@@ -0,0 +1,22 @@
webpackJsonp([1],{

/***/ 1:
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(6);

modules.export = function() {
return 'Route Contact';
};


/***/ }),

/***/ 6:
/***/ (function(module, exports) {

// removed by extract-text-webpack-plugin

/***/ })

});
9 changes: 9 additions & 0 deletions test/cases/multiple-entries-all-async/expected/contact.css
@@ -0,0 +1,9 @@
body {
background: red;
}
.contact {
color: black;
}
.homepage {
color: black;
}
9 changes: 9 additions & 0 deletions test/cases/multiple-entries-all-async/expected/homepage.css
@@ -0,0 +1,9 @@
body {
background: red;
}
.contact {
color: black;
}
.homepage {
color: black;
}
6 changes: 6 additions & 0 deletions test/cases/multiple-entries-all-async/router.js
@@ -0,0 +1,6 @@
require('./default-styles.css');
module.export = function (route) {
return import(/* webpackChunkName: "route-[request]" */ './routes/' + route + 'index.js').then(function (route) {
return route;
});
};
5 changes: 5 additions & 0 deletions test/cases/multiple-entries-all-async/routes/contact/index.js
@@ -0,0 +1,5 @@
require('./styles.css');

modules.export = function() {
return 'Route Contact';
};
@@ -0,0 +1,3 @@
.contact {
color: black;
}
@@ -0,0 +1,5 @@
require('./styles.css');

modules.export = function() {
return 'Route Homepage';
};
@@ -0,0 +1,3 @@
.homepage {
color: black;
}
23 changes: 23 additions & 0 deletions test/cases/multiple-entries-all-async/webpack.config.js
@@ -0,0 +1,23 @@
var ExtractTextPlugin = require("../../../");
module.exports = {
entry: {
'homepage': "./entries/homepage.js",
'contact': "./entries/contact.js"
},
module: {
loaders: [
{ test: /\.css$/, use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: { loader: "css-loader", options: {
sourceMap: false
} }
}) }
]
},
plugins: [
new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
})
]
};
3 changes: 3 additions & 0 deletions test/cases/multiple-entries-async/default-styles.css
@@ -0,0 +1,3 @@
body {
background: red;
}
2 changes: 2 additions & 0 deletions test/cases/multiple-entries-async/entries/contact.js
@@ -0,0 +1,2 @@
require('../router');
require('../routes/contact');
2 changes: 2 additions & 0 deletions test/cases/multiple-entries-async/entries/homepage.js
@@ -0,0 +1,2 @@
require('../router');
require('../routes/homepage');

0 comments on commit cdfccb4

Please sign in to comment.