UNPKG

11.8 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8
9var _fs = require('fs');
10
11var _fs2 = _interopRequireDefault(_fs);
12
13var _path = require('path');
14
15var _path2 = _interopRequireDefault(_path);
16
17var _Chunk = require('webpack/lib/Chunk');
18
19var _Chunk2 = _interopRequireDefault(_Chunk);
20
21var _webpackSources = require('webpack-sources');
22
23var _async = require('async');
24
25var _async2 = _interopRequireDefault(_async);
26
27var _loaderUtils = require('loader-utils');
28
29var _loaderUtils2 = _interopRequireDefault(_loaderUtils);
30
31var _schemaUtils = require('schema-utils');
32
33var _schemaUtils2 = _interopRequireDefault(_schemaUtils);
34
35var _ExtractTextPluginCompilation = require('./lib/ExtractTextPluginCompilation');
36
37var _ExtractTextPluginCompilation2 = _interopRequireDefault(_ExtractTextPluginCompilation);
38
39var _OrderUndefinedError = require('./lib/OrderUndefinedError');
40
41var _OrderUndefinedError2 = _interopRequireDefault(_OrderUndefinedError);
42
43var _helpers = require('./lib/helpers');
44
45function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
46
47function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
48
49var NS = _path2.default.dirname(_fs2.default.realpathSync(__filename));
50
51var nextId = 0;
52
53var ExtractTextPlugin = function () {
54 function ExtractTextPlugin(options) {
55 _classCallCheck(this, ExtractTextPlugin);
56
57 if ((0, _helpers.isString)(options)) {
58 options = { filename: options };
59 } else {
60 (0, _schemaUtils2.default)(_path2.default.resolve(__dirname, '../schema/plugin.json'), options, 'Extract Text Plugin');
61 }
62 this.filename = options.filename;
63 this.id = options.id != null ? options.id : ++nextId;
64 this.options = {};
65 (0, _helpers.mergeOptions)(this.options, options);
66 delete this.options.filename;
67 delete this.options.id;
68 }
69
70 _createClass(ExtractTextPlugin, [{
71 key: 'applyAdditionalInformation',
72 value: function applyAdditionalInformation(source, info) {
73 if (info) {
74 return new _webpackSources.ConcatSource(`@media ${info[0]} {`, source, '}');
75 }
76 return source;
77 }
78 }, {
79 key: 'loader',
80 value: function loader(options) {
81 return ExtractTextPlugin.loader((0, _helpers.mergeOptions)({ id: this.id }, options));
82 }
83 }, {
84 key: 'mergeNonInitialChunks',
85 value: function mergeNonInitialChunks(chunk, intoChunk, checkedChunks) {
86 var _this = this;
87
88 if (!intoChunk) {
89 checkedChunks = [];
90 chunk.chunks.forEach(function (c) {
91 if ((0, _helpers.isInitialOrHasNoParents)(c)) return;
92 _this.mergeNonInitialChunks(c, chunk, checkedChunks);
93 }, this);
94 } else if (checkedChunks.indexOf(chunk) < 0) {
95 checkedChunks.push(chunk);
96 chunk.forEachModule(function (module) {
97 intoChunk.addModule(module);
98 module.addChunk(intoChunk);
99 });
100 chunk.chunks.forEach(function (c) {
101 if ((0, _helpers.isInitialOrHasNoParents)(c)) return;
102 _this.mergeNonInitialChunks(c, intoChunk, checkedChunks);
103 }, this);
104 }
105 }
106 }, {
107 key: 'renderExtractedChunk',
108 value: function renderExtractedChunk(chunk) {
109 var _this2 = this;
110
111 var source = new _webpackSources.ConcatSource();
112 chunk.forEachModule(function (module) {
113 var moduleSource = module.source();
114 source.add(_this2.applyAdditionalInformation(moduleSource, module.additionalInformation));
115 }, this);
116 return source;
117 }
118 }, {
119 key: 'extract',
120 value: function extract(options) {
121 if (Array.isArray(options) || (0, _helpers.isString)(options) || typeof options.options === 'object' || typeof options.query === 'object') {
122 options = { use: options };
123 } else {
124 (0, _schemaUtils2.default)(_path2.default.resolve(__dirname, '../schema/loader.json'), options, 'Extract Text Plugin (Loader)');
125 }
126 var loader = options.use;
127 var before = options.fallback || [];
128 if ((0, _helpers.isString)(loader)) {
129 loader = loader.split('!');
130 }
131 if ((0, _helpers.isString)(before)) {
132 before = before.split('!');
133 } else if (!Array.isArray(before)) {
134 before = [before];
135 }
136 options = (0, _helpers.mergeOptions)({ omit: before.length, remove: true }, options);
137 delete options.use;
138 delete options.fallback;
139 return [this.loader(options)].concat(before, loader).map(_helpers.getLoaderObject);
140 }
141 }, {
142 key: 'apply',
143 value: function apply(compiler) {
144 var _this3 = this;
145
146 var options = this.options;
147 compiler.plugin('this-compilation', function (compilation) {
148 var extractCompilation = new _ExtractTextPluginCompilation2.default();
149 compilation.plugin('normal-module-loader', function (loaderContext, module) {
150 loaderContext[NS] = function (content, opt) {
151 if (options.disable) {
152 return false;
153 }
154 if (!Array.isArray(content) && content != null) {
155 throw new Error(`Exported value was not extracted as an array: ${JSON.stringify(content)}`);
156 }
157 module[NS] = {
158 content,
159 options: opt || {}
160 };
161 return options.allChunks || module[`${NS}/extract`]; // eslint-disable-line no-path-concat
162 };
163 });
164 var filename = _this3.filename;
165 var id = _this3.id;
166 var extractedChunks = void 0;
167 compilation.plugin('optimize-tree', function (chunks, modules, callback) {
168 extractedChunks = chunks.map(function () {
169 return new _Chunk2.default();
170 });
171 chunks.forEach(function (chunk, i) {
172 var extractedChunk = extractedChunks[i];
173 extractedChunk.index = i;
174 extractedChunk.originalChunk = chunk;
175 extractedChunk.name = chunk.name;
176 extractedChunk.entrypoints = chunk.entrypoints;
177 chunk.chunks.forEach(function (c) {
178 extractedChunk.addChunk(extractedChunks[chunks.indexOf(c)]);
179 });
180 chunk.parents.forEach(function (c) {
181 extractedChunk.addParent(extractedChunks[chunks.indexOf(c)]);
182 });
183 });
184 _async2.default.forEach(chunks, function (chunk, callback) {
185 // eslint-disable-line no-shadow
186 var extractedChunk = extractedChunks[chunks.indexOf(chunk)];
187 var shouldExtract = !!(options.allChunks || (0, _helpers.isInitialOrHasNoParents)(chunk));
188 chunk.sortModules();
189 _async2.default.forEach(chunk.mapModules(function (c) {
190 return c;
191 }), function (module, callback) {
192 // eslint-disable-line no-shadow
193 var meta = module[NS];
194 if (meta && (!meta.options.id || meta.options.id === id)) {
195 var wasExtracted = Array.isArray(meta.content);
196 // A stricter `shouldExtract !== wasExtracted` check to guard against cases where a previously extracted
197 // module would be extracted twice. Happens when a module is a dependency of an initial and a non-initial
198 // chunk. See issue #604
199 if (shouldExtract && !wasExtracted) {
200 module[`${NS}/extract`] = shouldExtract; // eslint-disable-line no-path-concat
201 compilation.rebuildModule(module, function (err) {
202 if (err) {
203 compilation.errors.push(err);
204 return callback();
205 }
206 meta = module[NS];
207 // Error out if content is not an array and is not null
208 if (!Array.isArray(meta.content) && meta.content != null) {
209 err = new Error(`${module.identifier()} doesn't export content`);
210 compilation.errors.push(err);
211 return callback();
212 }
213 if (meta.content) {
214 extractCompilation.addResultToChunk(module.identifier(), meta.content, module, extractedChunk);
215 }
216 callback();
217 });
218 } else {
219 if (meta.content) {
220 extractCompilation.addResultToChunk(module.identifier(), meta.content, module, extractedChunk);
221 }
222 callback();
223 }
224 } else callback();
225 }, function (err) {
226 if (err) return callback(err);
227 callback();
228 });
229 }, function (err) {
230 if (err) return callback(err);
231 extractedChunks.forEach(function (extractedChunk) {
232 if ((0, _helpers.isInitialOrHasNoParents)(extractedChunk)) {
233 _this3.mergeNonInitialChunks(extractedChunk);
234 }
235 }, _this3);
236 extractedChunks.forEach(function (extractedChunk) {
237 if (!(0, _helpers.isInitialOrHasNoParents)(extractedChunk)) {
238 extractedChunk.forEachModule(function (module) {
239 extractedChunk.removeModule(module);
240 });
241 }
242 });
243 compilation.applyPlugins('optimize-extracted-chunks', extractedChunks);
244 callback();
245 });
246 });
247 compilation.plugin('additional-assets', function (callback) {
248 extractedChunks.forEach(function (extractedChunk) {
249 if (extractedChunk.getNumberOfModules()) {
250 extractedChunk.sortModules(function (a, b) {
251 if (!options.ignoreOrder && (0, _helpers.isInvalidOrder)(a, b)) {
252 compilation.errors.push(new _OrderUndefinedError2.default(a.getOriginalModule()));
253 compilation.errors.push(new _OrderUndefinedError2.default(b.getOriginalModule()));
254 }
255 return (0, _helpers.getOrder)(a, b);
256 });
257 var chunk = extractedChunk.originalChunk;
258 var source = _this3.renderExtractedChunk(extractedChunk);
259
260 var getPath = function getPath(format) {
261 return compilation.getPath(format, {
262 chunk
263 }).replace(/\[(?:(\w+):)?contenthash(?::([a-z]+\d*))?(?::(\d+))?\]/ig, function () {
264 // eslint-disable-line func-names
265 return _loaderUtils2.default.getHashDigest(source.source(), arguments[1], arguments[2], parseInt(arguments[3], 10));
266 });
267 };
268
269 var file = (0, _helpers.isFunction)(filename) ? filename(getPath) : getPath(filename);
270
271 compilation.assets[file] = source;
272 chunk.files.push(file);
273 }
274 }, _this3);
275 callback();
276 });
277 });
278 }
279 }], [{
280 key: 'loader',
281 value: function loader(options) {
282 return { loader: require.resolve('./loader'), options };
283 }
284 }]);
285
286 return ExtractTextPlugin;
287}();
288
289ExtractTextPlugin.extract = ExtractTextPlugin.prototype.extract.bind(ExtractTextPlugin);
290
291exports.default = ExtractTextPlugin;
\No newline at end of file