1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | import etpl from 'etpl';
|
7 | import fs from 'fs';
|
8 | import path from 'path';
|
9 | import babel from 'babel-core';
|
10 |
|
11 |
|
12 | const cwd = process.cwd();
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | function getVersion() {
|
21 | let d = new Date();
|
22 | let p = function (value) {
|
23 | return value < 10 ? ('0' + value) : value;
|
24 | };
|
25 |
|
26 | return ''
|
27 | + d.getFullYear()
|
28 | + p(d.getMonth() + 1)
|
29 | + p(d.getDate())
|
30 | + p(d.getHours())
|
31 | + p(d.getMinutes())
|
32 | + p(d.getSeconds());
|
33 | }
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | function babelCompiler(source) {
|
42 | return babel.transform(source, {
|
43 | comments: false,
|
44 | minified: true,
|
45 | plugins: [
|
46 | 'transform-runtime',
|
47 | 'external-helpers'
|
48 | ],
|
49 | presets: [
|
50 | [
|
51 | 'env',
|
52 | {
|
53 | targets: {
|
54 | node: 3
|
55 | },
|
56 | modules: false
|
57 | }
|
58 | ]
|
59 | ]
|
60 | }).code;
|
61 | }
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 | function SwRegisterPlugin(options = {}) {
|
70 |
|
71 | let filePath = path.resolve(cwd, (options.filePath || './src/sw-register.js'));
|
72 |
|
73 | if (!fs.existsSync(filePath)) {
|
74 | filePath = path.resolve(__dirname, '..', 'templates', 'sw-register.js');
|
75 | }
|
76 | this.filePath = filePath;
|
77 | this.fileName = path.basename(filePath);
|
78 | this.swPath = options.swPath || '/service-worker.js';
|
79 | this.version = options.version || getVersion();
|
80 | }
|
81 |
|
82 |
|
83 |
|
84 | SwRegisterPlugin.prototype.apply = function (compiler) {
|
85 |
|
86 | const me = this;
|
87 | const swRegisterEntryFilePath = path.resolve(__dirname, '..', 'templates', 'sw-register-entry.js.tpl');
|
88 | const swRegisterFilePath = me.filePath;
|
89 |
|
90 | compiler.plugin('emit', (compilation, callback) => {
|
91 | Object.keys(compilation.assets).forEach(asset => {
|
92 |
|
93 | if (asset.indexOf('.html') > -1) {
|
94 | let htmlContent = compilation.assets[asset].source();
|
95 | let swRegisterEntryFileTpl = fs.readFileSync(swRegisterEntryFilePath, 'utf-8');
|
96 | let swRegisterEntryFileContent = etpl.compile(swRegisterEntryFileTpl)(me);
|
97 | let con = fs.readFileSync(swRegisterFilePath, 'utf-8');
|
98 |
|
99 | con = babelCompiler(con)
|
100 | .replace(
|
101 | /serviceWorker\.register\(.*\)/g,
|
102 | 'serviceWorker.register("' + me.swPath + '?v=' + me.version + '")'
|
103 | );
|
104 |
|
105 | htmlContent = htmlContent.replace(/<\/body>/, swRegisterEntryFileContent + '</body>');
|
106 |
|
107 | compilation.assets[asset] = {
|
108 | source() {
|
109 | return htmlContent;
|
110 | },
|
111 | size() {
|
112 | return htmlContent.length;
|
113 | }
|
114 | };
|
115 |
|
116 | compilation.assets[me.fileName] = {
|
117 | source() {
|
118 | return con;
|
119 | },
|
120 | size() {
|
121 | return con.length;
|
122 | }
|
123 | };
|
124 | }
|
125 | });
|
126 | callback();
|
127 | });
|
128 |
|
129 | };
|
130 |
|
131 |
|
132 | export default SwRegisterPlugin;
|
133 |
|