1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _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 |
|
9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
10 |
|
11 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
12 |
|
13 | var _appCache = require('./app-cache');
|
14 |
|
15 | var _appCache2 = _interopRequireDefault(_appCache);
|
16 |
|
17 | var _serviceWorker = require('./service-worker');
|
18 |
|
19 | var _serviceWorker2 = _interopRequireDefault(_serviceWorker);
|
20 |
|
21 | var _defaultOptions = require('./default-options');
|
22 |
|
23 | var _defaultOptions2 = _interopRequireDefault(_defaultOptions);
|
24 |
|
25 | var _miscUtils = require('./misc/utils');
|
26 |
|
27 | var _path2 = require('path');
|
28 |
|
29 | var _path3 = _interopRequireDefault(_path2);
|
30 |
|
31 | var _url = require('url');
|
32 |
|
33 | var _url2 = _interopRequireDefault(_url);
|
34 |
|
35 | var _deepExtend = require('deep-extend');
|
36 |
|
37 | var _deepExtend2 = _interopRequireDefault(_deepExtend);
|
38 |
|
39 | var _minimatch = require('minimatch');
|
40 |
|
41 | var _minimatch2 = _interopRequireDefault(_minimatch);
|
42 |
|
43 | var _loaderUtils = require('loader-utils');
|
44 |
|
45 | var _loaderUtils2 = _interopRequireDefault(_loaderUtils);
|
46 |
|
47 | var _slash = require('slash');
|
48 |
|
49 | var _slash2 = _interopRequireDefault(_slash);
|
50 |
|
51 | var _require = require('../package.json');
|
52 |
|
53 | var pluginVersion = _require.version;
|
54 |
|
55 | var hasOwn = ({}).hasOwnProperty;
|
56 | var updateStrategies = ['all', 'hash', 'changed'];
|
57 |
|
58 | var OfflinePlugin = (function () {
|
59 | function OfflinePlugin(options) {
|
60 | var _this = this;
|
61 |
|
62 | _classCallCheck(this, OfflinePlugin);
|
63 |
|
64 | var AppCacheOptions = options ? options.AppCache : void 0;
|
65 |
|
66 | this.options = (0, _deepExtend2['default'])({}, _defaultOptions2['default'], options, {
|
67 | AppCache: false
|
68 | });
|
69 |
|
70 | this.hash = null;
|
71 | this.assets = null;
|
72 | this.hashesMap = null;
|
73 | this.externals = null;
|
74 | this.publicPath = this.options.publicPath;
|
75 | this.strategy = this.options.updateStrategy;
|
76 | this.responseStrategy = this.options.responseStrategy;
|
77 | this.relativePaths = this.options.relativePaths;
|
78 | this.pluginVersion = pluginVersion;
|
79 | this.warnings = [];
|
80 | this.errors = [];
|
81 |
|
82 | this.__tests = this.options.__tests;
|
83 | this.flags = {};
|
84 |
|
85 | var appCacheEnabled = !!(AppCacheOptions || this.__tests.appCacheEnabled);
|
86 |
|
87 | if (appCacheEnabled) {
|
88 | this.options.AppCache = (0, _deepExtend2['default'])({}, _defaultOptions.AppCacheOptions, AppCacheOptions);
|
89 | }
|
90 |
|
91 | if (this.__tests.pluginVersion) {
|
92 | this.pluginVersion = this.__tests.pluginVersion;
|
93 | }
|
94 |
|
95 | var autoUpdate = this.options.autoUpdate;
|
96 |
|
97 | if (autoUpdate === true) {
|
98 | this.autoUpdate = _defaultOptions.DEFAULT_AUTO_UPDATE_INTERVAL;
|
99 | } else if (typeof autoUpdate === 'number' && autoUpdate) {
|
100 | this.autoUpdate = autoUpdate;
|
101 | }
|
102 |
|
103 | if (this.options.responseStrategy !== "cache-first" && this.options.responseStrategy !== "network-first") {
|
104 | throw new Error('OfflinePlugin: `responseStrategy` option must use ' + '`cache-first` or `network-first` (or be undefined).');
|
105 | }
|
106 |
|
107 | if (typeof this.publicPath !== 'string') {
|
108 | this.publicPath = null;
|
109 | }
|
110 |
|
111 | if (updateStrategies.indexOf(this.strategy) === -1) {
|
112 | throw new Error('Update strategy must be one of [' + updateStrategies + ']');
|
113 | } else if (this.strategy === 'hash') {
|
114 | this.warnings.push(new Error('OfflinePlugin: `hash` update strategy is deprecated, use `all` strategy and { version: "[hash]" } instead'));
|
115 |
|
116 | this.strategy = 'all';
|
117 | this.options.version = '[hash]';
|
118 | }
|
119 |
|
120 | if (!Array.isArray(this.options.externals)) {
|
121 | this.options.externals = [];
|
122 | }
|
123 |
|
124 | var rewrites = this.options.rewrites || _defaultOptions2['default'].rewrites;
|
125 |
|
126 | if (typeof rewrites === 'function') {
|
127 | this.rewrite = function (asset) {
|
128 | if (asset.indexOf(_this.entryPrefix) === 0) {
|
129 | return '';
|
130 | }
|
131 |
|
132 | return rewrites(asset);
|
133 | };
|
134 | } else {
|
135 | this.rewrite = function (asset) {
|
136 | if (asset.indexOf(_this.entryPrefix) === 0) {
|
137 | return '';
|
138 | }
|
139 |
|
140 | if (!hasOwn.call(rewrites, asset)) {
|
141 | return asset;
|
142 | }
|
143 |
|
144 | return rewrites[asset];
|
145 | };
|
146 | }
|
147 |
|
148 | if (this.options.appShell && typeof this.options.appShell === 'string') {
|
149 | this.appShell = this.options.appShell;
|
150 | }
|
151 |
|
152 | var cacheMaps = this.options.cacheMaps;
|
153 |
|
154 | if (this.appShell) {
|
155 |
|
156 | cacheMaps = (cacheMaps || []).concat({
|
157 | match: new Function('return new URL(' + JSON.stringify(this.appShell) + ', location);'),
|
158 | requestTypes: ['navigate']
|
159 | });
|
160 | }
|
161 |
|
162 | this.cacheMaps = this.stringifyCacheMaps(cacheMaps);
|
163 |
|
164 | this.REST_KEY = ':rest:';
|
165 | this.EXTERNALS_KEY = ':externals:';
|
166 | this.entryPrefix = '__offline_';
|
167 | this.tools = {};
|
168 |
|
169 | this.addTool(_serviceWorker2['default'], 'ServiceWorker');
|
170 | this.addTool(_appCache2['default'], 'AppCache');
|
171 |
|
172 | if (!Object.keys(this.tools).length) {
|
173 | throw new Error('You should have at least one cache service to be specified');
|
174 | }
|
175 | }
|
176 |
|
177 | _createClass(OfflinePlugin, [{
|
178 | key: 'apply',
|
179 | value: function apply(compiler) {
|
180 | var _this2 = this;
|
181 |
|
182 | var runtimePath = _path3['default'].resolve(__dirname, '../runtime.js');
|
183 | var compilerOptions = compiler.options;
|
184 |
|
185 | if (this.relativePaths === true) {
|
186 | this.publicPath = null;
|
187 | }
|
188 |
|
189 | if (typeof this.publicPath !== 'string' && compilerOptions && compilerOptions.output && compilerOptions.output.publicPath && this.relativePaths !== true) {
|
190 | this.publicPath = compilerOptions.output.publicPath;
|
191 | this.relativePaths = false;
|
192 | }
|
193 |
|
194 | if (this.publicPath) {
|
195 | this.publicPath = this.publicPath.replace(/\/$/, '') + '/';
|
196 | }
|
197 |
|
198 | if (this.relativePaths === true && this.publicPath) {
|
199 | this.errors.push(new Error('OfflinePlugin: `publicPath` is used in conjunction with `relativePaths`,\n' + 'choose one of it'));
|
200 |
|
201 | this.relativePaths = false;
|
202 | }
|
203 |
|
204 | if (this.relativePaths === _defaultOptions2['default'].relativePaths) {
|
205 | this.relativePaths = !this.publicPath;
|
206 | }
|
207 |
|
208 | this.useTools(function (tool, key) {
|
209 | _this2.resolveToolPaths(tool, key, compiler);
|
210 | });
|
211 |
|
212 | var afterResolveFn = function afterResolveFn(result, callback) {
|
213 | var resource = _path3['default'].resolve(compiler.context, result.resource);
|
214 |
|
215 | if (resource !== runtimePath) {
|
216 | callback(null, result);
|
217 | return;
|
218 | }
|
219 |
|
220 | var data = {
|
221 | autoUpdate: _this2.autoUpdate
|
222 | };
|
223 |
|
224 | _this2.useTools(function (tool, key) {
|
225 | data[key] = tool.getConfig(_this2);
|
226 | });
|
227 |
|
228 | result.loaders.push(_path3['default'].join(__dirname, 'misc/runtime-loader.js') + '?' + JSON.stringify(data));
|
229 |
|
230 | callback(null, result);
|
231 | };
|
232 |
|
233 | var makeFn = function makeFn(compilation, callback) {
|
234 | if (_this2.warnings.length) {
|
235 | [].push.apply(compilation.warnings, _this2.warnings);
|
236 | }
|
237 |
|
238 | if (_this2.errors.length) {
|
239 | [].push.apply(compilation.errors, _this2.errors);
|
240 | }
|
241 |
|
242 | _this2.useTools(function (tool) {
|
243 | return tool.addEntry(_this2, compilation, compiler);
|
244 | }).then(function () {
|
245 | callback();
|
246 | })['catch'](function (e) {
|
247 | throw e || new Error('Something went wrong');
|
248 | });
|
249 | };
|
250 |
|
251 | var emitFn = function emitFn(compilation, callback) {
|
252 | var runtimeTemplatePath = _path3['default'].resolve(__dirname, '../tpls/runtime-template.js');
|
253 | var hasRuntime = true;
|
254 |
|
255 | if (compilation.fileDependencies.indexOf) {
|
256 | hasRuntime = compilation.fileDependencies.indexOf(runtimeTemplatePath) !== -1;
|
257 | } else if (compilation.fileDependencies.has) {
|
258 | hasRuntime = compilation.fileDependencies.has(runtimeTemplatePath);
|
259 | }
|
260 |
|
261 | if (!hasRuntime && !_this2.__tests.ignoreRuntime) {
|
262 | compilation.errors.push(new Error('OfflinePlugin: Plugin\'s runtime wasn\'t added to one of your bundle entries. See this https://goo.gl/YwewYp for details.'));
|
263 | callback();
|
264 | return;
|
265 | }
|
266 |
|
267 | var stats = compilation.getStats().toJson();
|
268 |
|
269 |
|
270 |
|
271 | try {
|
272 | _this2.setAssets(compilation);
|
273 | _this2.setHashesMap(compilation);
|
274 |
|
275 |
|
276 | _this2.hash = _loaderUtils2['default'].getHashDigest(Object.keys(_this2.hashesMap).join(''), 'sha1');
|
277 |
|
278 |
|
279 |
|
280 | } catch (e) {
|
281 | callback(e);
|
282 | return;
|
283 | }
|
284 |
|
285 | _this2.useTools(function (tool) {
|
286 | return tool.apply(_this2, compilation, compiler);
|
287 | }).then(function () {
|
288 | callback();
|
289 | }, function () {
|
290 | callback(new Error('Something went wrong'));
|
291 | });
|
292 | };
|
293 |
|
294 | if (compiler.hooks) {
|
295 | (function () {
|
296 | var plugin = { name: 'OfflinePlugin' };
|
297 |
|
298 | compiler.hooks.normalModuleFactory.tap(plugin, function (nmf) {
|
299 | nmf.hooks.afterResolve.tapAsync(plugin, afterResolveFn);
|
300 | });
|
301 |
|
302 | compiler.hooks.make.tapAsync(plugin, makeFn);
|
303 | compiler.hooks.emit.tapAsync(plugin, emitFn);
|
304 | })();
|
305 | } else {
|
306 | compiler.plugin('normal-module-factory', function (nmf) {
|
307 | nmf.plugin('after-resolve', afterResolveFn);
|
308 | });
|
309 |
|
310 | compiler.plugin('make', makeFn);
|
311 | compiler.plugin('emit', emitFn);
|
312 | }
|
313 | }
|
314 | }, {
|
315 | key: 'setAssets',
|
316 | value: function setAssets(compilation) {
|
317 | var _this3 = this;
|
318 |
|
319 | var caches = this.options.caches || _defaultOptions2['default'].caches;
|
320 |
|
321 | if (this.options.safeToUseOptionalCaches !== true && (caches.additional && caches.additional.length || caches.optional && caches.optional.length)) {
|
322 | compilation.warnings.push(new Error('OfflinePlugin: Cache sections `additional` and `optional` could be used ' + 'only when each asset passed to it has unique name (e.g. hash or version in it) and ' + 'is permanently available for given URL. If you think that it\'s your case, ' + 'set `safeToUseOptionalCaches` option to `true`, to remove this warning.'));
|
323 | }
|
324 |
|
325 | var excludes = this.options.excludes;
|
326 | var assets = Object.keys(compilation.assets);
|
327 | var externals = this.options.externals;
|
328 |
|
329 | if (Array.isArray(excludes) && excludes.length) {
|
330 | assets = assets.filter(function (asset) {
|
331 | if (excludes.some(function (glob) {
|
332 | if ((0, _minimatch2['default'])(asset, glob)) {
|
333 | return true;
|
334 | }
|
335 | })) {
|
336 | return false;
|
337 | }
|
338 |
|
339 | return true;
|
340 | });
|
341 | }
|
342 |
|
343 | this.externals = this.validatePaths(externals);
|
344 |
|
345 | if (caches === 'all') {
|
346 | this.assets = this.validatePaths(assets).concat(this.externals);
|
347 | this.caches = {
|
348 | main: this.assets.concat()
|
349 | };
|
350 | } else {
|
351 | (function () {
|
352 | var restSection = undefined;
|
353 | var externalsSection = undefined;
|
354 |
|
355 | var handledCaches = ['main', 'additional', 'optional'].reduce(function (result, key) {
|
356 | var cache = Array.isArray(caches[key]) ? caches[key] : [];
|
357 |
|
358 | if (!cache.length) {
|
359 | result[key] = cache;
|
360 | return result;
|
361 | }
|
362 |
|
363 | var cacheResult = [];
|
364 |
|
365 | cache.some(function (cacheKey) {
|
366 | if (cacheKey === _this3.REST_KEY) {
|
367 | if (restSection) {
|
368 | throw new Error('The ' + _this3.REST_KEY + ' keyword can be used only once');
|
369 | }
|
370 |
|
371 | restSection = key;
|
372 | return;
|
373 | }
|
374 |
|
375 | if (cacheKey === _this3.EXTERNALS_KEY) {
|
376 | if (externalsSection) {
|
377 | throw new Error('The ' + _this3.EXTERNALS_KEY + ' keyword can be used only once');
|
378 | }
|
379 |
|
380 | externalsSection = key;
|
381 | return;
|
382 | }
|
383 |
|
384 | var magic = undefined;
|
385 |
|
386 | if (typeof cacheKey === 'string') {
|
387 | magic = !(0, _miscUtils.isAbsoluteURL)(cacheKey) && cacheKey[0] !== '/' && cacheKey.indexOf('./') !== 0 && (0, _miscUtils.hasMagic)(cacheKey);
|
388 | } else if (cacheKey instanceof RegExp) {
|
389 | magic = (0, _miscUtils.hasMagic)(cacheKey);
|
390 | } else {
|
391 |
|
392 | return;
|
393 | }
|
394 |
|
395 | if (magic) {
|
396 | var matched = undefined;
|
397 |
|
398 | for (var i = 0, len = assets.length; i < len; i++) {
|
399 | if (!magic.match(assets[i])) continue;
|
400 |
|
401 | matched = true;
|
402 | cacheResult.push(assets[i]);
|
403 | assets.splice(i, 1);
|
404 | i--, len--;
|
405 | }
|
406 |
|
407 | if (!matched) {
|
408 | compilation.warnings.push(new Error('OfflinePlugin: Cache pattern [' + cacheKey + '] did not match any assets'));
|
409 | }
|
410 |
|
411 | return;
|
412 | }
|
413 |
|
414 | var index = assets.indexOf(cacheKey);
|
415 |
|
416 | __EXTERNALS_CHECK: if (index === -1) {
|
417 | var externalsIndex = externals.indexOf(cacheKey);
|
418 |
|
419 | if (externalsIndex !== -1) {
|
420 | externals.splice(externalsIndex, 1);
|
421 | break __EXTERNALS_CHECK;
|
422 | }
|
423 |
|
424 | compilation.warnings.push(new Error('OfflinePlugin: Cache asset [' + cacheKey + '] is not found in the output assets, ' + 'if the asset is not processed by webpack, move it to the |externals| option to remove this warning.'));
|
425 | } else {
|
426 | assets.splice(index, 1);
|
427 | }
|
428 |
|
429 | cacheResult.push(cacheKey);
|
430 | });
|
431 |
|
432 | result[key] = _this3.validatePaths(cacheResult);
|
433 |
|
434 | return result;
|
435 | }, {});
|
436 |
|
437 | if (restSection && assets.length) {
|
438 | handledCaches[restSection] = handledCaches[restSection].concat(_this3.validatePaths(assets));
|
439 | }
|
440 |
|
441 | if (externalsSection && externals.length) {
|
442 | handledCaches[externalsSection] = handledCaches[externalsSection].concat(_this3.validatePaths(externals));
|
443 | }
|
444 |
|
445 | _this3.caches = handledCaches;
|
446 | _this3.assets = [].concat(_this3.caches.main, _this3.caches.additional, _this3.caches.optional);
|
447 | })();
|
448 | }
|
449 | }
|
450 | }, {
|
451 | key: 'setHashesMap',
|
452 | value: function setHashesMap(compilation) {
|
453 | var _this4 = this;
|
454 |
|
455 | this.hashesMap = {};
|
456 |
|
457 | Object.keys(compilation.assets).forEach(function (key) {
|
458 | var validatedPath = _this4.validatePaths([key])[0];
|
459 |
|
460 | if (typeof validatedPath !== 'string' || _this4.assets.indexOf(validatedPath) === -1) return;
|
461 |
|
462 | var hash = _loaderUtils2['default'].getHashDigest(compilation.assets[key].source(), 'sha1');
|
463 |
|
464 | _this4.hashesMap[hash] = validatedPath;
|
465 | });
|
466 | }
|
467 | }, {
|
468 | key: 'setNetworkOptions',
|
469 | value: function setNetworkOptions() {
|
470 | var alwaysRevalidate = this.options.alwaysRevalidate;
|
471 | var preferOnline = this.options.preferOnline;
|
472 | var ignoreSearch = this.options.ignoreSearch;
|
473 |
|
474 | var assets = this.assets;
|
475 |
|
476 |
|
477 | if (Array.isArray(alwaysRevalidate) && alwaysRevalidate.length) {
|
478 | alwaysRevalidate = assets.filter(function (asset) {
|
479 | if (alwaysRevalidate.some(function (glob) {
|
480 | if ((0, _minimatch2['default'])(asset, glob)) {
|
481 | return true;
|
482 | }
|
483 | })) {
|
484 | return true;
|
485 | }
|
486 |
|
487 | return false;
|
488 | });
|
489 |
|
490 | if (alwaysRevalidate.length) {
|
491 | this.alwaysRevalidate = alwaysRevalidate;
|
492 | }
|
493 | }
|
494 |
|
495 | if (Array.isArray(ignoreSearch) && ignoreSearch.length) {
|
496 | ignoreSearch = assets.filter(function (asset) {
|
497 | if (ignoreSearch.some(function (glob) {
|
498 | if ((0, _minimatch2['default'])(asset, glob)) {
|
499 | return true;
|
500 | }
|
501 | })) {
|
502 | return true;
|
503 | }
|
504 |
|
505 | return false;
|
506 | });
|
507 |
|
508 | if (ignoreSearch.length) {
|
509 | this.ignoreSearch = ignoreSearch;
|
510 | }
|
511 | }
|
512 |
|
513 | if (Array.isArray(preferOnline) && preferOnline.length) {
|
514 | preferOnline = assets.filter(function (asset) {
|
515 | if (preferOnline.some(function (glob) {
|
516 | if ((0, _minimatch2['default'])(asset, glob)) {
|
517 | return true;
|
518 | }
|
519 | })) {
|
520 | return true;
|
521 | }
|
522 |
|
523 | return false;
|
524 | });
|
525 |
|
526 | if (preferOnline.length) {
|
527 | this.preferOnline = preferOnline;
|
528 | }
|
529 | }
|
530 | }
|
531 | }, {
|
532 | key: 'stringifyCacheMaps',
|
533 | value: function stringifyCacheMaps(cacheMaps) {
|
534 | if (!cacheMaps) {
|
535 | return [];
|
536 | }
|
537 |
|
538 | return cacheMaps.map(function (map) {
|
539 | if (map.to != null && typeof map.to !== 'string' && typeof map.to !== 'function') {
|
540 | throw new Error('cacheMaps `to` property must either string, function, undefined or null');
|
541 | }
|
542 |
|
543 | if (map.requestTypes != null) {
|
544 | if (Array.isArray(map.requestTypes)) {
|
545 | var types = map.requestTypes.filter(function (item) {
|
546 | if (item === 'navigate' || item === 'same-origin' || item === 'cross-origin') {
|
547 | return false;
|
548 | }
|
549 |
|
550 | return true;
|
551 | });
|
552 |
|
553 | if (types.length) {
|
554 | throw new Error("cacheMaps `requestTypes` array values could be only: 'navigate', 'same-origin' or 'cross-origin'");
|
555 | }
|
556 | } else {
|
557 | throw new Error('cacheMaps `requestTypes` property must either array, undefined or null');
|
558 | }
|
559 | }
|
560 |
|
561 | var to = undefined;
|
562 | var match = undefined;
|
563 |
|
564 | if (typeof map.to === 'function') {
|
565 | to = (0, _miscUtils.functionToString)(map.to);
|
566 | } else {
|
567 | to = map.to ? JSON.stringify(map.to) : null;
|
568 | }
|
569 |
|
570 | if (typeof map.match === 'function') {
|
571 | match = (0, _miscUtils.functionToString)(map.match);
|
572 | } else {
|
573 | match = map.match + '';
|
574 | }
|
575 |
|
576 | return {
|
577 | match: match,
|
578 | to: to,
|
579 | requestTypes: map.requestTypes || null
|
580 | };
|
581 | });
|
582 | }
|
583 | }, {
|
584 | key: 'resolveToolPaths',
|
585 | value: function resolveToolPaths(tool, key, compiler) {
|
586 |
|
587 |
|
588 |
|
589 |
|
590 |
|
591 |
|
592 |
|
593 |
|
594 | if (!this.relativePaths && !this.publicPath) {
|
595 | throw new Error('OfflinePlugin: Cannot generate base path for ' + key);
|
596 | }
|
597 |
|
598 | var isDirectory = tool.output[tool.output.length - 1] === '/';
|
599 |
|
600 | if (this.relativePaths) {
|
601 | var compilerOutput = (compiler.options.output || { path: process.cwd() }).path;
|
602 | var absoluteOutput = _path3['default'].resolve(compilerOutput, tool.output);
|
603 |
|
604 | var relativeBase = undefined;
|
605 |
|
606 | if (isDirectory) {
|
607 | relativeBase = _path3['default'].relative(absoluteOutput, compilerOutput);
|
608 | } else {
|
609 | relativeBase = _path3['default'].relative(_path3['default'].dirname(absoluteOutput), compilerOutput);
|
610 | }
|
611 |
|
612 | relativeBase = (0, _slash2['default'])(relativeBase);
|
613 | relativeBase = relativeBase.replace(/\/$/, '');
|
614 |
|
615 | if (relativeBase) {
|
616 | relativeBase = relativeBase + '/';
|
617 | }
|
618 |
|
619 | tool.basePath = relativeBase[0] === '.' ? relativeBase : './' + relativeBase;
|
620 | } else if (this.publicPath) {
|
621 | tool.basePath = this.publicPath.replace(/\/$/, '') + '/';
|
622 | }
|
623 |
|
624 | if (this.relativePaths) {
|
625 | tool.location = tool.output;
|
626 | } else if (this.publicPath && tool.publicPath) {
|
627 | tool.location = tool.publicPath;
|
628 | } else if (this.publicPath) {
|
629 | var publicUrl = _url2['default'].parse(this.publicPath);
|
630 | var publicPath = publicUrl.pathname;
|
631 |
|
632 | publicUrl.pathname = _path3['default'].join(publicPath, tool.output);
|
633 | var outerPathname = _path3['default'].join('/outer/', publicPath, tool.output);
|
634 |
|
635 | if (outerPathname.indexOf('/outer/') !== 0) {
|
636 | new Error('OfflinePlugin: Wrong ' + key + '.output value. Final ' + key + '.location URL path bounds are outside of publicPath');
|
637 | }
|
638 |
|
639 | tool.location = _url2['default'].format(publicUrl);
|
640 | }
|
641 |
|
642 | if (this.relativePaths) {
|
643 | tool.pathRewrite = function (_path) {
|
644 | if ((0, _miscUtils.isAbsoluteURL)(_path) || _path[0] === '/') {
|
645 | return _path;
|
646 | }
|
647 |
|
648 | return tool.basePath + _path;
|
649 | };
|
650 | } else {
|
651 | tool.pathRewrite = function (path) {
|
652 | return path;
|
653 | };
|
654 | }
|
655 | }
|
656 | }, {
|
657 | key: 'validatePaths',
|
658 | value: function validatePaths(assets) {
|
659 | var _this5 = this;
|
660 |
|
661 | return assets.map(this.rewrite).filter(function (asset) {
|
662 | return !!asset;
|
663 | }).map(function (key) {
|
664 |
|
665 | if ((0, _miscUtils.isAbsoluteURL)(key)) {
|
666 | return key;
|
667 | }
|
668 |
|
669 | if (_this5.relativePaths) {
|
670 | return key.replace(/^\.\//, '');
|
671 | }
|
672 |
|
673 |
|
674 | if (key[0] === '/') {
|
675 | return key;
|
676 | }
|
677 |
|
678 | return _this5.publicPath + key.replace(/^\.?\//, '');
|
679 | });
|
680 | }
|
681 | }, {
|
682 | key: 'useTools',
|
683 | value: function useTools(fn) {
|
684 | var _this6 = this;
|
685 |
|
686 | var tools = Object.keys(this.tools).map(function (tool) {
|
687 | return fn(_this6.tools[tool], tool);
|
688 | });
|
689 |
|
690 | return Promise.all(tools);
|
691 | }
|
692 | }, {
|
693 | key: 'addTool',
|
694 | value: function addTool(Tool, name) {
|
695 | var options = this.options[name];
|
696 |
|
697 | if (options === null || options === false) {
|
698 |
|
699 | return;
|
700 | }
|
701 |
|
702 | this.tools[name] = new Tool(options);
|
703 | }
|
704 | }, {
|
705 | key: 'version',
|
706 | get: function get() {
|
707 | var version = this.options.version;
|
708 | var hash = this.hash;
|
709 |
|
710 | if (version == null) {
|
711 | return new Date().toLocaleString();
|
712 | }
|
713 |
|
714 | if (typeof version === 'function') {
|
715 | return version(this);
|
716 | }
|
717 |
|
718 | return (0, _miscUtils.interpolateString)(version, { hash: hash });
|
719 | }
|
720 | }]);
|
721 |
|
722 | return OfflinePlugin;
|
723 | })();
|
724 |
|
725 | exports['default'] = OfflinePlugin;
|
726 |
|
727 | OfflinePlugin.defaultOptions = _defaultOptions2['default'];
|
728 | module.exports = exports['default']; |
\ | No newline at end of file |