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