-
Notifications
You must be signed in to change notification settings - Fork 104
/
index.js
127 lines (104 loc) · 4.06 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import path from 'path';
import url from 'url';
import del from 'del';
import swPrecache from 'sw-precache';
const
DEFAULT_CACHE_ID = 'sw-precache-webpack-plugin',
DEFAULT_WORKER_FILENAME = 'service-worker.js',
DEFAULT_OUTPUT_PATH = '',
DEFAULT_PUBLIC_PATH = '',
DEFAULT_IMPORT_SCRIPTS = [];
const DEFAULT_OPTIONS = {
cacheId: DEFAULT_CACHE_ID,
filename: DEFAULT_WORKER_FILENAME,
forceDelete: true
};
/**
* SWPrecacheWebpackPlugin - A wrapper for sw-precache to use with webpack
* @param {object} options - All parameters should be passed as a single options object
*
* // sw-precache options:
* @param {string} [options.cacheId]
* @param {string} [options.directoryIndex]
* @param {object|array} [options.dynamicUrlToDependencies]
* @param {boolean} [options.handleFetch]
* @param {array} [options.ignoreUrlParametersMatching]
* @param {array} [options.importScripts]
* @param {function} [options.logger]
* @param {number} [options.maximumFileSizeToCacheInBytes]
* @param {array} [options.navigateFallbackWhitelist]
* @param {string} [options.replacePrefix]
* @param {array} [options.runtimeCaching]
* @param {array} [options.staticFileGlobs]
* @param {string} [options.stripPrefix]
* @param {string} [options.templateFilePath]
* @param {boolean} [options.verbose]
*
* // plugin options:
* @param {string} [options.filename] - Service worker filename, default is 'service-worker.js'
* @param {string} [options.filepath] - Service worker path and name, default is to use webpack.output.path + options.filename
* @param {RegExp} [options.staticFileGlobsIgnorePatterns[]] - Define an optional array of regex patterns to filter out of staticFileGlobs
*/
class SWPrecacheWebpackPlugin {
constructor(options) {
this.options = {
...DEFAULT_OPTIONS,
...options,
};
this.overrides = {};
}
apply(compiler) {
compiler.plugin('after-emit', (compilation, callback) => {
// get the output path specified in webpack config
const outputPath = compiler.options.output.path || DEFAULT_OUTPUT_PATH;
// get the public path specified in webpack config
const publicPath = compiler.options.output.publicPath || DEFAULT_PUBLIC_PATH;
// get the importScripts value specified in the sw-precache config
const importScripts = this.options.importScripts || DEFAULT_IMPORT_SCRIPTS;
// get all assets outputted by webpack
const assetGlobs = Object
.keys(compilation.assets)
.map(f => path.join(outputPath, f));
const ignorePatterns = this.options.staticFileGlobsIgnorePatterns || [];
// filter staticFileGlobs from ignorePatterns
const staticFileGlobs = assetGlobs.filter(text =>
(!ignorePatterns.some((regex) => regex.test(text)))
);
const config = {
staticFileGlobs,
verbose: true,
};
if (outputPath) {
// strip the webpack config's output.path
config.stripPrefix = `${outputPath}${path.sep}`;
}
if (publicPath) {
// prepend the public path to the resources
config.replacePrefix = publicPath;
}
if (importScripts) {
this.overrides.importScripts = importScripts
.map(f => f.replace(/\[hash\]/g, compilation.hash)) // need to override importScripts with stats.hash
.map(f => url.resolve(publicPath, f)); // add publicPath to importScripts
}
const done = () => callback();
const error = (err) => callback(err);
this.writeServiceWorker(compiler, config).then(done, error);
});
}
writeServiceWorker(compiler, config) {
const
fileDir = compiler.options.output.path || DEFAULT_OUTPUT_PATH,
// default to options.filepath for writing service worker location
filepath = this.options.filepath || path.join(fileDir, this.options.filename),
workerOptions = {
...config,
...this.options,
...this.overrides,
};
return del(filepath, { ...this.options.forceDelete }).then(() => {
return swPrecache.write(filepath, workerOptions);
});
}
}
module.exports = SWPrecacheWebpackPlugin;