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({
|
229 | loader: _path3['default'].join(__dirname, 'misc/runtime-loader.js'),
|
230 | options: JSON.stringify(data)
|
231 | });
|
232 |
|
233 | callback(null, result);
|
234 | };
|
235 |
|
236 | var makeFn = function makeFn(compilation, callback) {
|
237 | if (_this2.warnings.length) {
|
238 | [].push.apply(compilation.warnings, _this2.warnings);
|
239 | }
|
240 |
|
241 | if (_this2.errors.length) {
|
242 | [].push.apply(compilation.errors, _this2.errors);
|
243 | }
|
244 |
|
245 | _this2.useTools(function (tool) {
|
246 | return tool.addEntry(_this2, compilation, compiler);
|
247 | }).then(function () {
|
248 | callback();
|
249 | })['catch'](function (e) {
|
250 | throw e || new Error('Something went wrong');
|
251 | });
|
252 | };
|
253 |
|
254 | var emitFn = function emitFn(compilation, callback) {
|
255 | var runtimeTemplatePath = _path3['default'].resolve(__dirname, '../tpls/runtime-template.js');
|
256 | var hasRuntime = true;
|
257 |
|
258 | if (compilation.fileDependencies.indexOf) {
|
259 | hasRuntime = compilation.fileDependencies.indexOf(runtimeTemplatePath) !== -1;
|
260 | } else if (compilation.fileDependencies.has) {
|
261 | hasRuntime = compilation.fileDependencies.has(runtimeTemplatePath);
|
262 | }
|
263 |
|
264 | if (!hasRuntime && !_this2.__tests.ignoreRuntime) {
|
265 | 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.'));
|
266 | callback();
|
267 | return;
|
268 | }
|
269 |
|
270 | var stats = compilation.getStats().toJson();
|
271 |
|
272 |
|
273 |
|
274 | try {
|
275 | _this2.setAssets(compilation);
|
276 | _this2.setHashesMap(compilation);
|
277 |
|
278 |
|
279 | _this2.hash = _loaderUtils2['default'].getHashDigest(Object.keys(_this2.hashesMap).join(''), 'sha1');
|
280 |
|
281 |
|
282 |
|
283 | } catch (e) {
|
284 | callback(e);
|
285 | return;
|
286 | }
|
287 |
|
288 | _this2.useTools(function (tool) {
|
289 | return tool.apply(_this2, compilation, compiler);
|
290 | }).then(function () {
|
291 | callback();
|
292 | }, function () {
|
293 | callback(new Error('Something went wrong'));
|
294 | });
|
295 | };
|
296 |
|
297 | if (compiler.hooks) {
|
298 | (function () {
|
299 | var plugin = { name: 'OfflinePlugin' };
|
300 |
|
301 | compiler.hooks.normalModuleFactory.tap(plugin, function (nmf) {
|
302 | nmf.hooks.afterResolve.tapAsync(plugin, afterResolveFn);
|
303 | });
|
304 |
|
305 | compiler.hooks.make.tapAsync(plugin, makeFn);
|
306 | compiler.hooks.emit.tapAsync(plugin, emitFn);
|
307 | })();
|
308 | } else {
|
309 | compiler.plugin('normal-module-factory', function (nmf) {
|
310 | nmf.plugin('after-resolve', afterResolveFn);
|
311 | });
|
312 |
|
313 | compiler.plugin('make', makeFn);
|
314 | compiler.plugin('emit', emitFn);
|
315 | }
|
316 | }
|
317 | }, {
|
318 | key: 'setAssets',
|
319 | value: function setAssets(compilation) {
|
320 | var _this3 = this;
|
321 |
|
322 | var caches = this.options.caches || _defaultOptions2['default'].caches;
|
323 |
|
324 | if (this.options.safeToUseOptionalCaches !== true && (caches.additional && caches.additional.length || caches.optional && caches.optional.length)) {
|
325 | 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.'));
|
326 | }
|
327 |
|
328 | var excludes = this.options.excludes;
|
329 | var assets = Object.keys(compilation.assets);
|
330 | var externals = this.options.externals;
|
331 |
|
332 | if (Array.isArray(excludes) && excludes.length) {
|
333 | assets = assets.filter(function (asset) {
|
334 | if (excludes.some(function (glob) {
|
335 | if ((0, _minimatch2['default'])(asset, glob)) {
|
336 | return true;
|
337 | }
|
338 | })) {
|
339 | return false;
|
340 | }
|
341 |
|
342 | return true;
|
343 | });
|
344 | }
|
345 |
|
346 | this.externals = this.validatePaths(externals);
|
347 |
|
348 | if (caches === 'all') {
|
349 | this.assets = this.validatePaths(assets).concat(this.externals);
|
350 | this.caches = {
|
351 | main: this.assets.concat()
|
352 | };
|
353 | } else {
|
354 | (function () {
|
355 | var restSection = undefined;
|
356 | var externalsSection = undefined;
|
357 |
|
358 | var handledCaches = ['main', 'additional', 'optional'].reduce(function (result, key) {
|
359 | var cache = Array.isArray(caches[key]) ? caches[key] : [];
|
360 |
|
361 | if (!cache.length) {
|
362 | result[key] = cache;
|
363 | return result;
|
364 | }
|
365 |
|
366 | var cacheResult = [];
|
367 |
|
368 | cache.some(function (cacheKey) {
|
369 | if (cacheKey === _this3.REST_KEY) {
|
370 | if (restSection) {
|
371 | throw new Error('The ' + _this3.REST_KEY + ' keyword can be used only once');
|
372 | }
|
373 |
|
374 | restSection = key;
|
375 | return;
|
376 | }
|
377 |
|
378 | if (cacheKey === _this3.EXTERNALS_KEY) {
|
379 | if (externalsSection) {
|
380 | throw new Error('The ' + _this3.EXTERNALS_KEY + ' keyword can be used only once');
|
381 | }
|
382 |
|
383 | externalsSection = key;
|
384 | return;
|
385 | }
|
386 |
|
387 | var magic = undefined;
|
388 |
|
389 | if (typeof cacheKey === 'string') {
|
390 | magic = !(0, _miscUtils.isAbsoluteURL)(cacheKey) && cacheKey[0] !== '/' && cacheKey.indexOf('./') !== 0 && (0, _miscUtils.hasMagic)(cacheKey);
|
391 | } else if (cacheKey instanceof RegExp) {
|
392 | magic = (0, _miscUtils.hasMagic)(cacheKey);
|
393 | } else {
|
394 |
|
395 | return;
|
396 | }
|
397 |
|
398 | if (magic) {
|
399 | var matched = undefined;
|
400 |
|
401 | for (var i = 0, len = assets.length; i < len; i++) {
|
402 | if (!magic.match(assets[i])) continue;
|
403 |
|
404 | matched = true;
|
405 | cacheResult.push(assets[i]);
|
406 | assets.splice(i, 1);
|
407 | i--, len--;
|
408 | }
|
409 |
|
410 | if (!matched) {
|
411 | compilation.warnings.push(new Error('OfflinePlugin: Cache pattern [' + cacheKey + '] did not match any assets'));
|
412 | }
|
413 |
|
414 | return;
|
415 | }
|
416 |
|
417 | var index = assets.indexOf(cacheKey);
|
418 |
|
419 | __EXTERNALS_CHECK: if (index === -1) {
|
420 | var externalsIndex = externals.indexOf(cacheKey);
|
421 |
|
422 | if (externalsIndex !== -1) {
|
423 | externals.splice(externalsIndex, 1);
|
424 | break __EXTERNALS_CHECK;
|
425 | }
|
426 |
|
427 | 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.'));
|
428 | } else {
|
429 | assets.splice(index, 1);
|
430 | }
|
431 |
|
432 | cacheResult.push(cacheKey);
|
433 | });
|
434 |
|
435 | result[key] = _this3.validatePaths(cacheResult);
|
436 |
|
437 | return result;
|
438 | }, {});
|
439 |
|
440 | if (restSection && assets.length) {
|
441 | handledCaches[restSection] = handledCaches[restSection].concat(_this3.validatePaths(assets));
|
442 | }
|
443 |
|
444 | if (externalsSection && externals.length) {
|
445 | handledCaches[externalsSection] = handledCaches[externalsSection].concat(_this3.validatePaths(externals));
|
446 | }
|
447 |
|
448 | _this3.caches = handledCaches;
|
449 | _this3.assets = [].concat(_this3.caches.main, _this3.caches.additional, _this3.caches.optional);
|
450 | })();
|
451 | }
|
452 | }
|
453 | }, {
|
454 | key: 'setHashesMap',
|
455 | value: function setHashesMap(compilation) {
|
456 | var _this4 = this;
|
457 |
|
458 | this.hashesMap = {};
|
459 |
|
460 | Object.keys(compilation.assets).forEach(function (key) {
|
461 | var validatedPath = _this4.validatePaths([key])[0];
|
462 |
|
463 | if (typeof validatedPath !== 'string' || _this4.assets.indexOf(validatedPath) === -1) return;
|
464 |
|
465 | var hash = _loaderUtils2['default'].getHashDigest(compilation.assets[key].source(), 'sha1');
|
466 |
|
467 | _this4.hashesMap[hash] = validatedPath;
|
468 | });
|
469 | }
|
470 | }, {
|
471 | key: 'setNetworkOptions',
|
472 | value: function setNetworkOptions() {
|
473 | var alwaysRevalidate = this.options.alwaysRevalidate;
|
474 | var preferOnline = this.options.preferOnline;
|
475 | var ignoreSearch = this.options.ignoreSearch;
|
476 |
|
477 | var assets = this.assets;
|
478 |
|
479 |
|
480 | if (Array.isArray(alwaysRevalidate) && alwaysRevalidate.length) {
|
481 | alwaysRevalidate = assets.filter(function (asset) {
|
482 | if (alwaysRevalidate.some(function (glob) {
|
483 | if ((0, _minimatch2['default'])(asset, glob)) {
|
484 | return true;
|
485 | }
|
486 | })) {
|
487 | return true;
|
488 | }
|
489 |
|
490 | return false;
|
491 | });
|
492 |
|
493 | if (alwaysRevalidate.length) {
|
494 | this.alwaysRevalidate = alwaysRevalidate;
|
495 | }
|
496 | }
|
497 |
|
498 | if (Array.isArray(ignoreSearch) && ignoreSearch.length) {
|
499 | ignoreSearch = assets.filter(function (asset) {
|
500 | if (ignoreSearch.some(function (glob) {
|
501 | if ((0, _minimatch2['default'])(asset, glob)) {
|
502 | return true;
|
503 | }
|
504 | })) {
|
505 | return true;
|
506 | }
|
507 |
|
508 | return false;
|
509 | });
|
510 |
|
511 | if (ignoreSearch.length) {
|
512 | this.ignoreSearch = ignoreSearch;
|
513 | }
|
514 | }
|
515 |
|
516 | if (Array.isArray(preferOnline) && preferOnline.length) {
|
517 | preferOnline = assets.filter(function (asset) {
|
518 | if (preferOnline.some(function (glob) {
|
519 | if ((0, _minimatch2['default'])(asset, glob)) {
|
520 | return true;
|
521 | }
|
522 | })) {
|
523 | return true;
|
524 | }
|
525 |
|
526 | return false;
|
527 | });
|
528 |
|
529 | if (preferOnline.length) {
|
530 | this.preferOnline = preferOnline;
|
531 | }
|
532 | }
|
533 | }
|
534 | }, {
|
535 | key: 'stringifyCacheMaps',
|
536 | value: function stringifyCacheMaps(cacheMaps) {
|
537 | if (!cacheMaps) {
|
538 | return [];
|
539 | }
|
540 |
|
541 | return cacheMaps.map(function (map) {
|
542 | if (map.to != null && typeof map.to !== 'string' && typeof map.to !== 'function') {
|
543 | throw new Error('cacheMaps `to` property must either string, function, undefined or null');
|
544 | }
|
545 |
|
546 | if (map.requestTypes != null) {
|
547 | if (Array.isArray(map.requestTypes)) {
|
548 | var types = map.requestTypes.filter(function (item) {
|
549 | if (item === 'navigate' || item === 'same-origin' || item === 'cross-origin') {
|
550 | return false;
|
551 | }
|
552 |
|
553 | return true;
|
554 | });
|
555 |
|
556 | if (types.length) {
|
557 | throw new Error("cacheMaps `requestTypes` array values could be only: 'navigate', 'same-origin' or 'cross-origin'");
|
558 | }
|
559 | } else {
|
560 | throw new Error('cacheMaps `requestTypes` property must either array, undefined or null');
|
561 | }
|
562 | }
|
563 |
|
564 | var to = undefined;
|
565 | var match = undefined;
|
566 |
|
567 | if (typeof map.to === 'function') {
|
568 | to = (0, _miscUtils.functionToString)(map.to);
|
569 | } else {
|
570 | to = map.to ? JSON.stringify(map.to) : null;
|
571 | }
|
572 |
|
573 | if (typeof map.match === 'function') {
|
574 | match = (0, _miscUtils.functionToString)(map.match);
|
575 | } else {
|
576 | match = map.match + '';
|
577 | }
|
578 |
|
579 | return {
|
580 | match: match,
|
581 | to: to,
|
582 | requestTypes: map.requestTypes || null
|
583 | };
|
584 | });
|
585 | }
|
586 | }, {
|
587 | key: 'resolveToolPaths',
|
588 | value: function resolveToolPaths(tool, key, compiler) {
|
589 |
|
590 |
|
591 |
|
592 |
|
593 |
|
594 |
|
595 |
|
596 |
|
597 | if (!this.relativePaths && !this.publicPath) {
|
598 | throw new Error('OfflinePlugin: Cannot generate base path for ' + key);
|
599 | }
|
600 |
|
601 | var isDirectory = tool.output[tool.output.length - 1] === '/';
|
602 |
|
603 | if (this.relativePaths) {
|
604 | var compilerOutput = (compiler.options.output || { path: process.cwd() }).path;
|
605 | var absoluteOutput = _path3['default'].resolve(compilerOutput, tool.output);
|
606 |
|
607 | var relativeBase = undefined;
|
608 |
|
609 | if (isDirectory) {
|
610 | relativeBase = _path3['default'].relative(absoluteOutput, compilerOutput);
|
611 | } else {
|
612 | relativeBase = _path3['default'].relative(_path3['default'].dirname(absoluteOutput), compilerOutput);
|
613 | }
|
614 |
|
615 | relativeBase = (0, _slash2['default'])(relativeBase);
|
616 | relativeBase = relativeBase.replace(/\/$/, '');
|
617 |
|
618 | if (relativeBase) {
|
619 | relativeBase = relativeBase + '/';
|
620 | }
|
621 |
|
622 | tool.basePath = relativeBase[0] === '.' ? relativeBase : './' + relativeBase;
|
623 | } else if (this.publicPath) {
|
624 | tool.basePath = this.publicPath.replace(/\/$/, '') + '/';
|
625 | }
|
626 |
|
627 | if (this.relativePaths) {
|
628 | tool.location = tool.output;
|
629 | } else if (this.publicPath && tool.publicPath) {
|
630 | tool.location = tool.publicPath;
|
631 | } else if (this.publicPath) {
|
632 | var publicUrl = _url2['default'].parse(this.publicPath);
|
633 | var publicPath = publicUrl.pathname;
|
634 |
|
635 | publicUrl.pathname = _path3['default'].join(publicPath, tool.output);
|
636 | var outerPathname = _path3['default'].join('/outer/', publicPath, tool.output);
|
637 |
|
638 | if (outerPathname.indexOf('/outer/') !== 0) {
|
639 | new Error('OfflinePlugin: Wrong ' + key + '.output value. Final ' + key + '.location URL path bounds are outside of publicPath');
|
640 | }
|
641 |
|
642 | tool.location = _url2['default'].format(publicUrl);
|
643 | }
|
644 |
|
645 | if (this.relativePaths) {
|
646 | tool.pathRewrite = function (_path) {
|
647 | if ((0, _miscUtils.isAbsoluteURL)(_path) || _path[0] === '/') {
|
648 | return _path;
|
649 | }
|
650 |
|
651 | return tool.basePath + _path;
|
652 | };
|
653 | } else {
|
654 | tool.pathRewrite = function (path) {
|
655 | return path;
|
656 | };
|
657 | }
|
658 | }
|
659 | }, {
|
660 | key: 'validatePaths',
|
661 | value: function validatePaths(assets) {
|
662 | var _this5 = this;
|
663 |
|
664 | return assets.map(this.rewrite).filter(function (asset) {
|
665 | return !!asset;
|
666 | }).map(function (key) {
|
667 |
|
668 | if ((0, _miscUtils.isAbsoluteURL)(key)) {
|
669 | return key;
|
670 | }
|
671 |
|
672 | if (_this5.relativePaths) {
|
673 | return key.replace(/^\.\//, '');
|
674 | }
|
675 |
|
676 |
|
677 | if (key[0] === '/') {
|
678 | return key;
|
679 | }
|
680 |
|
681 | return _this5.publicPath + key.replace(/^\.?\//, '');
|
682 | });
|
683 | }
|
684 | }, {
|
685 | key: 'useTools',
|
686 | value: function useTools(fn) {
|
687 | var _this6 = this;
|
688 |
|
689 | var tools = Object.keys(this.tools).map(function (tool) {
|
690 | return fn(_this6.tools[tool], tool);
|
691 | });
|
692 |
|
693 | return Promise.all(tools);
|
694 | }
|
695 | }, {
|
696 | key: 'addTool',
|
697 | value: function addTool(Tool, name) {
|
698 | var options = this.options[name];
|
699 |
|
700 | if (options === null || options === false) {
|
701 |
|
702 | return;
|
703 | }
|
704 |
|
705 | this.tools[name] = new Tool(options);
|
706 | }
|
707 | }, {
|
708 | key: 'version',
|
709 | get: function get() {
|
710 | var version = this.options.version;
|
711 | var hash = this.hash;
|
712 |
|
713 | if (version == null) {
|
714 | return new Date().toLocaleString();
|
715 | }
|
716 |
|
717 | if (typeof version === 'function') {
|
718 | return version(this);
|
719 | }
|
720 |
|
721 | return (0, _miscUtils.interpolateString)(version, { hash: hash });
|
722 | }
|
723 | }]);
|
724 |
|
725 | return OfflinePlugin;
|
726 | })();
|
727 |
|
728 | exports['default'] = OfflinePlugin;
|
729 |
|
730 | OfflinePlugin.defaultOptions = _defaultOptions2['default'];
|
731 | module.exports = exports['default']; |
\ | No newline at end of file |