diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 00000000..a50c18d3
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,2 @@
+extract-text-webpack-plugin
+node_modules
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/.editorconfig b/extract-text-webpack-plugin/.editorconfig
new file mode 100644
index 00000000..4d3466a5
--- /dev/null
+++ b/extract-text-webpack-plugin/.editorconfig
@@ -0,0 +1,17 @@
+# EditorConfig is awesome: http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = tab
+indent_size = 4
+
+# Matches the exact files either package.json or .travis.yml
+[{package.json,.travis.yml}]
+indent_style = space
+indent_size = 2
diff --git a/extract-text-webpack-plugin/.eslintrc b/extract-text-webpack-plugin/.eslintrc
new file mode 100644
index 00000000..e325bf44
--- /dev/null
+++ b/extract-text-webpack-plugin/.eslintrc
@@ -0,0 +1,12 @@
+{
+ "env": {
+ "node": true
+ },
+ "rules": {
+ "strict": 0,
+ "curly": 0,
+ "quotes": 0,
+ "no-shadow": 0,
+ "no-underscore-dangle": 0
+ }
+}
diff --git a/extract-text-webpack-plugin/.gitattributes b/extract-text-webpack-plugin/.gitattributes
new file mode 100644
index 00000000..176a458f
--- /dev/null
+++ b/extract-text-webpack-plugin/.gitattributes
@@ -0,0 +1 @@
+* text=auto
diff --git a/extract-text-webpack-plugin/.github/ISSUE_TEMPLATE.md b/extract-text-webpack-plugin/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 00000000..04348540
--- /dev/null
+++ b/extract-text-webpack-plugin/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,5 @@
+1. Check the version of package you are using. If it's not the newest version, update and try again (see changelog while updating!).
+2. If the issue is still there, write a minimal project showing the problem and expected output.
+3. Link to the project and mention Node version and OS in your report.
+
+**IMPORTANT! You should use [Stack Overflow](https://stackoverflow.com/) for support related questions.**
diff --git a/extract-text-webpack-plugin/.github/PULL_REQUEST_TEMPLATE.md b/extract-text-webpack-plugin/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000..f0c0b39c
--- /dev/null
+++ b/extract-text-webpack-plugin/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,4 @@
+1. [Read and sign the CLA](https://cla.js.foundation/webpack/webpack.js.org). This needs to be done only once. PRs that haven't signed it won't be accepted.
+2. Check out the [development guide](https://webpack.js.org/development/) for the API and development guidelines.
+3. Read through the PR diff carefully as sometimes this can reveal issues. The work will be reviewed, but this can save some effort.
+4. Remove these instructions from your PR as they are for your eyes only.
diff --git a/extract-text-webpack-plugin/.gitignore b/extract-text-webpack-plugin/.gitignore
new file mode 100644
index 00000000..fbc409e4
--- /dev/null
+++ b/extract-text-webpack-plugin/.gitignore
@@ -0,0 +1,10 @@
+/node_modules
+
+/example/assets
+
+/test/js
+/coverage
+
+/.idea
+
+.DS_Store
diff --git a/extract-text-webpack-plugin/.travis.yml b/extract-text-webpack-plugin/.travis.yml
new file mode 100644
index 00000000..42ae6c8d
--- /dev/null
+++ b/extract-text-webpack-plugin/.travis.yml
@@ -0,0 +1,12 @@
+sudo: false
+language: node_js
+node_js:
+ - node
+ - 6
+ - 4
+script: npm run travis
+
+after_success:
+ - cat ./coverage/lcov.info | node_modules/.bin/coveralls --verbose
+ - cat ./coverage/coverage.json | node_modules/codecov.io/bin/codecov.io.js
+ - rm -rf ./coverage
diff --git a/extract-text-webpack-plugin/CHANGELOG.md b/extract-text-webpack-plugin/CHANGELOG.md
new file mode 100644
index 00000000..0b6ec15f
--- /dev/null
+++ b/extract-text-webpack-plugin/CHANGELOG.md
@@ -0,0 +1,77 @@
+# Change Log
+
+All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+
+
+## [2.1.2](https://github.com/webpack-contrib/extract-text-webpack-plugin/compare/v2.1.1...v2.1.2) (2017-06-08)
+
+
+
+
+## [2.1.1](https://github.com/webpack-contrib/extract-text-webpack-plugin/compare/v2.1.0...v2.1.1) (2017-06-08)
+
+
+### Bug Fixes
+
+* add a not null check for the content property before throwing error ([#404](https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/404)) ([58dd5d3](https://github.com/webpack-contrib/extract-text-webpack-plugin/commit/58dd5d3))
+* **loader:** rm unnecessary `this.cacheable` (caching) ([#530](https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/530)) ([c3cb091](https://github.com/webpack-contrib/extract-text-webpack-plugin/commit/c3cb091))
+* don't extract from common async chunks ([#508](https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/508)) ([e595417](https://github.com/webpack-contrib/extract-text-webpack-plugin/commit/e595417))
+* validation schema (`schema-utils`) ([#527](https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/527)) ([dfeb347](https://github.com/webpack-contrib/extract-text-webpack-plugin/commit/dfeb347))
+
+
+
+
+# [2.1.0](https://github.com/webpack/extract-text-webpack-plugin/compare/v2.0.0...v2.1.0) (2017-03-05)
+
+### Features
+
+* The plugin **filename** accepts a function now. [c9a19ad](https://github.com/webpack-contrib/extract-text-webpack-plugin/commit/c9a19ad), closes [#423](https://github.com/webpack-contrib/extract-text-webpack-plugin/pull/423)
+
+
+# [2.0.0](https://github.com/webpack/extract-text-webpack-plugin/compare/v2.0.0-rc.3...v2.0.0) (2017-02-24)
+
+
+# [2.0.0-rc.2](https://github.com/webpack/extract-text-webpack-plugin/compare/v2.0.0-rc.1...v2.0.0-rc.2) (2017-01-28)
+
+
+### Bug Fixes
+
+* **schema:** allow `extract` to accept omit/remove flags ([8ce93d5](https://github.com/webpack/extract-text-webpack-plugin/commit/8ce93d5)), closes [#371](https://github.com/webpack/extract-text-webpack-plugin/issues/371)
+* **schema:** connect loader schema with the code properly ([03bb4aa](https://github.com/webpack/extract-text-webpack-plugin/commit/03bb4aa))
+* **schema:** emit proper error messages ([70cbd4b](https://github.com/webpack/extract-text-webpack-plugin/commit/70cbd4b))
+
+
+### Features
+
+* **errors:** show nicer errors if there are extra fields ([76a171d](https://github.com/webpack/extract-text-webpack-plugin/commit/76a171d))
+
+
+
+
+# [2.0.0-rc.1](https://github.com/webpack/extract-text-webpack-plugin/compare/v2.0.0-rc.0...v2.0.0-rc.1) (2017-01-28)
+
+
+### Bug Fixes
+
+* **options:** pass proper loader options to children ([#266](https://github.com/webpack/extract-text-webpack-plugin/issues/266)) ([6abf42d](https://github.com/webpack/extract-text-webpack-plugin/commit/6abf42d))
+
+
+
+
+# [2.0.0-rc.0](https://github.com/webpack/extract-text-webpack-plugin/compare/v2.0.0-beta.5...v2.0.0-rc.0) (2017-01-26)
+
+
+### Bug Fixes
+
+* **readme:** Incorrect loader configuration ([e477cc7](https://github.com/webpack/extract-text-webpack-plugin/commit/e477cc7))
+
+
+### Features
+
+* **extract:** return an array of loader objects ([#343](https://github.com/webpack/extract-text-webpack-plugin/issues/343)) ([74b86e0](https://github.com/webpack/extract-text-webpack-plugin/commit/74b86e0))
+
+
+
+# Change Log
+
+All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
diff --git a/extract-text-webpack-plugin/ExtractedModule.js b/extract-text-webpack-plugin/ExtractedModule.js
new file mode 100644
index 00000000..38207a8d
--- /dev/null
+++ b/extract-text-webpack-plugin/ExtractedModule.js
@@ -0,0 +1,70 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+var SourceMapSource = require("webpack-sources").SourceMapSource;
+var RawSource = require("webpack-sources").RawSource;
+
+function ExtractedModule(identifier, originalModule, source, sourceMap, addtitionalInformation, prevModules) {
+ this._identifier = identifier;
+ this._originalModule = originalModule;
+ this._source = source;
+ this._sourceMap = sourceMap;
+ this._prevModules = prevModules;
+ this.addtitionalInformation = addtitionalInformation;
+ this.chunks = [];
+}
+module.exports = ExtractedModule;
+
+ExtractedModule.prototype.getOrder = function() {
+ // http://stackoverflow.com/a/14676665/1458162
+ return /^@import url/.test(this._source) ? 0 : 1;
+};
+
+ExtractedModule.prototype.addChunk = function(chunk) {
+ var idx = this.chunks.indexOf(chunk);
+ if(idx < 0)
+ this.chunks.push(chunk);
+};
+
+ExtractedModule.prototype.removeChunk = function(chunk) {
+ var idx = this.chunks.indexOf(chunk);
+ if(idx >= 0) {
+ this.chunks.splice(idx, 1);
+ chunk.removeModule(this);
+ return true;
+ }
+ return false;
+};
+
+ExtractedModule.prototype.rewriteChunkInReasons = function(oldChunk, newChunks) { };
+
+ExtractedModule.prototype.identifier = function() {
+ return this._identifier;
+};
+
+ExtractedModule.prototype.source = function() {
+ if(this._sourceMap)
+ return new SourceMapSource(this._source, null, this._sourceMap);
+ else
+ return new RawSource(this._source);
+};
+
+ExtractedModule.prototype.getOriginalModule = function() {
+ return this._originalModule;
+};
+
+ExtractedModule.prototype.getPrevModules = function() {
+ return this._prevModules;
+};
+
+ExtractedModule.prototype.addPrevModules = function(prevModules) {
+ prevModules.forEach(function(m) {
+ if(this._prevModules.indexOf(m) < 0)
+ this._prevModules.push(m);
+ }, this);
+};
+
+ExtractedModule.prototype.setOriginalModule = function(originalModule) {
+ this._originalModule = originalModule;
+};
diff --git a/extract-text-webpack-plugin/LICENSE b/extract-text-webpack-plugin/LICENSE
new file mode 100644
index 00000000..8c11fc72
--- /dev/null
+++ b/extract-text-webpack-plugin/LICENSE
@@ -0,0 +1,20 @@
+Copyright JS Foundation and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/extract-text-webpack-plugin/OrderUndefinedError.js b/extract-text-webpack-plugin/OrderUndefinedError.js
new file mode 100644
index 00000000..cedec9a3
--- /dev/null
+++ b/extract-text-webpack-plugin/OrderUndefinedError.js
@@ -0,0 +1,14 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+function OrderUndefinedError(module) {
+ Error.call(this);
+ Error.captureStackTrace(this, OrderUndefinedError);
+ this.name = "OrderUndefinedError";
+ this.message = "Order in extracted chunk undefined";
+ this.module = module;
+}
+module.exports = OrderUndefinedError;
+
+OrderUndefinedError.prototype = Object.create(Error.prototype);
diff --git a/extract-text-webpack-plugin/README.md b/extract-text-webpack-plugin/README.md
new file mode 100644
index 00000000..56b607b5
--- /dev/null
+++ b/extract-text-webpack-plugin/README.md
@@ -0,0 +1,228 @@
+[![npm][npm]][npm-url]
+[![node][node]][node-url]
+[![deps][deps]][deps-url]
+[![tests][tests]][tests-url]
+[![coverage][cover]][cover-url]
+[![chat][chat]][chat-url]
+
+
+
+
+
+
+
Extract Text Plugin
+
Extract text from a bundle, or bundles, into a separate file.
+
+
+Install
+
+```bash
+# for webpack 2
+npm install --save-dev extract-text-webpack-plugin
+# for webpack 1
+npm install --save-dev extract-text-webpack-plugin@1.0.1
+```
+
+Usage
+
+> :warning: For webpack v1, see [the README in the webpack-1 branch](https://github.com/webpack/extract-text-webpack-plugin/blob/webpack-1/README.md).
+
+```js
+const ExtractTextPlugin = require("extract-text-webpack-plugin");
+
+module.exports = {
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ use: ExtractTextPlugin.extract({
+ fallback: "style-loader",
+ use: "css-loader"
+ })
+ }
+ ]
+ },
+ plugins: [
+ new ExtractTextPlugin("styles.css"),
+ ]
+}
+```
+
+It moves all the required `*.css` modules in entry chunks into a separate CSS file. So your styles are no longer inlined into the JS bundle, but in a separate CSS file (`styles.css`). If your total stylesheet volume is big, it will be faster because the CSS bundle is loaded in parallel to the JS bundle.
+
+|Advantages|Caveats|
+|:---------|:------|
+| Fewer style tags (older IE has a limit) | Additional HTTP request |
+| CSS SourceMap (with `devtool: "source-map"` and `extract-text-webpack-plugin?sourceMap`) | Longer compilation time |
+| CSS requested in parallel | No runtime public path modification |
+| CSS cached separate | No Hot Module Replacement |
+| Faster runtime (less code and DOM operations) | ... |
+
+Options
+
+```js
+new ExtractTextPlugin(options: filename | object)
+```
+
+|Name|Type|Description|
+|:--:|:--:|:----------|
+|**`id`**|`{String}`|Unique ident for this plugin instance. (For advanced usage only, by default automatically generated)|
+|**`filename`**|`{String\|Function}`|Name of the result file. May contain `[name]`, `[id]` and `[contenthash]`|
+|**`allChunks`**|`{Boolean}`|Extract from all additional chunks too (by default it extracts only from the initial chunk(s)) When using `CommonsChunkPlugin` and there are extracted chunks (from `ExtractTextPlugin.extract`) in the commons chunk, `allChunks` **must** be set to `true`|
+|**`disable`**|`{Boolean}`|Disables the plugin|
+|**`ignoreOrder`**|`{Boolean}`|Disables order check (useful for CSS Modules!), `false` by default|
+
+* `[name]` name of the chunk
+* `[id]` number of the chunk
+* `[contenthash]` hash of the content of the extracted file
+
+> :warning: `ExtractTextPlugin` generates a file **per entry**, so you must use `[name]`, `[id]` or `[contenthash]` when using multiple entries.
+
+#### `#extract`
+
+```js
+ExtractTextPlugin.extract(options: loader | object)
+```
+
+Creates an extracting loader from an existing loader. Supports loaders of type `{ loader: [name]-loader -> {String}, options: {} -> {Object} }`.
+
+|Name|Type|Description|
+|:--:|:--:|:----------|
+|**`options.use`**|`{String}`/`{Array}`/`{Object}`|Loader(s) that should be used for converting the resource to a CSS exporting module _(required)_|
+|**`options.fallback`**|`{String}`/`{Array}`/`{Object}`|loader(e.g `'style-loader'`) that should be used when the CSS is not extracted (i.e. in an additional chunk when `allChunks: false`)|
+|**`options.publicPath`**|`{String}`|Override the `publicPath` setting for this loader|
+
+
+#### Multiple Instances
+
+There is also an `extract` function on the instance. You should use this if you have more than one instance of `ExtractTextPlugin`.
+
+```js
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+
+// Create multiple instances
+const extractCSS = new ExtractTextPlugin('stylesheets/[name]-one.css');
+const extractLESS = new ExtractTextPlugin('stylesheets/[name]-two.css');
+
+module.exports = {
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ use: extractCSS.extract([ 'css-loader', 'postcss-loader' ])
+ },
+ {
+ test: /\.less$/i,
+ use: extractLESS.extract([ 'css-loader', 'less-loader' ])
+ },
+ ]
+ },
+ plugins: [
+ extractCSS,
+ extractLESS
+ ]
+};
+```
+
+### Extracting Sass or LESS
+
+The configuration is the same, switch out `sass-loader` for `less-loader` when necessary.
+
+```js
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+
+module.exports = {
+ module: {
+ rules: [
+ {
+ test: /\.scss$/,
+ use: ExtractTextPlugin.extract({
+ fallback: 'style-loader',
+ //resolve-url-loader may be chained before sass-loader if necessary
+ use: ['css-loader', 'sass-loader']
+ })
+ }
+ ]
+ },
+ plugins: [
+ new ExtractTextPlugin('style.css')
+ //if you want to pass in options, you can do so:
+ //new ExtractTextPlugin({
+ // filename: 'style.css'
+ //})
+ ]
+}
+```
+
+### Modify filename
+
+`filename` parameter could be `Function`. It passes `getPath` to process the format like `css/[name].css` and returns the real file name, `css/js/a.css`. You can replace `css/js` with `css` then you will get the new path `css/a.css`.
+
+
+```js
+entry: {
+ 'js/a': "./a"
+},
+plugins: [
+ new ExtractTextPlugin({
+ filename: (getPath) => {
+ return getPath('css/[name].css').replace('css/js', 'css');
+ },
+ allChunks: true
+ })
+]
+```
+
+Maintainers
+
+
+
+
+[npm]: https://img.shields.io/npm/v/extract-text-webpack-plugin.svg
+[npm-url]: https://npmjs.com/package/extract-text-webpack-plugin
+
+[node]: https://img.shields.io/node/v/extract-text-webpack-plugin.svg
+[node-url]: https://nodejs.org
+
+[deps]: https://david-dm.org/webpack-contrib/extract-text-webpack-plugin.svg
+[deps-url]: https://david-dm.org/webpack-contrib/extract-text-webpack-plugin
+
+[tests]: http://img.shields.io/travis/webpack-contrib/extract-text-webpack-plugin.svg
+[tests-url]: https://travis-ci.org/webpack-contrib/extract-text-webpack-plugin
+
+[cover]: https://coveralls.io/repos/github/webpack-contrib/extract-text-webpack-plugin/badge.svg
+[cover-url]: https://coveralls.io/github/webpack-contrib/extract-text-webpack-plugin
+
+[chat]: https://badges.gitter.im/webpack/webpack.svg
+[chat-url]: https://gitter.im/webpack/webpack
diff --git a/extract-text-webpack-plugin/example/base.css b/extract-text-webpack-plugin/example/base.css
new file mode 100644
index 00000000..9e5f03af
--- /dev/null
+++ b/extract-text-webpack-plugin/example/base.css
@@ -0,0 +1,6 @@
+@import url(http://this.should.be/in/c);
+@import url("http://this.should.also.be/in/c");
+body {
+ border: 1px solid black;
+ correct: c;
+}
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/common.css b/extract-text-webpack-plugin/example/common.css
new file mode 100644
index 00000000..583225c3
--- /dev/null
+++ b/extract-text-webpack-plugin/example/common.css
@@ -0,0 +1,5 @@
+@import url(http://this.should.be/in/c);
+body {
+ height: 100%;
+ correct: c;
+}
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/dep.js b/extract-text-webpack-plugin/example/dep.js
new file mode 100644
index 00000000..990fd60b
--- /dev/null
+++ b/extract-text-webpack-plugin/example/dep.js
@@ -0,0 +1,2 @@
+require("./style2.css");
+require(["./dep2"]);
diff --git a/extract-text-webpack-plugin/example/dep2.js b/extract-text-webpack-plugin/example/dep2.js
new file mode 100644
index 00000000..4e3bbdfe
--- /dev/null
+++ b/extract-text-webpack-plugin/example/dep2.js
@@ -0,0 +1 @@
+require("./style3.css");
diff --git a/extract-text-webpack-plugin/example/entry.js b/extract-text-webpack-plugin/example/entry.js
new file mode 100644
index 00000000..64a8dcae
--- /dev/null
+++ b/extract-text-webpack-plugin/example/entry.js
@@ -0,0 +1,3 @@
+require("./common.css");
+require("./style.css");
+require("./dep");
diff --git a/extract-text-webpack-plugin/example/entry2.js b/extract-text-webpack-plugin/example/entry2.js
new file mode 100644
index 00000000..ebfece3a
--- /dev/null
+++ b/extract-text-webpack-plugin/example/entry2.js
@@ -0,0 +1,4 @@
+require("./common.css");
+require("./style4.css");
+require("./style6.css");
+require("./style5.css");
diff --git a/extract-text-webpack-plugin/example/image.png b/extract-text-webpack-plugin/example/image.png
new file mode 100644
index 00000000..818c71d0
Binary files /dev/null and b/extract-text-webpack-plugin/example/image.png differ
diff --git a/extract-text-webpack-plugin/example/index.html b/extract-text-webpack-plugin/example/index.html
new file mode 100644
index 00000000..4944044f
--- /dev/null
+++ b/extract-text-webpack-plugin/example/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/style.css b/extract-text-webpack-plugin/example/style.css
new file mode 100644
index 00000000..7f728b77
--- /dev/null
+++ b/extract-text-webpack-plugin/example/style.css
@@ -0,0 +1,5 @@
+@import "base.css";
+body {
+ background: url(image.png);
+ correct: a;
+}
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/style2.css b/extract-text-webpack-plugin/example/style2.css
new file mode 100644
index 00000000..19b5d431
--- /dev/null
+++ b/extract-text-webpack-plugin/example/style2.css
@@ -0,0 +1,6 @@
+@import "base.css";
+@import "style3.css";
+body {
+ color: red;
+ correct: a;
+}
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/style3.css b/extract-text-webpack-plugin/example/style3.css
new file mode 100644
index 00000000..fb3f9977
--- /dev/null
+++ b/extract-text-webpack-plugin/example/style3.css
@@ -0,0 +1,5 @@
+@import url(http://this.should.be/in/a);
+.xyz {
+ color: url(image.png);
+ correct: a;
+}
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/style4.css b/extract-text-webpack-plugin/example/style4.css
new file mode 100644
index 00000000..5520e813
--- /dev/null
+++ b/extract-text-webpack-plugin/example/style4.css
@@ -0,0 +1,6 @@
+@import "base.css";
+.secondary {
+ order: 0;
+ color: url(image.png);
+ correct: b;
+}
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/style5.1.css b/extract-text-webpack-plugin/example/style5.1.css
new file mode 100644
index 00000000..a74d76fc
--- /dev/null
+++ b/extract-text-webpack-plugin/example/style5.1.css
@@ -0,0 +1,4 @@
+body {
+ order: 2;
+ correct: b;
+}
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/style5.2.css b/extract-text-webpack-plugin/example/style5.2.css
new file mode 100644
index 00000000..04aa0924
--- /dev/null
+++ b/extract-text-webpack-plugin/example/style5.2.css
@@ -0,0 +1,4 @@
+body {
+ order: 3;
+ correct: b;
+}
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/style5.css b/extract-text-webpack-plugin/example/style5.css
new file mode 100644
index 00000000..d51d385d
--- /dev/null
+++ b/extract-text-webpack-plugin/example/style5.css
@@ -0,0 +1,6 @@
+@import "style5.1.css";
+@import "style5.2.css";
+body {
+ order: 4;
+ correct: b;
+}
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/style6.css b/extract-text-webpack-plugin/example/style6.css
new file mode 100644
index 00000000..14dc5a22
--- /dev/null
+++ b/extract-text-webpack-plugin/example/style6.css
@@ -0,0 +1,4 @@
+body {
+ order: 1;
+ correct: b;
+}
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/example/webpack.config.js b/extract-text-webpack-plugin/example/webpack.config.js
new file mode 100644
index 00000000..89119c9f
--- /dev/null
+++ b/extract-text-webpack-plugin/example/webpack.config.js
@@ -0,0 +1,38 @@
+var webpack = require("webpack");
+var ExtractTextPlugin = require("../");
+module.exports = {
+ entry: {
+ a: "./entry.js",
+ b: "./entry2.js"
+ },
+ output: {
+ filename: "[name].js?[hash]-[chunkhash]",
+ chunkFilename: "[name].js?[hash]-[chunkhash]",
+ path: __dirname + "/assets",
+ publicPath: "/assets/"
+ },
+ module: {
+ loaders: [
+ { test: /\.css$/, use: ExtractTextPlugin.extract({
+ fallback: "style-loader",
+ use: {
+ loader: "css-loader",
+ options: {
+ sourceMap: true
+ }
+ },
+ publicPath: "../"
+ }) },
+ { test: /\.png$/, loader: "file-loader" }
+ ]
+ },
+ devtool: "source-map",
+ plugins: [
+ new ExtractTextPlugin({
+ filename: "css/[name].css?[hash]-[chunkhash]-[contenthash]-[name]",
+ disable: false,
+ allChunks: true
+ }),
+ new webpack.optimize.CommonsChunkPlugin({ name: "c", filename: "c.js" })
+ ]
+};
diff --git a/extract-text-webpack-plugin/index.js b/extract-text-webpack-plugin/index.js
new file mode 100644
index 00000000..816a7d2c
--- /dev/null
+++ b/extract-text-webpack-plugin/index.js
@@ -0,0 +1,355 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+process.noDeprecation = true;
+
+var fs = require('fs');
+var ConcatSource = require("webpack-sources").ConcatSource;
+var async = require("async");
+var ExtractedModule = require("./ExtractedModule");
+var Chunk = require("webpack/lib/Chunk");
+var OrderUndefinedError = require("./OrderUndefinedError");
+var loaderUtils = require("loader-utils");
+var validateOptions = require('schema-utils');
+var path = require('path');
+
+var NS = fs.realpathSync(__dirname);
+
+var nextId = 0;
+
+function ExtractTextPluginCompilation() {
+ this.modulesByIdentifier = {};
+}
+
+function isInitialOrHasNoParents(chunk) {
+ return chunk.isInitial() || chunk.parents.length === 0;
+}
+
+ExtractTextPlugin.prototype.mergeNonInitialChunks = function(chunk, intoChunk, checkedChunks) {
+ if(!intoChunk) {
+ checkedChunks = [];
+ chunk.chunks.forEach(function(c) {
+ if(isInitialOrHasNoParents(c)) return;
+ this.mergeNonInitialChunks(c, chunk, checkedChunks);
+ }, this);
+ } else if(checkedChunks.indexOf(chunk) < 0) {
+ checkedChunks.push(chunk);
+ chunk.modules.slice().forEach(function(module) {
+ intoChunk.addModule(module);
+ module.addChunk(intoChunk);
+ });
+ chunk.chunks.forEach(function(c) {
+ if(isInitialOrHasNoParents(c)) return;
+ this.mergeNonInitialChunks(c, intoChunk, checkedChunks);
+ }, this);
+ }
+};
+
+ExtractTextPluginCompilation.prototype.addModule = function(identifier, originalModule, source, additionalInformation, sourceMap, prevModules) {
+ var m;
+ if(!this.modulesByIdentifier[identifier]) {
+ m = this.modulesByIdentifier[identifier] = new ExtractedModule(identifier, originalModule, source, sourceMap, additionalInformation, prevModules);
+ } else {
+ m = this.modulesByIdentifier[identifier];
+ m.addPrevModules(prevModules);
+ if(originalModule.index2 < m.getOriginalModule().index2) {
+ m.setOriginalModule(originalModule);
+ }
+ }
+ return m;
+};
+
+ExtractTextPluginCompilation.prototype.addResultToChunk = function(identifier, result, originalModule, extractedChunk) {
+ if(!Array.isArray(result)) {
+ result = [[identifier, result]];
+ }
+ var counterMap = {};
+ var prevModules = [];
+ result.forEach(function(item) {
+ var c = counterMap[item[0]];
+ var module = this.addModule.call(this, item[0] + (c || ""), originalModule, item[1], item[2], item[3], prevModules.slice());
+ extractedChunk.addModule(module);
+ module.addChunk(extractedChunk);
+ counterMap[item[0]] = (c || 0) + 1;
+ prevModules.push(module);
+ }, this);
+};
+
+ExtractTextPlugin.prototype.renderExtractedChunk = function(chunk) {
+ var source = new ConcatSource();
+ chunk.modules.forEach(function(module) {
+ var moduleSource = module.source();
+ source.add(this.applyAdditionalInformation(moduleSource, module.additionalInformation));
+ }, this);
+ return source;
+};
+
+function isInvalidOrder(a, b) {
+ var bBeforeA = a.getPrevModules().indexOf(b) >= 0;
+ var aBeforeB = b.getPrevModules().indexOf(a) >= 0;
+ return aBeforeB && bBeforeA;
+}
+
+function getOrder(a, b) {
+ var aOrder = a.getOrder();
+ var bOrder = b.getOrder();
+ if(aOrder < bOrder) return -1;
+ if(aOrder > bOrder) return 1;
+ var aIndex = a.getOriginalModule().index2;
+ var bIndex = b.getOriginalModule().index2;
+ if(aIndex < bIndex) return -1;
+ if(aIndex > bIndex) return 1;
+ var bBeforeA = a.getPrevModules().indexOf(b) >= 0;
+ var aBeforeB = b.getPrevModules().indexOf(a) >= 0;
+ if(aBeforeB && !bBeforeA) return -1;
+ if(!aBeforeB && bBeforeA) return 1;
+ var ai = a.identifier();
+ var bi = b.identifier();
+ if(ai < bi) return -1;
+ if(ai > bi) return 1;
+ return 0;
+}
+
+function ExtractTextPlugin(options) {
+ if(arguments.length > 1) {
+ throw new Error("Breaking change: ExtractTextPlugin now only takes a single argument. Either an options " +
+ "object *or* the name of the result file.\n" +
+ "Example: if your old code looked like this:\n" +
+ " new ExtractTextPlugin('css/[name].css', { disable: false, allChunks: true })\n\n" +
+ "You would change it to:\n" +
+ " new ExtractTextPlugin({ filename: 'css/[name].css', disable: false, allChunks: true })\n\n" +
+ "The available options are:\n" +
+ " filename: string\n" +
+ " allChunks: boolean\n" +
+ " disable: boolean\n");
+ }
+ if(isString(options)) {
+ options = { filename: options };
+ } else {
+ validateOptions(path.resolve(__dirname, './schema/plugin.json'), options, 'Extract Text Plugin');
+ }
+ this.filename = options.filename;
+ this.id = options.id != null ? options.id : ++nextId;
+ this.options = {};
+ mergeOptions(this.options, options);
+ delete this.options.filename;
+ delete this.options.id;
+}
+module.exports = ExtractTextPlugin;
+
+function getLoaderObject(loader) {
+ if (isString(loader)) {
+ return {loader: loader};
+ }
+ return loader;
+}
+
+function mergeOptions(a, b) {
+ if(!b) return a;
+ Object.keys(b).forEach(function(key) {
+ a[key] = b[key];
+ });
+ return a;
+}
+
+function isString(a) {
+ return typeof a === "string";
+}
+
+function isFunction(a) {
+ return isType('Function', a);
+}
+
+function isType(type, obj) {
+ return Object.prototype.toString.call(obj) === '[object ' + type + ']';
+}
+
+ExtractTextPlugin.loader = function(options) {
+ return { loader: require.resolve("./loader"), options: options };
+};
+
+ExtractTextPlugin.prototype.applyAdditionalInformation = function(source, info) {
+ if(info) {
+ return new ConcatSource(
+ "@media " + info[0] + " {",
+ source,
+ "}"
+ );
+ }
+ return source;
+};
+
+ExtractTextPlugin.prototype.loader = function(options) {
+ return ExtractTextPlugin.loader(mergeOptions({id: this.id}, 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");
+ }
+ if(options.fallbackLoader) {
+ console.warn('fallbackLoader option has been deprecated - replace with "fallback"');
+ }
+ if(options.loader) {
+ console.warn('loader option has been deprecated - replace with "use"');
+ }
+ if(Array.isArray(options) || isString(options) || typeof options.options === "object" || typeof options.query === 'object') {
+ options = { loader: options };
+ } else {
+ validateOptions(path.resolve(__dirname, './schema/loader.json'), options, 'Extract Text Plugin (Loader)');
+ }
+ var loader = options.use || options.loader;
+ var before = options.fallback || options.fallbackLoader || [];
+ if(isString(loader)) {
+ loader = loader.split("!");
+ }
+ if(isString(before)) {
+ before = before.split("!");
+ } else if(!Array.isArray(before)) {
+ before = [before];
+ }
+ options = mergeOptions({omit: before.length, remove: true}, options);
+ delete options.loader;
+ delete options.use;
+ delete options.fallback;
+ delete options.fallbackLoader;
+ 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();
+ compilation.plugin("normal-module-loader", function(loaderContext, module) {
+ loaderContext[NS] = function(content, opt) {
+ if(options.disable)
+ return false;
+ if(!Array.isArray(content) && content != null)
+ throw new Error("Exported value was not extracted as an array: " + JSON.stringify(content));
+ module[NS] = {
+ content: content,
+ options: opt || {}
+ };
+ return options.allChunks || module[NS + "/extract"]; // eslint-disable-line no-path-concat
+ };
+ });
+ var filename = this.filename;
+ var id = this.id;
+ var extractedChunks, entryChunks, initialChunks;
+ compilation.plugin("optimize-tree", function(chunks, modules, callback) {
+ extractedChunks = chunks.map(function() {
+ return new Chunk();
+ });
+ chunks.forEach(function(chunk, i) {
+ var extractedChunk = extractedChunks[i];
+ extractedChunk.index = i;
+ extractedChunk.originalChunk = chunk;
+ extractedChunk.name = chunk.name;
+ extractedChunk.entrypoints = chunk.entrypoints;
+ chunk.chunks.forEach(function(c) {
+ extractedChunk.addChunk(extractedChunks[chunks.indexOf(c)]);
+ });
+ chunk.parents.forEach(function(c) {
+ extractedChunk.addParent(extractedChunks[chunks.indexOf(c)]);
+ });
+ });
+ async.forEach(chunks, function(chunk, callback) {
+ var extractedChunk = extractedChunks[chunks.indexOf(chunk)];
+ var shouldExtract = !!(options.allChunks || isInitialOrHasNoParents(chunk));
+ async.forEach(chunk.modules.slice(), function(module, callback) {
+ var meta = module[NS];
+ 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) {
+ if(err) {
+ compilation.errors.push(err);
+ return callback();
+ }
+ meta = module[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");
+ compilation.errors.push(err);
+ return callback();
+ }
+ if(meta.content)
+ extractCompilation.addResultToChunk(module.identifier(), meta.content, module, extractedChunk);
+ callback();
+ });
+ } else {
+ if(meta.content)
+ extractCompilation.addResultToChunk(module.identifier(), meta.content, module, extractedChunk);
+ callback();
+ }
+ } else callback();
+ }, function(err) {
+ if(err) return callback(err);
+ callback();
+ });
+ }, function(err) {
+ if(err) return callback(err);
+ extractedChunks.forEach(function(extractedChunk) {
+ if(isInitialOrHasNoParents(extractedChunk))
+ this.mergeNonInitialChunks(extractedChunk);
+ }, this);
+ extractedChunks.forEach(function(extractedChunk) {
+ if(!isInitialOrHasNoParents(extractedChunk)) {
+ extractedChunk.modules.slice().forEach(function(module) {
+ extractedChunk.removeModule(module);
+ });
+ }
+ });
+ compilation.applyPlugins("optimize-extracted-chunks", extractedChunks);
+ callback();
+ }.bind(this));
+ }.bind(this));
+ compilation.plugin("additional-assets", function(callback) {
+ extractedChunks.forEach(function(extractedChunk) {
+ if(extractedChunk.modules.length) {
+ // HACK: Fix the CSS ordering issue present in 2.1.2 without needing to move to
+ // version 3.0.0 which breaks reloading in webpack-dev-server.
+ // See:
+ // https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/548
+ // https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/579
+ extractedChunk.modules = extractedChunk.modules.sort(function(a, b) {
+ if(!options.ignoreOrder && isInvalidOrder(a, b)) {
+ compilation.errors.push(new OrderUndefinedError(a.getOriginalModule()));
+ compilation.errors.push(new OrderUndefinedError(b.getOriginalModule()));
+ }
+ return getOrder(a, b);
+ });
+ var chunk = extractedChunk.originalChunk;
+ var source = this.renderExtractedChunk(extractedChunk);
+
+ var getPath = (format) => compilation.getPath(format, {
+ chunk: chunk
+ }).replace(/\[(?:(\w+):)?contenthash(?::([a-z]+\d*))?(?::(\d+))?\]/ig, function() {
+ return loaderUtils.getHashDigest(source.source(), arguments[1], arguments[2], parseInt(arguments[3], 10));
+ });
+
+ var file = (isFunction(filename)) ? filename(getPath) : getPath(filename);
+
+ compilation.assets[file] = source;
+ chunk.files.push(file);
+ }
+ }, this);
+ callback();
+ }.bind(this));
+ }.bind(this));
+};
diff --git a/extract-text-webpack-plugin/loader.js b/extract-text-webpack-plugin/loader.js
new file mode 100644
index 00000000..06e649e1
--- /dev/null
+++ b/extract-text-webpack-plugin/loader.js
@@ -0,0 +1,133 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+var fs = require("fs");
+var loaderUtils = require("loader-utils");
+var NodeTemplatePlugin = require("webpack/lib/node/NodeTemplatePlugin");
+var NodeTargetPlugin = require("webpack/lib/node/NodeTargetPlugin");
+var LibraryTemplatePlugin = require("webpack/lib/LibraryTemplatePlugin");
+var SingleEntryPlugin = require("webpack/lib/SingleEntryPlugin");
+var LimitChunkCountPlugin = require("webpack/lib/optimize/LimitChunkCountPlugin");
+
+var NS = fs.realpathSync(__dirname);
+
+module.exports = function(source) {
+ return source;
+};
+
+module.exports.pitch = function(request) {
+ var query = loaderUtils.getOptions(this) || {};
+ var loaders = this.loaders.slice(this.loaderIndex + 1);
+ this.addDependency(this.resourcePath);
+ // We already in child compiler, return empty bundle
+ if(this[NS] === undefined) {
+ throw new Error(
+ '"extract-text-webpack-plugin" loader is used without the corresponding plugin, ' +
+ 'refer to https://github.com/webpack/extract-text-webpack-plugin for the usage example'
+ );
+ } else if(this[NS] === false) {
+ return "";
+ } else if(this[NS](null, query)) {
+ if(query.omit) {
+ this.loaderIndex += +query.omit + 1;
+ request = request.split("!").slice(+query.omit).join("!");
+ loaders = loaders.slice(+query.omit);
+ }
+ var resultSource;
+ if(query.remove) {
+ resultSource = "// removed by extract-text-webpack-plugin";
+ } else {
+ resultSource = undefined;
+ }
+
+ var childFilename = "extract-text-webpack-plugin-output-filename"; // eslint-disable-line no-path-concat
+ var publicPath = typeof query.publicPath === "string" ? query.publicPath : this._compilation.outputOptions.publicPath;
+ var outputOptions = {
+ filename: childFilename,
+ publicPath: publicPath
+ };
+ var childCompiler = this._compilation.createChildCompiler("extract-text-webpack-plugin", outputOptions);
+ childCompiler.apply(new NodeTemplatePlugin(outputOptions));
+ childCompiler.apply(new LibraryTemplatePlugin(null, "commonjs2"));
+ childCompiler.apply(new NodeTargetPlugin());
+ childCompiler.apply(new SingleEntryPlugin(this.context, "!!" + request));
+ childCompiler.apply(new LimitChunkCountPlugin({ maxChunks: 1 }));
+ var subCache = "subcache " + NS + " " + request; // eslint-disable-line no-path-concat
+ childCompiler.plugin("compilation", function(compilation) {
+ if(compilation.cache) {
+ if(!compilation.cache[subCache])
+ compilation.cache[subCache] = {};
+ compilation.cache = compilation.cache[subCache];
+ }
+ });
+ // We set loaderContext[NS] = false to indicate we already in
+ // a child compiler so we don't spawn another child compilers from there.
+ childCompiler.plugin("this-compilation", function(compilation) {
+ compilation.plugin("normal-module-loader", function(loaderContext, module) {
+ loaderContext[NS] = false;
+ if (module.request === request) {
+ module.loaders = loaders.map(function(loader) {
+ return {
+ loader: loader.path,
+ options: loader.options
+ };
+ });
+ }
+ });
+ });
+
+ var source;
+ childCompiler.plugin("after-compile", function(compilation, callback) {
+ source = compilation.assets[childFilename] && compilation.assets[childFilename].source();
+
+ // Remove all chunk assets
+ compilation.chunks.forEach(function(chunk) {
+ chunk.files.forEach(function(file) {
+ delete compilation.assets[file];
+ });
+ });
+
+ callback();
+ });
+ var callback = this.async();
+ childCompiler.runAsChild(function(err, entries, compilation) {
+ if(err) return callback(err);
+
+ if(compilation.errors.length > 0) {
+ return callback(compilation.errors[0]);
+ }
+ compilation.fileDependencies.forEach(function(dep) {
+ this.addDependency(dep);
+ }, this);
+ compilation.contextDependencies.forEach(function(dep) {
+ this.addContextDependency(dep);
+ }, this);
+ if(!source) {
+ return callback(new Error("Didn't get a result from child compiler"));
+ }
+ try {
+ var text = this.exec(source, request);
+ if(typeof text === "string")
+ text = [[0, text]];
+ text.forEach(function(item) {
+ var id = item[0];
+ compilation.modules.forEach(function(module) {
+ if(module.id === id)
+ item[0] = module.identifier();
+ });
+ });
+ this[NS](text, query);
+ if(text.locals && typeof resultSource !== "undefined") {
+ resultSource += "\nmodule.exports = " + JSON.stringify(text.locals) + ";";
+ }
+ } catch(e) {
+ return callback(e);
+ }
+ if(resultSource)
+ callback(null, resultSource);
+ else
+ callback();
+ }.bind(this));
+ }
+};
diff --git a/extract-text-webpack-plugin/logo.svg b/extract-text-webpack-plugin/logo.svg
new file mode 100644
index 00000000..febdc80e
--- /dev/null
+++ b/extract-text-webpack-plugin/logo.svg
@@ -0,0 +1,4 @@
+
+ Svg Vector Icons : http://www.onlinewebfonts.com/icon
+
+
diff --git a/extract-text-webpack-plugin/package.json b/extract-text-webpack-plugin/package.json
new file mode 100644
index 00000000..02e78e71
--- /dev/null
+++ b/extract-text-webpack-plugin/package.json
@@ -0,0 +1,53 @@
+{
+ "name": "extract-text-webpack-plugin",
+ "version": "2.1.2-issue579",
+ "author": "Tobias Koppers @sokra",
+ "description": "Extract text from bundle into a file.",
+ "engines": {
+ "node": ">=4.3.0 < 5.0.0 || >= 5.10"
+ },
+ "main": "index.js",
+ "files": [
+ "schema",
+ "ExtractedModule.js",
+ "index.js",
+ "loader.js",
+ "OrderUndefinedError.js"
+ ],
+ "peerDependencies": {
+ "webpack": "^2.2.0 || ^3.0.0"
+ },
+ "dependencies": {
+ "schema-utils": "^0.3.0",
+ "async": "^2.1.2",
+ "loader-utils": "^1.0.2",
+ "webpack-sources": "^1.0.1"
+ },
+ "devDependencies": {
+ "codecov.io": "^0.1.6",
+ "coveralls": "^2.11.2",
+ "css-loader": "^0.28.4",
+ "file-loader": "^0.11.2",
+ "istanbul": "^0.4.5",
+ "mocha": "^3.2.0",
+ "mocha-lcov-reporter": "1.3.0",
+ "raw-loader": "^0.5.1",
+ "should": "^11.1.2",
+ "standard-version": "^4.1.0",
+ "style-loader": "^0.18.2",
+ "webpack": "^2.6.1"
+ },
+ "homepage": "http://github.com/webpack-contrib/extract-text-webpack-plugin",
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/webpack-contrib/extract-text-webpack-plugin.git"
+ },
+ "license": "MIT",
+ "scripts": {
+ "test": "mocha",
+ "travis": "npm run cover -- --report lcovonly",
+ "cover": "istanbul cover _mocha",
+ "release": "standard-version",
+ "build:example": "(cd example && webpack)"
+ }
+}
diff --git a/extract-text-webpack-plugin/schema/loader.json b/extract-text-webpack-plugin/schema/loader.json
new file mode 100644
index 00000000..bca660af
--- /dev/null
+++ b/extract-text-webpack-plugin/schema/loader.json
@@ -0,0 +1,36 @@
+{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allChunks": {
+ "type": "boolean"
+ },
+ "disable": {
+ "type": "boolean"
+ },
+ "omit": {
+ "type": "boolean"
+ },
+ "remove": {
+ "type": "boolean"
+ },
+ "fallback": {
+ "type": ["string", "array", "object"]
+ },
+ "filename": {
+ "type": "string"
+ },
+ "use": {
+ "type": ["string", "array", "object"]
+ },
+ "publicPath": {
+ "type": "string"
+ },
+ "fallbackLoader": {
+ "type": ["string", "array", "object"]
+ },
+ "loader": {
+ "type": ["string", "array", "object"]
+ }
+ }
+}
diff --git a/extract-text-webpack-plugin/schema/plugin.json b/extract-text-webpack-plugin/schema/plugin.json
new file mode 100644
index 00000000..4fcf2e66
--- /dev/null
+++ b/extract-text-webpack-plugin/schema/plugin.json
@@ -0,0 +1,40 @@
+{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allChunks": {
+ "description": "",
+ "type": "boolean"
+ },
+ "disable": {
+ "description": "",
+ "type": "boolean"
+ },
+ "fallback": {
+ "description": "A loader that webpack can fall back to if the original one fails.",
+ "modes": {
+ "type": ["string", "object", "array"]
+ }
+ },
+ "filename": {
+ "description": "The filename and path that ExtractTextPlugin will extract to",
+ "modes": {
+ "type": ["string", "function"]
+ }
+ },
+ "ignoreOrder": {
+ "description": "Ignore dependency order (useful for CSS Modules)",
+ "type": "boolean"
+ },
+ "loader": {
+ "description": "The loader that ExtractTextPlugin will attempt to load through.",
+ "modes": {
+ "type": ["string", "object", "array"]
+ }
+ },
+ "publicPath": {
+ "description": "",
+ "type": "string"
+ }
+ }
+}
diff --git a/extract-text-webpack-plugin/test/TestCases.test.js b/extract-text-webpack-plugin/test/TestCases.test.js
new file mode 100644
index 00000000..bbcb3712
--- /dev/null
+++ b/extract-text-webpack-plugin/test/TestCases.test.js
@@ -0,0 +1,55 @@
+var fs = require("fs");
+var vm = require("vm");
+var path = require("path");
+var webpack = require("webpack");
+var should = require("should");
+var ExtractTextPlugin = require("../");
+
+var cases = process.env.CASES ? process.env.CASES.split(",") : fs.readdirSync(path.join(__dirname, "cases"));
+
+describe("TestCases", function() {
+ cases.forEach(function(testCase) {
+ 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");
+ });
+ done();
+ });
+ });
+ });
+});
+
+function readFileOrEmpty(path) {
+ try {
+ return fs.readFileSync(path, "utf-8");
+ } catch(e) {
+ return "";
+ }
+}
diff --git a/extract-text-webpack-plugin/test/cases/common-async/a.js b/extract-text-webpack-plugin/test/cases/common-async/a.js
new file mode 100644
index 00000000..2d7d820b
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/common-async/a.js
@@ -0,0 +1,2 @@
+require("./a.txt");
+require("./b.txt");
diff --git a/extract-text-webpack-plugin/test/cases/common-async/a.txt b/extract-text-webpack-plugin/test/cases/common-async/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/common-async/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/common-async/b.js b/extract-text-webpack-plugin/test/cases/common-async/b.js
new file mode 100644
index 00000000..caac53f4
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/common-async/b.js
@@ -0,0 +1,3 @@
+require("./a.txt");
+require("./c.txt");
+
diff --git a/extract-text-webpack-plugin/test/cases/common-async/b.txt b/extract-text-webpack-plugin/test/cases/common-async/b.txt
new file mode 100644
index 00000000..61780798
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/common-async/b.txt
@@ -0,0 +1 @@
+b
diff --git a/extract-text-webpack-plugin/test/cases/common-async/c.txt b/extract-text-webpack-plugin/test/cases/common-async/c.txt
new file mode 100644
index 00000000..f2ad6c76
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/common-async/c.txt
@@ -0,0 +1 @@
+c
diff --git a/extract-text-webpack-plugin/test/cases/common-async/expected/file.css b/extract-text-webpack-plugin/test/cases/common-async/expected/file.css
new file mode 100644
index 00000000..de980441
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/common-async/expected/file.css
@@ -0,0 +1,3 @@
+a
+b
+c
diff --git a/extract-text-webpack-plugin/test/cases/common-async/index.js b/extract-text-webpack-plugin/test/cases/common-async/index.js
new file mode 100644
index 00000000..624fa419
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/common-async/index.js
@@ -0,0 +1,14 @@
+require.ensure(
+ [],
+ function() {
+ require("./a.js");
+ },
+ 'async-chunk-a'
+);
+require.ensure(
+ [],
+ function() {
+ require("./b.js");
+ },
+ 'async-chunk-b'
+);
diff --git a/extract-text-webpack-plugin/test/cases/common-async/webpack.config.js b/extract-text-webpack-plugin/test/cases/common-async/webpack.config.js
new file mode 100644
index 00000000..758d08a1
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/common-async/webpack.config.js
@@ -0,0 +1,17 @@
+var webpack = require('webpack');
+var ExtractTextPlugin = require("../../../index");
+
+module.exports = {
+ entry: "./index",
+ plugins: [
+ new webpack.optimize.CommonsChunkPlugin({
+ name: 'common',
+ filename: 'common.js',
+ chunks: ['async-chunk-a', 'async-chunk-b']
+ }),
+ new ExtractTextPlugin({
+ filename: "file.css",
+ allChunks: true
+ })
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/merging-chunk/a.txt b/extract-text-webpack-plugin/test/cases/merging-chunk/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-chunk/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/merging-chunk/b.txt b/extract-text-webpack-plugin/test/cases/merging-chunk/b.txt
new file mode 100644
index 00000000..61780798
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-chunk/b.txt
@@ -0,0 +1 @@
+b
diff --git a/extract-text-webpack-plugin/test/cases/merging-chunk/c.txt b/extract-text-webpack-plugin/test/cases/merging-chunk/c.txt
new file mode 100644
index 00000000..f2ad6c76
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-chunk/c.txt
@@ -0,0 +1 @@
+c
diff --git a/extract-text-webpack-plugin/test/cases/merging-chunk/expected/file.css b/extract-text-webpack-plugin/test/cases/merging-chunk/expected/file.css
new file mode 100644
index 00000000..de980441
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-chunk/expected/file.css
@@ -0,0 +1,3 @@
+a
+b
+c
diff --git a/extract-text-webpack-plugin/test/cases/merging-chunk/index.js b/extract-text-webpack-plugin/test/cases/merging-chunk/index.js
new file mode 100644
index 00000000..17b8acee
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-chunk/index.js
@@ -0,0 +1,5 @@
+require("./a.txt");
+require.ensure([], function() {
+ require("./b.txt");
+ require("./c.txt");
+});
diff --git a/extract-text-webpack-plugin/test/cases/merging-chunk/webpack.config.js b/extract-text-webpack-plugin/test/cases/merging-chunk/webpack.config.js
new file mode 100644
index 00000000..3113d66f
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-chunk/webpack.config.js
@@ -0,0 +1,10 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: "./index",
+ plugins: [
+ new ExtractTextPlugin({
+ filename: "file.css",
+ allChunks: true
+ })
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/a.js b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/a.js
new file mode 100644
index 00000000..91df1daf
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/a.js
@@ -0,0 +1,3 @@
+require.ensure([], function() {
+ require("./a.txt");
+});
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/a.txt b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/b.js b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/b.js
new file mode 100644
index 00000000..91df1daf
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/b.js
@@ -0,0 +1,3 @@
+require.ensure([], function() {
+ require("./a.txt");
+});
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/expected/a.txt b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/expected/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/expected/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/expected/b.txt b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/expected/b.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/expected/b.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/webpack.config.js b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/webpack.config.js
new file mode 100644
index 00000000..c15ebfc1
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries-shared/webpack.config.js
@@ -0,0 +1,13 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: {
+ a: "./a",
+ b: "./b"
+ },
+ plugins: [
+ new ExtractTextPlugin({
+ filename: "[name].txt",
+ allChunks: true
+ })
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries/a.js b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/a.js
new file mode 100644
index 00000000..b3a9ca9d
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/a.js
@@ -0,0 +1,4 @@
+require.ensure([], function() {
+ require("./a.txt");
+ require("./b.txt");
+});
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries/a.txt b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries/b.js b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/b.js
new file mode 100644
index 00000000..d7f9f0f4
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/b.js
@@ -0,0 +1,4 @@
+require.ensure([], function() {
+ require("./a.txt");
+ require("./c.txt");
+});
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries/b.txt b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/b.txt
new file mode 100644
index 00000000..61780798
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/b.txt
@@ -0,0 +1 @@
+b
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries/c.txt b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/c.txt
new file mode 100644
index 00000000..f2ad6c76
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/c.txt
@@ -0,0 +1 @@
+c
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries/expected/a.txt b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/expected/a.txt
new file mode 100644
index 00000000..422c2b7a
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/expected/a.txt
@@ -0,0 +1,2 @@
+a
+b
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries/expected/b.txt b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/expected/b.txt
new file mode 100644
index 00000000..0f7bc766
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/expected/b.txt
@@ -0,0 +1,2 @@
+a
+c
diff --git a/extract-text-webpack-plugin/test/cases/merging-multiple-entries/webpack.config.js b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/webpack.config.js
new file mode 100644
index 00000000..c15ebfc1
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/merging-multiple-entries/webpack.config.js
@@ -0,0 +1,13 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: {
+ a: "./a",
+ b: "./b"
+ },
+ plugins: [
+ new ExtractTextPlugin({
+ filename: "[name].txt",
+ allChunks: true
+ })
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries-filename/a.js b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/a.js
new file mode 100644
index 00000000..b3a9ca9d
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/a.js
@@ -0,0 +1,4 @@
+require.ensure([], function() {
+ require("./a.txt");
+ require("./b.txt");
+});
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries-filename/a.txt b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries-filename/b.js b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/b.js
new file mode 100644
index 00000000..d7f9f0f4
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/b.js
@@ -0,0 +1,4 @@
+require.ensure([], function() {
+ require("./a.txt");
+ require("./c.txt");
+});
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries-filename/b.txt b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/b.txt
new file mode 100644
index 00000000..61780798
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/b.txt
@@ -0,0 +1 @@
+b
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries-filename/c.txt b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/c.txt
new file mode 100644
index 00000000..f2ad6c76
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/c.txt
@@ -0,0 +1 @@
+c
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/a.txt b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/a.txt
new file mode 100755
index 00000000..422c2b7a
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/a.txt
@@ -0,0 +1,2 @@
+a
+b
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/b.txt b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/b.txt
new file mode 100755
index 00000000..0f7bc766
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/b.txt
@@ -0,0 +1,2 @@
+a
+c
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/txt/a.txt b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/txt/a.txt
new file mode 100644
index 00000000..422c2b7a
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/txt/a.txt
@@ -0,0 +1,2 @@
+a
+b
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/txt/b.txt b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/txt/b.txt
new file mode 100644
index 00000000..0f7bc766
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/expected/txt/b.txt
@@ -0,0 +1,2 @@
+a
+c
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries-filename/webpack.config.js b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/webpack.config.js
new file mode 100644
index 00000000..2337be5a
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries-filename/webpack.config.js
@@ -0,0 +1,15 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: {
+ 'js/a': "./a",
+ 'js/b': "./b"
+ },
+ plugins: [
+ new ExtractTextPlugin({
+ filename: (getPath) => {
+ return getPath('txt/[name].txt').replace('txt/js', '');
+ },
+ allChunks: true
+ })
+ ]
+};
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries/a.js b/extract-text-webpack-plugin/test/cases/multiple-entries/a.js
new file mode 100644
index 00000000..2d7d820b
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries/a.js
@@ -0,0 +1,2 @@
+require("./a.txt");
+require("./b.txt");
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries/a.txt b/extract-text-webpack-plugin/test/cases/multiple-entries/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries/b.js b/extract-text-webpack-plugin/test/cases/multiple-entries/b.js
new file mode 100644
index 00000000..d41b987b
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries/b.js
@@ -0,0 +1,2 @@
+require("./a.txt");
+require("./c.txt");
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries/b.txt b/extract-text-webpack-plugin/test/cases/multiple-entries/b.txt
new file mode 100644
index 00000000..61780798
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries/b.txt
@@ -0,0 +1 @@
+b
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries/c.txt b/extract-text-webpack-plugin/test/cases/multiple-entries/c.txt
new file mode 100644
index 00000000..f2ad6c76
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries/c.txt
@@ -0,0 +1 @@
+c
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries/expected/a.txt b/extract-text-webpack-plugin/test/cases/multiple-entries/expected/a.txt
new file mode 100644
index 00000000..422c2b7a
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries/expected/a.txt
@@ -0,0 +1,2 @@
+a
+b
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries/expected/b.txt b/extract-text-webpack-plugin/test/cases/multiple-entries/expected/b.txt
new file mode 100644
index 00000000..0f7bc766
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries/expected/b.txt
@@ -0,0 +1,2 @@
+a
+c
diff --git a/extract-text-webpack-plugin/test/cases/multiple-entries/webpack.config.js b/extract-text-webpack-plugin/test/cases/multiple-entries/webpack.config.js
new file mode 100644
index 00000000..8fa58a32
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/multiple-entries/webpack.config.js
@@ -0,0 +1,10 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: {
+ a: "./a",
+ b: "./b"
+ },
+ plugins: [
+ new ExtractTextPlugin("[name].txt")
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/nested/a.txt b/extract-text-webpack-plugin/test/cases/nested/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/nested/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/nested/b.txt b/extract-text-webpack-plugin/test/cases/nested/b.txt
new file mode 100644
index 00000000..61780798
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/nested/b.txt
@@ -0,0 +1 @@
+b
diff --git a/extract-text-webpack-plugin/test/cases/nested/c.txt b/extract-text-webpack-plugin/test/cases/nested/c.txt
new file mode 100644
index 00000000..f2ad6c76
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/nested/c.txt
@@ -0,0 +1 @@
+c
diff --git a/extract-text-webpack-plugin/test/cases/nested/d.txt b/extract-text-webpack-plugin/test/cases/nested/d.txt
new file mode 100644
index 00000000..4bcfe98e
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/nested/d.txt
@@ -0,0 +1 @@
+d
diff --git a/extract-text-webpack-plugin/test/cases/nested/expected/file.css b/extract-text-webpack-plugin/test/cases/nested/expected/file.css
new file mode 100644
index 00000000..d68dd403
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/nested/expected/file.css
@@ -0,0 +1,4 @@
+a
+b
+c
+d
diff --git a/extract-text-webpack-plugin/test/cases/nested/file.js b/extract-text-webpack-plugin/test/cases/nested/file.js
new file mode 100644
index 00000000..dc1adf18
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/nested/file.js
@@ -0,0 +1,4 @@
+require("./a.txt");
+require("./b.txt");
+require("./c.txt");
+require("./d.txt");
diff --git a/extract-text-webpack-plugin/test/cases/nested/index.js b/extract-text-webpack-plugin/test/cases/nested/index.js
new file mode 100644
index 00000000..9377b055
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/nested/index.js
@@ -0,0 +1,3 @@
+require("./a.txt");
+require("./file");
+require("./b.txt");
diff --git a/extract-text-webpack-plugin/test/cases/nested/webpack.config.js b/extract-text-webpack-plugin/test/cases/nested/webpack.config.js
new file mode 100644
index 00000000..0fbc2d5c
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/nested/webpack.config.js
@@ -0,0 +1,7 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: "./index",
+ plugins: [
+ new ExtractTextPlugin("file.css")
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/optimize-tree/a.js b/extract-text-webpack-plugin/test/cases/optimize-tree/a.js
new file mode 100644
index 00000000..f0403b6f
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/optimize-tree/a.js
@@ -0,0 +1,5 @@
+require.ensure([], function() {
+ require("./a.txt");
+});
+
+a = {};
diff --git a/extract-text-webpack-plugin/test/cases/optimize-tree/a.txt b/extract-text-webpack-plugin/test/cases/optimize-tree/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/optimize-tree/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/optimize-tree/b.js b/extract-text-webpack-plugin/test/cases/optimize-tree/b.js
new file mode 100644
index 00000000..16786af0
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/optimize-tree/b.js
@@ -0,0 +1,5 @@
+require.ensure([], function() {
+ require("./b.txt");
+});
+
+b = {};
diff --git a/extract-text-webpack-plugin/test/cases/optimize-tree/b.txt b/extract-text-webpack-plugin/test/cases/optimize-tree/b.txt
new file mode 100644
index 00000000..61780798
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/optimize-tree/b.txt
@@ -0,0 +1 @@
+b
diff --git a/extract-text-webpack-plugin/test/cases/optimize-tree/expected/main.txt b/extract-text-webpack-plugin/test/cases/optimize-tree/expected/main.txt
new file mode 100644
index 00000000..1c539e8d
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/optimize-tree/expected/main.txt
@@ -0,0 +1,3 @@
+index
+a
+b
diff --git a/extract-text-webpack-plugin/test/cases/optimize-tree/index.js b/extract-text-webpack-plugin/test/cases/optimize-tree/index.js
new file mode 100644
index 00000000..26b45623
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/optimize-tree/index.js
@@ -0,0 +1,9 @@
+require("./index.txt");
+
+require.ensure([], function() {
+ require("./a.js");
+}, 'a-chunk');
+
+require.ensure([], function() {
+ require("./b.js");
+}, 'b-chunk');
diff --git a/extract-text-webpack-plugin/test/cases/optimize-tree/index.txt b/extract-text-webpack-plugin/test/cases/optimize-tree/index.txt
new file mode 100644
index 00000000..9015a7a3
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/optimize-tree/index.txt
@@ -0,0 +1 @@
+index
diff --git a/extract-text-webpack-plugin/test/cases/optimize-tree/webpack.config.js b/extract-text-webpack-plugin/test/cases/optimize-tree/webpack.config.js
new file mode 100644
index 00000000..01a76132
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/optimize-tree/webpack.config.js
@@ -0,0 +1,19 @@
+var ExtractTextPlugin = require("../../../");
+var webpack = require("webpack");
+
+module.exports = {
+ entry: "./index.js",
+ plugins: [
+ new ExtractTextPlugin({
+ filename: "[name].txt",
+ allChunks: true
+ }),
+ new webpack.optimize.CommonsChunkPlugin({
+ children: true,
+ minChunks: 2
+ }),
+ new webpack.optimize.MinChunkSizePlugin({
+ minChunkSize: 51200 // 50ko
+ })
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/order-undefined-error/a.css b/extract-text-webpack-plugin/test/cases/order-undefined-error/a.css
new file mode 100644
index 00000000..8abd6bfb
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/order-undefined-error/a.css
@@ -0,0 +1,4 @@
+.a {
+ composes: c1 from './c1.css';
+ composes: c2 from './c2.css';
+}
diff --git a/extract-text-webpack-plugin/test/cases/order-undefined-error/b.css b/extract-text-webpack-plugin/test/cases/order-undefined-error/b.css
new file mode 100644
index 00000000..bbc901f7
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/order-undefined-error/b.css
@@ -0,0 +1,4 @@
+.b {
+ composes: c2 from './c2.css';
+ composes: c1 from './c1.css';
+}
diff --git a/extract-text-webpack-plugin/test/cases/order-undefined-error/c1.css b/extract-text-webpack-plugin/test/cases/order-undefined-error/c1.css
new file mode 100644
index 00000000..af144e72
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/order-undefined-error/c1.css
@@ -0,0 +1,2 @@
+.c1 {
+}
diff --git a/extract-text-webpack-plugin/test/cases/order-undefined-error/c2.css b/extract-text-webpack-plugin/test/cases/order-undefined-error/c2.css
new file mode 100644
index 00000000..f9e9e192
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/order-undefined-error/c2.css
@@ -0,0 +1,2 @@
+.c2 {
+}
diff --git a/extract-text-webpack-plugin/test/cases/order-undefined-error/expected/file.css b/extract-text-webpack-plugin/test/cases/order-undefined-error/expected/file.css
new file mode 100644
index 00000000..b87b58bd
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/order-undefined-error/expected/file.css
@@ -0,0 +1,8 @@
+._3QiTkN7JPds2C9Bq73MpOX {
+}
+._3dtwYD12yqGZUJ-uPQLu9z {
+}
+._32HVXkGocfWZMaHoXEFkED {
+}
+.hbZI7DlQBB9VYNCgL20kL {
+}
diff --git a/extract-text-webpack-plugin/test/cases/order-undefined-error/index.js b/extract-text-webpack-plugin/test/cases/order-undefined-error/index.js
new file mode 100644
index 00000000..a2a7578a
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/order-undefined-error/index.js
@@ -0,0 +1,2 @@
+require('./a.css');
+require('./b.css');
diff --git a/extract-text-webpack-plugin/test/cases/order-undefined-error/webpack.config.js b/extract-text-webpack-plugin/test/cases/order-undefined-error/webpack.config.js
new file mode 100644
index 00000000..b7fcd5a8
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/order-undefined-error/webpack.config.js
@@ -0,0 +1,26 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: "./index.js",
+ module: {
+ loaders: [
+ {
+ test: /\.css$/,
+ use: ExtractTextPlugin.extract({
+ fallback: 'style-loader',
+ use: {
+ loader: 'css-loader',
+ options: {
+ modules: true
+ }
+ }
+ })
+ }
+ ]
+ },
+ plugins: [
+ new ExtractTextPlugin({
+ filename: 'file.css',
+ ignoreOrder: true
+ })
+ ]
+}
diff --git a/extract-text-webpack-plugin/test/cases/simple-query-object/a.css b/extract-text-webpack-plugin/test/cases/simple-query-object/a.css
new file mode 100644
index 00000000..9ad17d2e
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple-query-object/a.css
@@ -0,0 +1,3 @@
+body {
+ correct: a;
+}
diff --git a/extract-text-webpack-plugin/test/cases/simple-query-object/b.css b/extract-text-webpack-plugin/test/cases/simple-query-object/b.css
new file mode 100644
index 00000000..485c35d7
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple-query-object/b.css
@@ -0,0 +1,3 @@
+body {
+ correct: b;
+}
diff --git a/extract-text-webpack-plugin/test/cases/simple-query-object/expected/file.css b/extract-text-webpack-plugin/test/cases/simple-query-object/expected/file.css
new file mode 100644
index 00000000..37866b01
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple-query-object/expected/file.css
@@ -0,0 +1,8 @@
+body {
+ correct: a;
+}
+body {
+ correct: b;
+}
+
+/*# sourceMappingURL=file.css.map*/
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/test/cases/simple-query-object/index.js b/extract-text-webpack-plugin/test/cases/simple-query-object/index.js
new file mode 100644
index 00000000..5cf57e58
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple-query-object/index.js
@@ -0,0 +1,2 @@
+require("./a.css");
+require("./b.css");
diff --git a/extract-text-webpack-plugin/test/cases/simple-query-object/webpack.config.js b/extract-text-webpack-plugin/test/cases/simple-query-object/webpack.config.js
new file mode 100644
index 00000000..2ef632f4
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple-query-object/webpack.config.js
@@ -0,0 +1,18 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: "./index",
+ module: {
+ loaders: [
+ { test: /\.css$/, use: ExtractTextPlugin.extract({
+ fallback: "style-loader",
+ use: { loader: "css-loader", options: {
+ sourceMap: true
+ } }
+ }) }
+ ]
+ },
+ devtool: "source-map",
+ plugins: [
+ new ExtractTextPlugin("file.css")
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/simple-queryless-object/a.css b/extract-text-webpack-plugin/test/cases/simple-queryless-object/a.css
new file mode 100644
index 00000000..9ad17d2e
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple-queryless-object/a.css
@@ -0,0 +1,3 @@
+body {
+ correct: a;
+}
diff --git a/extract-text-webpack-plugin/test/cases/simple-queryless-object/b.css b/extract-text-webpack-plugin/test/cases/simple-queryless-object/b.css
new file mode 100644
index 00000000..485c35d7
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple-queryless-object/b.css
@@ -0,0 +1,3 @@
+body {
+ correct: b;
+}
diff --git a/extract-text-webpack-plugin/test/cases/simple-queryless-object/expected/file.css b/extract-text-webpack-plugin/test/cases/simple-queryless-object/expected/file.css
new file mode 100644
index 00000000..37866b01
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple-queryless-object/expected/file.css
@@ -0,0 +1,8 @@
+body {
+ correct: a;
+}
+body {
+ correct: b;
+}
+
+/*# sourceMappingURL=file.css.map*/
\ No newline at end of file
diff --git a/extract-text-webpack-plugin/test/cases/simple-queryless-object/index.js b/extract-text-webpack-plugin/test/cases/simple-queryless-object/index.js
new file mode 100644
index 00000000..5cf57e58
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple-queryless-object/index.js
@@ -0,0 +1,2 @@
+require("./a.css");
+require("./b.css");
diff --git a/extract-text-webpack-plugin/test/cases/simple-queryless-object/webpack.config.js b/extract-text-webpack-plugin/test/cases/simple-queryless-object/webpack.config.js
new file mode 100644
index 00000000..64c58901
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple-queryless-object/webpack.config.js
@@ -0,0 +1,18 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: "./index",
+ module: {
+ loaders: [
+ { test: /\.css$/, use: ExtractTextPlugin.extract({
+ fallback: { loader: "style-loader" },
+ use: { loader: "css-loader", options: {
+ sourceMap: true
+ } }
+ }) }
+ ]
+ },
+ devtool: "source-map",
+ plugins: [
+ new ExtractTextPlugin("file.css")
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/simple/a.txt b/extract-text-webpack-plugin/test/cases/simple/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/simple/b.txt b/extract-text-webpack-plugin/test/cases/simple/b.txt
new file mode 100644
index 00000000..61780798
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple/b.txt
@@ -0,0 +1 @@
+b
diff --git a/extract-text-webpack-plugin/test/cases/simple/expected/file.css b/extract-text-webpack-plugin/test/cases/simple/expected/file.css
new file mode 100644
index 00000000..422c2b7a
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple/expected/file.css
@@ -0,0 +1,2 @@
+a
+b
diff --git a/extract-text-webpack-plugin/test/cases/simple/index.js b/extract-text-webpack-plugin/test/cases/simple/index.js
new file mode 100644
index 00000000..2d7d820b
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple/index.js
@@ -0,0 +1,2 @@
+require("./a.txt");
+require("./b.txt");
diff --git a/extract-text-webpack-plugin/test/cases/simple/webpack.config.js b/extract-text-webpack-plugin/test/cases/simple/webpack.config.js
new file mode 100644
index 00000000..0fbc2d5c
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/simple/webpack.config.js
@@ -0,0 +1,7 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: "./index",
+ plugins: [
+ new ExtractTextPlugin("file.css")
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/splitted-chunk/a.txt b/extract-text-webpack-plugin/test/cases/splitted-chunk/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-chunk/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/splitted-chunk/b.txt b/extract-text-webpack-plugin/test/cases/splitted-chunk/b.txt
new file mode 100644
index 00000000..61780798
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-chunk/b.txt
@@ -0,0 +1 @@
+b
diff --git a/extract-text-webpack-plugin/test/cases/splitted-chunk/expected/file.css b/extract-text-webpack-plugin/test/cases/splitted-chunk/expected/file.css
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-chunk/expected/file.css
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/splitted-chunk/index.js b/extract-text-webpack-plugin/test/cases/splitted-chunk/index.js
new file mode 100644
index 00000000..ed04a320
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-chunk/index.js
@@ -0,0 +1,4 @@
+require("./a.txt");
+require.ensure([], function() {
+ require("./b.txt");
+});
diff --git a/extract-text-webpack-plugin/test/cases/splitted-chunk/webpack.config.js b/extract-text-webpack-plugin/test/cases/splitted-chunk/webpack.config.js
new file mode 100644
index 00000000..bc4e0730
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-chunk/webpack.config.js
@@ -0,0 +1,10 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: "./index",
+ plugins: [
+ new ExtractTextPlugin({
+ filename: "file.css",
+ allChunks: false
+ })
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/a.js b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/a.js
new file mode 100644
index 00000000..b3a9ca9d
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/a.js
@@ -0,0 +1,4 @@
+require.ensure([], function() {
+ require("./a.txt");
+ require("./b.txt");
+});
diff --git a/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/a.txt b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/a.txt
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/a.txt
@@ -0,0 +1 @@
+a
diff --git a/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/b.js b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/b.js
new file mode 100644
index 00000000..d7f9f0f4
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/b.js
@@ -0,0 +1,4 @@
+require.ensure([], function() {
+ require("./a.txt");
+ require("./c.txt");
+});
diff --git a/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/b.txt b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/b.txt
new file mode 100644
index 00000000..61780798
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/b.txt
@@ -0,0 +1 @@
+b
diff --git a/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/c.txt b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/c.txt
new file mode 100644
index 00000000..f2ad6c76
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/c.txt
@@ -0,0 +1 @@
+c
diff --git a/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/expected/a.txt b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/expected/a.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/expected/b.txt b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/expected/b.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/webpack.config.js b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/webpack.config.js
new file mode 100644
index 00000000..9e3526c1
--- /dev/null
+++ b/extract-text-webpack-plugin/test/cases/splitted-multiple-entries/webpack.config.js
@@ -0,0 +1,13 @@
+var ExtractTextPlugin = require("../../../");
+module.exports = {
+ entry: {
+ a: "./a",
+ b: "./b"
+ },
+ plugins: [
+ new ExtractTextPlugin({
+ filename: "[name].txt",
+ allChunks: false
+ })
+ ]
+};
diff --git a/extract-text-webpack-plugin/test/extract.test.js b/extract-text-webpack-plugin/test/extract.test.js
new file mode 100644
index 00000000..3c21fa9b
--- /dev/null
+++ b/extract-text-webpack-plugin/test/extract.test.js
@@ -0,0 +1,215 @@
+var should = require("should");
+var ExtractTextPlugin = require("../");
+
+var loaderPath = require.resolve("../loader.js");
+
+describe("ExtractTextPlugin.extract()", function() {
+ it("throws if given multiple arguments", function() {
+ should.throws(function() {
+ ExtractTextPlugin.extract("style-loader", "css-loader");
+ });
+ });
+
+ context("json schema validation", function() {
+ it("does not throw if a filename is specified", function() {
+ should.doesNotThrow(function() {
+ ExtractTextPlugin.extract("file.css");
+ });
+ });
+
+ it("does not throw if a correct config object is passed in", function() {
+ should.doesNotThrow(function() {
+ ExtractTextPlugin.extract({use: 'css-loader'});
+ });
+ });
+
+ it("throws if an incorrect config is passed in", function() {
+ should.throws(
+ function() {
+ ExtractTextPlugin.extract({style: 'file.css'});
+ },
+ function(err) {
+ return err.message === 'Validation Error\n\n' +
+ 'Extract Text Plugin (Loader) Invalid Options\n\n' +
+ 'options[\'style\'] should NOT have additional properties\n';
+ }
+ );
+ });
+ });
+
+ context("specifying loader", function() {
+ it("accepts a loader string", function() {
+ ExtractTextPlugin.extract("css-loader").should.deepEqual([
+ { loader: loaderPath, options: { omit: 0, remove:true } },
+ { loader: "css-loader" }
+ ]);
+ });
+
+ it("accepts a chained loader string", function() {
+ ExtractTextPlugin.extract(
+ "css-loader!postcss-loader!sass-loader"
+ ).should.deepEqual([
+ { loader: loaderPath, options: { omit: 0, remove:true } },
+ { loader: "css-loader" },
+ { loader: "postcss-loader" },
+ { loader: "sass-loader" }
+ ]);
+ });
+
+ it("accepts an array of loader names", function() {
+ ExtractTextPlugin.extract(
+ ["css-loader", "postcss-loader", "sass-loader"]
+ ).should.deepEqual([
+ { loader: loaderPath, options: { omit: 0, remove:true } },
+ { loader: "css-loader" },
+ { loader: "postcss-loader" },
+ { loader: "sass-loader" }
+ ]);
+ });
+
+ it("accepts a loader object", function() {
+ ExtractTextPlugin.extract({ use: "css-loader" }).should.deepEqual([
+ { loader: loaderPath, options: { omit: 0, remove:true } },
+ { loader: "css-loader" }
+ ]);
+ });
+
+ it("accepts an array of loader names in loader object", function() {
+ ExtractTextPlugin.extract({
+ use: ["css-loader", "postcss-loader", "sass-loader"]
+ }).should.deepEqual([
+ { loader: loaderPath, options: { omit: 0, remove:true } },
+ { loader: "css-loader" },
+ { loader: "postcss-loader" },
+ { loader: "sass-loader" }
+ ]);
+ });
+
+ it("accepts a loader object with an options object", function() {
+ ExtractTextPlugin.extract(
+ { use: "css-loader", options: { modules: true } }
+ ).should.deepEqual([
+ { loader: loaderPath, options: { omit: 0, remove:true } },
+ { use: "css-loader", options: { modules: true } }
+ ]);
+ });
+
+ it("accepts a loader object with an options object in array of loaders", function() {
+ ExtractTextPlugin.extract({
+ use: [
+ { loader: "css-loader", options: { modules: true } },
+ "postcss-loader"
+ ]
+ }).should.deepEqual([
+ { loader: loaderPath, options: { omit: 0, remove:true } },
+ { loader: "css-loader", options: { modules: true } },
+ { loader: "postcss-loader" }
+ ]);
+ });
+
+ it("accepts a loader object with a (legacy) query object", function() {
+ ExtractTextPlugin.extract(
+ { use: "css-loader", query: { modules: true } }
+ ).should.deepEqual([
+ { loader: loaderPath, options: { omit: 0, remove:true } },
+ { use: "css-loader", query: { modules: true } }
+ ]);
+ });
+
+ it("accepts a loader object with a legacy loader field", function() {
+ ExtractTextPlugin.extract(
+ { loader: "css-loader", query: { modules: true } }
+ ).should.deepEqual([
+ { loader: loaderPath, options: { omit: 0, remove:true } },
+ { loader: "css-loader", query: { modules: true } }
+ ]);
+ });
+
+ it("accepts an array of loader objects", function() {
+ ExtractTextPlugin.extract([
+ { loader: "css-loader" },
+ { loader: "postcss-loader" },
+ { loader: "sass-loader" }
+ ]).should.deepEqual([
+ { loader: loaderPath, options: { omit: 0, remove:true } },
+ { loader: "css-loader" },
+ { loader: "postcss-loader" },
+ { loader: "sass-loader" }
+ ]);
+ });
+ })
+
+ context("specifying fallback", function() {
+ it("accepts a fallback string", function() {
+ ExtractTextPlugin.extract({
+ fallback: "style-loader",
+ use: "css-loader"
+ }).should.deepEqual([
+ { loader: loaderPath, options: { omit: 1, remove: true } },
+ { loader: "style-loader" },
+ { loader: "css-loader" }
+ ]);
+ });
+
+ it("accepts a fallback string with legacy fallbackLoader option", function() {
+ ExtractTextPlugin.extract({
+ fallbackLoader: "style-loader",
+ use: "css-loader"
+ }).should.deepEqual([
+ { loader: loaderPath, options: { omit: 1, remove: true } },
+ { loader: "style-loader" },
+ { loader: "css-loader" }
+ ]);
+ });
+
+ it("accepts a chained fallback string", function() {
+ ExtractTextPlugin.extract({
+ fallback: "something-loader!style-loader",
+ use: "css-loader"
+ }).should.deepEqual([
+ { loader: loaderPath, options: { omit: 2, remove: true } },
+ { loader: "something-loader" },
+ { loader: "style-loader" },
+ { loader: "css-loader" }
+ ]);
+ });
+
+ it("accepts a fallback object", function() {
+ ExtractTextPlugin.extract({
+ fallback: { loader: "style-loader" },
+ use: "css-loader"
+ }).should.deepEqual([
+ { loader: loaderPath, options: { omit: 1, remove: true } },
+ { loader: "style-loader" },
+ { loader: "css-loader" }
+ ]);
+ });
+
+ it("accepts an array of fallback objects", function() {
+ ExtractTextPlugin.extract({
+ fallback: [
+ { loader: "something-loader" },
+ { loader: "style-loader" }
+ ],
+ use: "css-loader"
+ }).should.deepEqual([
+ { loader: loaderPath, options: { omit: 2, remove: true } },
+ { loader: "something-loader" },
+ { loader: "style-loader" },
+ { loader: "css-loader" }
+ ]);
+ });
+ });
+
+ it("passes additional options to its own loader", function() {
+ ExtractTextPlugin.extract({
+ fallback: "style-loader",
+ use: "css-loader",
+ publicPath: "/test"
+ }).should.deepEqual([
+ { loader: loaderPath, options: { omit: 1, remove: true, publicPath: "/test" } },
+ { loader: "style-loader" },
+ { loader: "css-loader" }
+ ]);
+ });
+});
diff --git a/global-cli/serve.js b/global-cli/serve.js
index 49d3071f..b5264d6d 100755
--- a/global-cli/serve.js
+++ b/global-cli/serve.js
@@ -196,45 +196,6 @@ module.exports = function(args) {
const config = hotDevServer(devConfig);
- // Temporary workaround until https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/579 is fixed
- const enact = require(path.resolve('./package.json')).enact || {};
- const autoprefixer = require('autoprefixer');
- const LessPluginRi = require('resolution-independence');
- config.module.rules[3] = {
- test: /\.(c|le)ss$/,
- use: [
- require.resolve('style-loader'),
- {
- loader: require.resolve('css-loader'),
- options: {
- importLoaders: 2,
- modules: true,
- sourceMap: true,
- localIdentName: '[name]__[local]___[hash:base64:5]'
- }
- },
- {
- loader: require.resolve('postcss-loader'),
- options: {
- ident: 'postcss',
- sourceMap: true,
- plugins: () => [
- autoprefixer({browsers:['>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9'], flexbox:'no-2009'}),
- require('postcss-flexbugs-fixes')
- ]
- }
- },
- {
- loader: require.resolve('less-loader'),
- options: {
- sourceMap: true,
- plugins: ((enact.ri) ? [new LessPluginRi(enact.ri)] : [])
- }
- }
- ]
- };
- config.plugins.splice(2, 1);
-
// Warn and crash if required files are missing
if (!checkRequiredFiles([config.entry.main[config.entry.main.length-1]])) {
process.exit(1);
diff --git a/package.json b/package.json
index 3d8a6224..fa6df95a 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,7 @@
"eslint-plugin-enact": "~0.1.3",
"eslint-plugin-react": "7.2.1",
"expose-loader": "~0.7.3",
- "extract-text-webpack-plugin": "~3.0.0",
+ "extract-text-webpack-plugin": "file:extract-text-webpack-plugin",
"file-loader": "~0.11.2",
"filesize": "~3.5.10",
"find-cache-dir": "~1.0.0",