UNPKG

31.9 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _setImmediate2 = require('babel-runtime/core-js/set-immediate');
8
9var _setImmediate3 = _interopRequireDefault(_setImmediate2);
10
11var _keys = require('babel-runtime/core-js/object/keys');
12
13var _keys2 = _interopRequireDefault(_keys);
14
15var _promise = require('babel-runtime/core-js/promise');
16
17var _promise2 = _interopRequireDefault(_promise);
18
19var _getIterator2 = require('babel-runtime/core-js/get-iterator');
20
21var _getIterator3 = _interopRequireDefault(_getIterator2);
22
23var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
24
25var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
26
27var _createClass2 = require('babel-runtime/helpers/createClass');
28
29var _createClass3 = _interopRequireDefault(_createClass2);
30
31var _path2 = require('path');
32
33var _path3 = _interopRequireDefault(_path2);
34
35var _fs = require('fs');
36
37var _fs2 = _interopRequireDefault(_fs);
38
39var _requireHacker = require('require-hacker');
40
41var _requireHacker2 = _interopRequireDefault(_requireHacker);
42
43var _uglifyJs = require('uglify-js');
44
45var _uglifyJs2 = _interopRequireDefault(_uglifyJs);
46
47var _log = require('./tools/log');
48
49var _log2 = _interopRequireDefault(_log);
50
51var _synchronousHttp = require('./tools/synchronous http');
52
53var _synchronousHttp2 = _interopRequireDefault(_synchronousHttp);
54
55var _helpers = require('./helpers');
56
57var _common = require('./common');
58
59function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
60
61// using ES6 template strings
62// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
63
64var webpack_isomorphic_tools = function () {
65 // require() hooks for assets
66
67 function webpack_isomorphic_tools(options) {
68 (0, _classCallCheck3.default)(this, webpack_isomorphic_tools);
69 this.hooks = [];
70 this.cached_assets = [];
71
72 // take the passed in options
73 this.options = (0, _helpers.convert_from_camel_case)((0, _helpers.clone)(options));
74
75 // add missing fields, etc
76 (0, _common.normalize_options)(this.options);
77
78 // set development mode flag
79 this.options.development = process.env.NODE_ENV !== 'production';
80
81 // set require-hacker debug mode if run in debug mode
82 if (this.options.debug) {
83 _requireHacker2.default.log.options.debug = true;
84 }
85
86 // logging
87 this.log = new _log2.default('webpack-isomorphic-tools', { debug: this.options.debug });
88
89 this.log.debug('instantiated webpack-isomorphic-tools v' + require('../package.json').version + ' with options', this.options);
90 }
91
92 // (deprecated)
93 // sets development mode flag to whatever was passed (or true if nothing was passed)
94 // (development mode allows asset hot reloading when used with webpack-dev-server)
95
96
97 // used to keep track of cached assets and flush their caches on .refresh() call
98
99
100 (0, _createClass3.default)(webpack_isomorphic_tools, [{
101 key: 'development',
102 value: function development() {
103 // display deprecation notice
104 this.log.error('`.development()` method is now deprecated ' + '(for server-side instance only, not for webpack plugin instance) ' + 'and has no effect. Set up a proper `process.env.NODE_ENV` variable instead: ' + 'it should be "production" for production, otherwise it assumes development. ' + 'The currently used mode is: ' + (this.options.development ? 'development' : 'production') + '. ' + '`process.env.NODE_ENV is: ' + process.env.NODE_ENV);
105
106 // allows method chaining
107 return this;
108 }
109
110 // returns a mapping to read file paths for all the user specified asset types
111 // along with a couple of predefined ones: javascripts and styles
112
113 }, {
114 key: 'assets',
115 value: function assets() {
116 // when in development mode
117 if (this.options.development) {
118 // webpack and node.js start in parallel
119 // so webpack-assets.json might not exist on the very first run
120 // if a developer chose not to use the .server() method with a callback
121 // (or if a developer chose not to wait for a Promise returned by the .server() method)
122
123 // either go over a network
124 if (this.options.port) {
125 try {
126 return (0, _synchronousHttp2.default)(this.options.port);
127 } catch (error) {
128 this.log.error('Couldn\'t contact webpack-isomorphic-tools plugin over HTTP. Using an empty stub for webpack assets map.');
129 this.log.error(error);
130 return (0, _common.default_webpack_assets)();
131 }
132 }
133 // or read it from disk
134 else {
135 if (!_fs2.default.existsSync(this.webpack_assets_path)) {
136 this.log.error('"' + this.webpack_assets_path + '" not found. Most likely it hasn\'t yet been generated by Webpack. The most probable cause of this error is that you placed your server code outside of the callback in "webpack_isomorphic_tools.server(path, callback)" (or outside of the ".then()" call if you are using promises API). Using an empty stub instead.');
137 return (0, _common.default_webpack_assets)();
138 }
139 }
140 }
141
142 // sanity check
143 if (!this.webpack_assets_path) {
144 throw new Error('You seem to have forgotten to call the .server() method');
145 }
146
147 return require(this.webpack_assets_path);
148 }
149
150 // clear the require.cache (only used in developer mode with webpack-dev-server)
151
152 }, {
153 key: 'refresh',
154 value: function refresh() {
155 // ensure this is development mode
156 if (!this.options.development) {
157 throw new Error('.refresh() called in production mode. It shouldn\'t be called in production mode because that would degrade website performance by discarding caches.');
158 }
159
160 this.log.debug('flushing require() caches');
161
162 // uncache webpack-assets.json file
163 // this.log.debug(' flushing require() cache for webpack assets json file')
164 // this.log.debug(` (was cached: ${typeof(require.cache[this.webpack_assets_path]) !== 'undefined'})`)
165 delete require.cache[this.webpack_assets_path];
166
167 // uncache cached assets
168 var _iteratorNormalCompletion = true;
169 var _didIteratorError = false;
170 var _iteratorError = undefined;
171
172 try {
173 for (var _iterator = (0, _getIterator3.default)(this.cached_assets), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
174 var _path = _step.value;
175
176 this.log.debug(' flushing require() cache for ' + _path);
177 delete require.cache[_path];
178 }
179
180 // no assets are cached now
181 } catch (err) {
182 _didIteratorError = true;
183 _iteratorError = err;
184 } finally {
185 try {
186 if (!_iteratorNormalCompletion && _iterator.return) {
187 _iterator.return();
188 }
189 } finally {
190 if (_didIteratorError) {
191 throw _iteratorError;
192 }
193 }
194 }
195
196 this.cached_assets = [];
197 }
198
199 // Makes `webpack-isomorphic-tools` aware of Webpack aliasing feature.
200 // https://webpack.github.io/docs/resolving.html#aliasing
201 // The `aliases` parameter corresponds to `resolve.alias`
202 // in your Webpack configuration.
203 // If this method is used it must be called before the `.server()` method.
204
205 }, {
206 key: 'enable_aliasing',
207 value: function enable_aliasing() {
208 var _this = this;
209
210 // mount require() hook
211 this.alias_hook = _requireHacker2.default.resolver(function (path, module) {
212 // returns aliased global filesystem path
213 return (0, _common.alias_hook)(path, module, _this.options.project_path, _this.options.alias, _this.log);
214 });
215
216 // allows method chaining
217 return this;
218 }
219
220 // Initializes server-side instance of `webpack-isomorphic-tools`
221 // with the base path for your project, then calls `.register()`,
222 // and after that calls .wait_for_assets(callback).
223 //
224 // The `project_path` parameter must be identical
225 // to the `context` parameter of your Webpack configuration
226 // and is needed to locate `webpack-assets.json`
227 // which is output by Webpack process.
228 //
229 // sets up "project_path" option
230 // (this option is required on the server to locate webpack-assets.json)
231
232 }, {
233 key: 'server',
234 value: function server(project_path, callback) {
235 var _this2 = this;
236
237 // project base path, required to locate webpack-assets.json
238 this.options.project_path = project_path;
239
240 // resolve webpack-assets.json file path
241 this.webpack_assets_path = _path3.default.resolve(this.options.project_path, this.options.webpack_assets_file_path);
242
243 // register require() hooks
244 this.register();
245
246 // if Webpack aliases are supplied, enable aliasing
247 if (this.options.alias) {
248 this.enable_aliasing();
249 }
250
251 // if Webpack `modulesDirectories` are supplied, enable them
252 if (this.options.modules_directories) {
253 this.inject_modules_directories(this.options.modules_directories);
254 }
255
256 // inject helpers like require.context() and require.ensure()
257 if (this.options.patch_require) {
258 this.log.debug('Patching Node.js require() function');
259 this.patch_require();
260 }
261
262 // when ready:
263
264 // if callback is given, call it back
265 if (callback) {
266 // call back when ready
267 return this.wait_for_assets(callback);
268 }
269 // otherwise resolve a Promise
270 else {
271 // no callback given, return a Promise
272 return new _promise2.default(function (resolve, reject) {
273 return _this2.wait_for_assets(resolve);
274 });
275 }
276 }
277
278 // Registers Node.js require() hooks for the assets
279 //
280 // This is what makes the `requre()` magic work on server.
281 // These `require()` hooks must be set before you `require()`
282 // any of your assets
283 // (e.g. before you `require()` any React components
284 // `require()`ing your assets).
285 //
286 // read this article if you don't know what a "require hook" is
287 // http://bahmutov.calepin.co/hooking-into-node-loader-for-fun-and-profit.html
288
289 }, {
290 key: 'register',
291 value: function register() {
292 var _this3 = this;
293
294 this.log.debug('registering require() hooks for assets');
295
296 // // a helper array for extension matching
297 // const extensions = []
298 //
299 // // for each user specified asset type,
300 // // for each file extension,
301 // // create an entry in the extension matching array
302 // for (let asset_type of Object.keys(this.options.assets))
303 // {
304 // const description = this.options.assets[asset_type]
305 //
306 // for (let extension of description.extensions)
307 // {
308 // extensions.push([`.${extension}`, description])
309 // }
310 // }
311 //
312 // // registers a global require() hook which runs
313 // // before the default Node.js require() logic
314 // this.asset_hook = require_hacker.global_hook('webpack-asset', (path, module) =>
315 // {
316 // // for each asset file extension
317 // for (let extension of extensions)
318 // {
319 // // if the require()d path has this file extension
320 // if (ends_with(path, extension[0]))
321 // {
322 // // then require() it using webpack-assets.json
323 // return this.require(require_hacker.resolve(path, module), extension[1])
324 // }
325 // }
326 // })
327
328 // for each user specified asset type,
329 // register a require() hook for each file extension of this asset type
330 var _iteratorNormalCompletion2 = true;
331 var _didIteratorError2 = false;
332 var _iteratorError2 = undefined;
333
334 try {
335 for (var _iterator2 = (0, _getIterator3.default)((0, _keys2.default)(this.options.assets)), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
336 var asset_type = _step2.value;
337
338 var description = this.options.assets[asset_type];
339
340 var _iteratorNormalCompletion3 = true;
341 var _didIteratorError3 = false;
342 var _iteratorError3 = undefined;
343
344 try {
345 for (var _iterator3 = (0, _getIterator3.default)(description.extensions), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
346 var extension = _step3.value;
347
348 this.register_extension(extension, description);
349 }
350 } catch (err) {
351 _didIteratorError3 = true;
352 _iteratorError3 = err;
353 } finally {
354 try {
355 if (!_iteratorNormalCompletion3 && _iterator3.return) {
356 _iterator3.return();
357 }
358 } finally {
359 if (_didIteratorError3) {
360 throw _iteratorError3;
361 }
362 }
363 }
364 }
365
366 // intercepts loader-powered require() paths
367 } catch (err) {
368 _didIteratorError2 = true;
369 _iteratorError2 = err;
370 } finally {
371 try {
372 if (!_iteratorNormalCompletion2 && _iterator2.return) {
373 _iterator2.return();
374 }
375 } finally {
376 if (_didIteratorError2) {
377 throw _iteratorError2;
378 }
379 }
380 }
381
382 this.loaders_hook = _requireHacker2.default.global_hook('webpack-loaders', function (required_path, module) {
383 // filter out non-loader paths
384 // (ignore filesystem paths (both Linux and Windows)
385 // and non-loader paths)
386 if ((0, _helpers.starts_with)(required_path, '/') || (0, _helpers.starts_with)(required_path, './') || (0, _helpers.starts_with)(required_path, '../') || required_path.indexOf(':') > 0 || required_path.indexOf('!') < 0) {
387 return;
388 }
389
390 var parts = required_path.split('!');
391 var local_asset_path = parts.pop();
392
393 // extra measures taken here to not
394 // confuse some legit require()d path
395 // with a seemingly loader-powered one
396 if (!(0, _helpers.starts_with)(local_asset_path, './') && !(0, _helpers.starts_with)(local_asset_path, '../')) {
397 return;
398 }
399
400 parts = parts.map(function (loader) {
401 var loader_parts = loader.split('?');
402
403 if (!(0, _helpers.ends_with)(loader_parts[0], '-loader')) {
404 loader_parts[0] += '-loader';
405 }
406
407 return './~/' + loader_parts.join('?');
408 });
409
410 var global_asset_path = _requireHacker2.default.resolve(local_asset_path, module);
411
412 var path = parts.join('!') + '!' + _this3.normalize_asset_path(global_asset_path);
413
414 var asset = _this3.asset_source(path);
415
416 if (asset === undefined) {
417 return;
418 }
419
420 return _this3.require_asset(asset, { require_cache_path: required_path + '.webpack-loaders' });
421 });
422
423 // allows method chaining
424 return this;
425 }
426
427 // registers a require hook for a particular file extension
428
429 }, {
430 key: 'register_extension',
431 value: function register_extension(extension, description) {
432 var _this4 = this;
433
434 this.log.debug(' registering a require() hook for *.' + extension);
435
436 // place the require() hook for this extension
437 if (extension === 'json') {
438 this.hooks.push(_requireHacker2.default.hook(extension, function (path) {
439 // special case for require('webpack-assets.json') and 'json' asset extension
440 if (path === _this4.webpack_assets_path) {
441 return;
442 }
443
444 return _this4.require(path, description);
445 }));
446 } else {
447 this.hooks.push(_requireHacker2.default.hook(extension, function (path) {
448 return _this4.require(path, description);
449 }));
450 }
451 }
452
453 // injects Webpack's `modulesDirectories` into Node.js module resolver
454
455 }, {
456 key: 'inject_modules_directories',
457 value: function inject_modules_directories(modules_directories) {
458 modules_directories = modules_directories.filter(function (x) {
459 return x !== 'node_modules';
460 });
461
462 // instrument Module._nodeModulePaths function
463 // https://github.com/nodejs/node/blob/master/lib/module.js#L202
464 //
465 var original_find_paths = require('module')._findPath;
466 //
467 require('module')._findPath = function (request, paths) {
468 paths.map(function (a_path) {
469 var parts = a_path.split(_path3.default.sep);
470 if (parts[parts.length - 1] === 'node_modules') {
471 parts[parts.length - 1] = '';
472 return parts.join(_path3.default.sep);
473 }
474 }).filter(function (a_path) {
475 return a_path;
476 }).forEach(function (a_path) {
477 modules_directories.forEach(function (modules_directory) {
478 paths.push(a_path + modules_directory);
479 });
480 });
481
482 return original_find_paths(request, paths);
483 };
484 }
485
486 // injects helper functions into `require()` function
487 // (such as `.context()` and `.ensure()`)
488 // https://github.com/halt-hammerzeit/webpack-isomorphic-tools/issues/48#issuecomment-182878437
489 // (this is a "dirty" way to do it but it works)
490
491 }, {
492 key: 'patch_require',
493 value: function patch_require() {
494 // a source code of a function that
495 // require()s all modules inside the `base` folder
496 // and puts them into a hash map for further reference
497 //
498 // https://webpack.github.io/docs/context.html
499 //
500 var require_context = 'require.context = function(base, scan_subdirectories, regular_expression)\n\t\t{\n\t\t\tbase = require(\'path\').join(require(\'path\').dirname(module.filename), base)\n\n\t\t\tvar contents = {}\n\n\t\t\t// recursive function\n\t\t\tfunction read_directory(directory)\n\t\t\t{\n\t\t\t\trequire(\'fs\').readdirSync(directory).forEach(function(child)\n\t\t\t\t{\n\t\t\t\t\tvar full_path = require(\'path\').resolve(directory, child)\n\n\t\t\t\t\tif (require(\'fs\').statSync(full_path).isDirectory())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (scan_subdirectories)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tread_directory(full_path)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvar asset_path = require(\'path\').relative(base, full_path)\n\n\t\t\t\t\t\t// analogous to "uniform_path" from "./common.js"\n\t\t\t\t\t\tasset_path = (asset_path[0] === \'.\' ? asset_path : (\'./\' + asset_path)).replace(/\\\\/g, \'/\')\n\n\t\t\t\t\t\tif (regular_expression && !regular_expression.test(asset_path))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontents[asset_path] = full_path\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tread_directory(base)\n\n\t\t\tvar result = function(asset_path)\n\t\t\t{\n\t\t\t\treturn require(contents[asset_path])\n\t\t\t}\n\n\t\t\tresult.keys = function()\n\t\t\t{\n\t\t\t\treturn Object.keys(contents)\n\t\t\t}\n\n\t\t\tresult.resolve = function(asset_path)\n\t\t\t{\n\t\t\t\treturn contents[asset_path]\n\t\t\t}\n\n\t\t\treturn result\n\t\t};';
501
502 // some code minification
503 require_context = _uglifyJs2.default.minify(require_context, { fromString: true }).code;
504
505 // Source code for `require.ensure()`
506 // https://github.com/halt-hammerzeit/webpack-isomorphic-tools/issues/84
507 var require_ensure = 'require.ensure=function(d,c){c(require)};';
508
509 var debug = this.log.debug.bind(this.log);
510
511 // instrument Module.prototype._compile function
512 // https://github.com/nodejs/node/blob/master/lib/module.js#L376-L380
513 //
514 var original_compile = require('module').prototype._compile;
515 //
516 require('module').prototype._compile = function (content, filename) {
517 // inject it only in .js files
518 if (!(0, _helpers.ends_with)(filename, '.js')) {
519 // (the return value is supposed to be `undefined`)
520 return original_compile.call(this, content, filename);
521 }
522
523 // will be prepended to the module source code
524 var preamble = '';
525
526 // inject it only in .js files which
527 // might probably have `require.context` reference
528 if (content.indexOf('require.context') >= 0) {
529 debug('Injecting require.context() into "' + filename + '"');
530 preamble += require_context;
531 }
532
533 // inject it only in .js files which
534 // might probably have `require.ensure` reference
535 if (content.indexOf('require.ensure') >= 0) {
536 debug('Injecting require.ensure() into "' + filename + '"');
537 preamble += require_ensure;
538 }
539
540 // If there is a preamble to prepend
541 if (preamble) {
542 // Account for "use strict" which is required to be in the beginning of the source code
543 if ((0, _helpers.starts_with)(content, '\'use strict\'') || (0, _helpers.starts_with)(content, '"use strict"')) {
544 preamble = '"use strict";' + preamble;
545 }
546 }
547
548 // the "dirty" way
549 content = preamble + content;
550
551 // (the return value is supposed to be `undefined`)
552 return original_compile.call(this, content, filename);
553 };
554 }
555 }, {
556 key: 'normalize_asset_path',
557 value: function normalize_asset_path(global_asset_path) {
558 // sanity check
559 /* istanbul ignore if */
560 if (!this.options.project_path) {
561 throw new Error('You forgot to call the .server() method passing it your project\'s base path');
562 }
563
564 // convert global asset path to local-to-the-project asset path
565 return (0, _common.normalize_asset_path)(global_asset_path, this.options.project_path);
566 }
567
568 // require()s an asset by a global path
569
570 }, {
571 key: 'require',
572 value: function require(global_asset_path, description) {
573 this.log.debug('require() called for ' + global_asset_path);
574
575 // convert global asset path to local-to-the-project asset path
576 var asset_path = this.normalize_asset_path(global_asset_path);
577
578 // if this filename is in the user specified exceptions list
579 // (or is not in the user explicitly specified inclusion list)
580 // then fall back to the normal require() behaviour
581 if (!this.includes(asset_path, description) || this.excludes(asset_path, description)) {
582 this.log.debug(' skipping require call for ' + asset_path);
583 return;
584 }
585
586 // find this asset in the list
587 var asset = this.asset_source(asset_path);
588
589 // if the asset was not found in the list, output an error
590 if (asset === undefined) {
591 this.log.error('asset not found: ' + asset_path);
592 }
593
594 return this.require_asset(asset, { require_cache_path: global_asset_path });
595 }
596
597 // require()s an asset by it source
598
599 }, {
600 key: 'require_asset',
601 value: function require_asset(asset, options) {
602 // this.log.debug(`require() called for ${asset_path}`)
603
604 // track cached assets (only in development mode)
605 if (this.options.development) {
606 // mark this asset as cached
607 this.cached_assets.push(options.require_cache_path);
608 }
609
610 // return CommonJS module source for this asset
611 return _requireHacker2.default.to_javascript_module_source(asset);
612 }
613
614 // returns asset source by path (looks it up in webpack-assets.json)
615
616 }, {
617 key: 'asset_source',
618 value: function asset_source(asset_path) {
619 this.log.debug(' requiring ' + asset_path);
620
621 // Webpack replaces `node_modules` with `~`.
622 // I don't know how exactly it decides whether to
623 // replace `node_modules` with `~` or not
624 // so it will be a guess.
625 function possible_webpack_paths(asset_path) {
626 // Webpack always replaces project's own `node_modules` with `~`
627 if ((0, _helpers.starts_with)(asset_path, './node_modules/')) {
628 asset_path = asset_path.replace('./node_modules/', './~/');
629 }
630
631 // if there are any `node_modules` left,
632 // supposing the count is N,
633 // then there are 2 to the power of N possible guesses
634 // on how webpack path might look like.
635 var parts = asset_path.split('/node_modules/');
636
637 function construct_guesses(parts) {
638 if (parts.length === 1) {
639 return [parts];
640 }
641
642 var last = parts.pop();
643 var rest = construct_guesses(parts);
644
645 var guesses = [];
646
647 var _iteratorNormalCompletion4 = true;
648 var _didIteratorError4 = false;
649 var _iteratorError4 = undefined;
650
651 try {
652 for (var _iterator4 = (0, _getIterator3.default)(rest), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
653 var guess = _step4.value;
654
655 var one = (0, _helpers.clone)(guess);
656 one.push('/~/');
657 one.push(last);
658
659 var two = (0, _helpers.clone)(guess);
660 two.push('/node_modules/');
661 two.push(last);
662
663 guesses.push(one);
664 guesses.push(two);
665 }
666 } catch (err) {
667 _didIteratorError4 = true;
668 _iteratorError4 = err;
669 } finally {
670 try {
671 if (!_iteratorNormalCompletion4 && _iterator4.return) {
672 _iterator4.return();
673 }
674 } finally {
675 if (_didIteratorError4) {
676 throw _iteratorError4;
677 }
678 }
679 }
680
681 return guesses;
682 }
683
684 return construct_guesses(parts);
685 }
686
687 // get real file path list
688 var assets = this.assets().assets;
689
690 var possible_webpack_asset_paths = possible_webpack_paths(asset_path).map(function (path) {
691 return path.join('');
692 });
693
694 var _iteratorNormalCompletion5 = true;
695 var _didIteratorError5 = false;
696 var _iteratorError5 = undefined;
697
698 try {
699 for (var _iterator5 = (0, _getIterator3.default)(possible_webpack_asset_paths), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
700 var webpack_asset_path = _step5.value;
701
702 if (possible_webpack_asset_paths.length > 1) {
703 this.log.debug(' trying "' + webpack_asset_path + '"');
704 }
705
706 // find this asset in the real file path list
707 var asset = assets[webpack_asset_path];
708
709 if ((0, _helpers.exists)(asset)) {
710 // the asset was found in the list - return it
711 return asset;
712 }
713 }
714
715 // if the asset was not found in the list, return nothing
716 } catch (err) {
717 _didIteratorError5 = true;
718 _iteratorError5 = err;
719 } finally {
720 try {
721 if (!_iteratorNormalCompletion5 && _iterator5.return) {
722 _iterator5.return();
723 }
724 } finally {
725 if (_didIteratorError5) {
726 throw _iteratorError5;
727 }
728 }
729 }
730
731 return;
732 }
733
734 // unregisters require() hooks
735
736 }, {
737 key: 'undo',
738 value: function undo() {
739 // for each user specified asset type,
740 // unregister a require() hook for each file extension of this asset type
741 var _iteratorNormalCompletion6 = true;
742 var _didIteratorError6 = false;
743 var _iteratorError6 = undefined;
744
745 try {
746 for (var _iterator6 = (0, _getIterator3.default)(this.hooks), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
747 var hook = _step6.value;
748
749 hook.unmount();
750 }
751
752 // this.asset_hook.unmount()
753
754 // unmount the aliasing hook (if mounted)
755 } catch (err) {
756 _didIteratorError6 = true;
757 _iteratorError6 = err;
758 } finally {
759 try {
760 if (!_iteratorNormalCompletion6 && _iterator6.return) {
761 _iterator6.return();
762 }
763 } finally {
764 if (_didIteratorError6) {
765 throw _iteratorError6;
766 }
767 }
768 }
769
770 if (this.alias_hook) {
771 this.alias_hook.unmount();
772 }
773
774 // unmount require() hook which intercepts loader-powered require() paths
775 if (this.loaders_hook) {
776 this.loaders_hook.unmount();
777 }
778 }
779
780 // Checks if the required path should be excluded from the custom require() hook
781
782 }, {
783 key: 'excludes',
784 value: function excludes(path, options) {
785 // if "exclude" parameter isn't specified, then exclude nothing
786 if (!(0, _helpers.exists)(options.exclude)) {
787 return false;
788 }
789
790 // for each exclusion case
791 var _iteratorNormalCompletion7 = true;
792 var _didIteratorError7 = false;
793 var _iteratorError7 = undefined;
794
795 try {
796 for (var _iterator7 = (0, _getIterator3.default)(options.exclude), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
797 var exclude = _step7.value;
798
799 // supports regular expressions
800 if (exclude instanceof RegExp) {
801 if (exclude.test(path)) {
802 return true;
803 }
804 }
805 // check for a compex logic match
806 else if (typeof exclude === 'function') {
807 if (exclude(path)) {
808 return true;
809 }
810 }
811 // otherwise check for a simple textual match
812 else {
813 if (exclude === path) {
814 return true;
815 }
816 }
817 }
818
819 // no matches found.
820 // returns false so that it isn't undefined (for testing purpose)
821 } catch (err) {
822 _didIteratorError7 = true;
823 _iteratorError7 = err;
824 } finally {
825 try {
826 if (!_iteratorNormalCompletion7 && _iterator7.return) {
827 _iterator7.return();
828 }
829 } finally {
830 if (_didIteratorError7) {
831 throw _iteratorError7;
832 }
833 }
834 }
835
836 return false;
837 }
838
839 // Checks if the required path should be included in the custom require() hook
840
841 }, {
842 key: 'includes',
843 value: function includes(path, options) {
844 // if "include" parameter isn't specified, then include everything
845 if (!(0, _helpers.exists)(options.include)) {
846 return true;
847 }
848
849 // for each inclusion case
850 var _iteratorNormalCompletion8 = true;
851 var _didIteratorError8 = false;
852 var _iteratorError8 = undefined;
853
854 try {
855 for (var _iterator8 = (0, _getIterator3.default)(options.include), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
856 var include = _step8.value;
857
858 // supports regular expressions
859 if (include instanceof RegExp) {
860 if (include.test(path)) {
861 return true;
862 }
863 }
864 // check for a compex logic match
865 else if (typeof include === 'function') {
866 if (include(path)) {
867 return true;
868 }
869 }
870 // otherwise check for a simple textual match
871 else {
872 if (include === path) {
873 return true;
874 }
875 }
876 }
877
878 // no matches found.
879 // returns false so that it isn't undefined (for testing purpose)
880 } catch (err) {
881 _didIteratorError8 = true;
882 _iteratorError8 = err;
883 } finally {
884 try {
885 if (!_iteratorNormalCompletion8 && _iterator8.return) {
886 _iterator8.return();
887 }
888 } finally {
889 if (_didIteratorError8) {
890 throw _iteratorError8;
891 }
892 }
893 }
894
895 return false;
896 }
897
898 // Waits for webpack-assets.json to be created after Webpack build process finishes
899 //
900 // The callback is called when `webpack-assets.json` has been found
901 // (it's needed for development because `webpack-dev-server`
902 // and your application server are usually run in parallel).
903 //
904
905 }, {
906 key: 'wait_for_assets',
907 value: function wait_for_assets(done) {
908 var _this5 = this;
909
910 // condition check interval
911 var check_interval = 300; // in milliseconds
912 var message_interval = 2000; // in milliseconds
913
914 // show the message not too often
915 var message_timer = 0;
916
917 // selfie
918 var tools = this;
919
920 // waits for condition to be met, then proceeds
921 function wait_for(condition, proceed) {
922 function check() {
923 // if the condition is met, then proceed
924 if (condition()) {
925 return proceed();
926 }
927
928 message_timer += check_interval;
929
930 if (message_timer >= message_interval) {
931 message_timer = 0;
932
933 tools.log.debug('(' + tools.webpack_assets_path + ' not found)');
934 tools.log.info('(waiting for the first Webpack build to finish)');
935 }
936
937 setTimeout(check, check_interval);
938 }
939
940 check();
941 }
942
943 // wait for webpack-assets.json to be written to disk by Webpack
944 // (setTimeout() for global.webpack_isomorphic_tools )
945
946 var ready_check = void 0;
947
948 // either go over network
949 if (this.options.development && this.options.port) {
950 ready_check = function ready_check() {
951 try {
952 (0, _synchronousHttp2.default)(_this5.options.port);
953 return true;
954 } catch (error) {
955 if (!(0, _helpers.starts_with)(error.message, 'Server responded with status code 404:\nWebpack assets not generated yet') && !(0, _helpers.starts_with)(error.message, 'connect ECONNREFUSED') && !(0, _helpers.starts_with)(error.message, 'Request timed out after')) {
956 _this5.log.error('Couldn\'t contact webpack-isomorphic-tools plugin over HTTP. Using an empty stub for webpack assets map.');
957 _this5.log.error(error);
958 }
959
960 return false;
961 }
962 };
963 }
964 // or read it from disk
965 else {
966 ready_check = function ready_check() {
967 return _fs2.default.existsSync(_this5.webpack_assets_path);
968 };
969 }
970
971 (0, _setImmediate3.default)(function () {
972 return wait_for(ready_check, done);
973 });
974
975 // allows method chaining
976 return this;
977 }
978 }]);
979 return webpack_isomorphic_tools;
980}();
981
982// Doesn't work with Babel 6 compiler
983// // alias camel case for those who prefer it
984// alias_properties_with_camel_case(webpack_isomorphic_tools.prototype)
985
986
987exports.default = webpack_isomorphic_tools;
988module.exports = exports['default'];
989//# sourceMappingURL=index.js.map
\No newline at end of file