UNPKG

7.55 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', {
4 value: true
5});
6
7var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
8
9function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
10
11function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
12
13var _webpackLibSingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
14
15var _webpackLibSingleEntryPlugin2 = _interopRequireDefault(_webpackLibSingleEntryPlugin);
16
17var _path = require('path');
18
19var _path2 = _interopRequireDefault(_path);
20
21var _webpack = require('webpack');
22
23var _webpack2 = _interopRequireDefault(_webpack);
24
25var _deepExtend = require('deep-extend');
26
27var _deepExtend2 = _interopRequireDefault(_deepExtend);
28
29var _miscUtils = require('./misc/utils');
30
31var ServiceWorker = (function () {
32 function ServiceWorker(options) {
33 _classCallCheck(this, ServiceWorker);
34
35 if ((0, _miscUtils.isAbsolutePath)(options.output)) {
36 throw new Error('OfflinePlugin: ServiceWorker.output option must be a relative path, ' + 'but an absolute path was passed');
37 }
38
39 this.output = options.output.replace(/^\.\/+/, '');
40 this.publicPath = options.publicPath;
41
42 this.basePath = null;
43 this.location = null;
44 this.pathRewrite = null;
45
46 // Tool specific properties
47 this.entry = options.entry;
48 this.scope = options.scope ? options.scope + '' : void 0;
49 this.events = !!options.events;
50 this.navigateFallbackURL = options.navigateFallbackURL;
51 this.prefetchRequest = this.validatePrefetch(options.prefetchRequest);
52
53 var cacheNameQualifier = '';
54
55 if (options.cacheName) {
56 cacheNameQualifier = ':' + options.cacheName;
57 }
58
59 this.ENTRY_NAME = 'serviceworker';
60 this.CACHE_NAME = 'webpack-offline' + cacheNameQualifier;
61 this.SW_DATA_VAR = '__wpo';
62 }
63
64 _createClass(ServiceWorker, [{
65 key: 'addEntry',
66 value: function addEntry(plugin, compilation, compiler) {
67 if (!this.entry) return Promise.resolve();
68
69 var name = plugin.entryPrefix + this.ENTRY_NAME;
70 var childCompiler = compilation.createChildCompiler(name, {
71 // filename: this.output
72 filename: name
73 });
74
75 var data = JSON.stringify({
76 data_var_name: this.SW_DATA_VAR,
77 loaders: Object.keys(plugin.loaders),
78 cacheMaps: plugin.cacheMaps
79 });
80
81 var loader = '!!' + _path2['default'].join(__dirname, 'misc/sw-loader.js') + '?json=' + escape(data);
82 var entry = loader + '!' + this.entry;
83
84 childCompiler.context = compiler.context;
85 childCompiler.apply(new _webpackLibSingleEntryPlugin2['default'](compiler.context, entry, name));
86
87 (compiler.options.plugins || []).some(function (plugin) {
88 if (plugin instanceof _webpack2['default'].optimize.UglifyJsPlugin) {
89 var options = (0, _deepExtend2['default'])({}, plugin.options);
90
91 options.test = new RegExp(name);
92 childCompiler.apply(new _webpack2['default'].optimize.UglifyJsPlugin(options));
93
94 return true;
95 }
96 });
97
98 // Needed for HMR. offline-plugin doesn't support it,
99 // but added just in case to prevent other errors
100 childCompiler.plugin('compilation', function (compilation) {
101 if (compilation.cache) {
102 if (!compilation.cache[name]) {
103 compilation.cache[name] = {};
104 }
105
106 compilation.cache = compilation.cache[name];
107 }
108 });
109
110 return new Promise(function (resolve, reject) {
111 childCompiler.runAsChild(function (err, entries, childCompilation) {
112 if (err) {
113 reject(err);
114 return;
115 }
116
117 resolve();
118 });
119 });
120 }
121 }, {
122 key: 'apply',
123 value: function apply(plugin, compilation, compiler) {
124 var minify = (compiler.options.plugins || []).some(function (plugin) {
125 return plugin instanceof _webpack2['default'].optimize.UglifyJsPlugin;
126 });
127
128 var source = this.getDataTemplate(plugin.caches, plugin, minify);
129
130 if (this.entry) {
131 var _name = plugin.entryPrefix + this.ENTRY_NAME;
132 var asset = compilation.assets[_name];
133
134 if (!asset) {
135 compilation.errors.push(new Error('OfflinePlugin: ServiceWorker entry is not found in output assets'));
136
137 return;
138 }
139
140 delete compilation.assets[_name];
141
142 if (!plugin.__tests.swMetadataOnly) {
143 source += '\n\n' + asset.source();
144 }
145 }
146
147 compilation.assets[this.output] = (0, _miscUtils.getSource)(source);
148 }
149 }, {
150 key: 'getDataTemplate',
151 value: function getDataTemplate(data, plugin, minify) {
152 var rewriteFunction = this.pathRewrite;
153
154 var cache = function cache(key) {
155 return (data[key] || []).map(rewriteFunction);
156 };
157
158 var hashesMap = Object.keys(plugin.hashesMap).reduce(function (result, hash) {
159 var asset = plugin.hashesMap[hash];
160
161 result[hash] = rewriteFunction(asset);
162 return result;
163 }, {});
164
165 var externals = plugin.externals.map(rewriteFunction);
166
167 var pluginVersion = undefined;
168
169 if (plugin.pluginVersion && !plugin.__tests.noVersionDump) {
170 pluginVersion = plugin.pluginVersion;
171 }
172
173 var loaders = Object.keys(plugin.loaders).length ? plugin.loaders : void 0;
174
175 return ('\n var ' + this.SW_DATA_VAR + ' = ' + JSON.stringify({
176 assets: {
177 main: cache('main'),
178 additional: cache('additional'),
179 optional: cache('optional')
180 },
181
182 externals: externals,
183
184 hashesMap: hashesMap,
185 navigateFallbackURL: this.navigateFallbackURL,
186
187 strategy: plugin.strategy,
188 responseStrategy: plugin.responseStrategy,
189 version: plugin.version,
190 name: this.CACHE_NAME,
191 pluginVersion: pluginVersion,
192 relativePaths: plugin.relativePaths,
193
194 prefetchRequest: this.prefetchRequest,
195 loaders: loaders,
196
197 // These aren't added
198 alwaysRevalidate: plugin.alwaysRevalidate,
199 preferOnline: plugin.preferOnline,
200 ignoreSearch: plugin.ignoreSearch
201 }, null, minify ? void 0 : ' ') + ';\n ').trim();
202 }
203 }, {
204 key: 'getConfig',
205 value: function getConfig(plugin) {
206 return {
207 location: this.location,
208 scope: this.scope,
209 events: this.events
210 };
211 }
212 }, {
213 key: 'validatePrefetch',
214 value: function validatePrefetch(request) {
215 if (!request) {
216 return void 0;
217 }
218
219 if (request.credentials === 'omit' && request.headers === void 0 && request.mode === 'cors' && request.cache === void 0) {
220 return void 0;
221 }
222
223 return {
224 credentials: request.credentials,
225 headers: request.headers,
226 mode: request.mode,
227 cache: request.cache
228 };
229 }
230 }]);
231
232 return ServiceWorker;
233})();
234
235exports['default'] = ServiceWorker;
236module.exports = exports['default'];
\No newline at end of file