UNPKG

3.42 kBJavaScriptView Raw
1/**
2 * @file serviceWorker register no-cache solution
3 * @author mj(zoumiaojiang@gmail.com)
4 */
5
6import etpl from 'etpl';
7import fs from 'fs';
8import path from 'path';
9import babel from 'babel-core';
10
11
12const cwd = process.cwd();
13
14
15/**
16 * 获取时间戳版本号
17 *
18 * @return {string} 版本号
19 */
20function 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 * babel 编译
37 *
38 * @param {string} source 源代码
39 * @return {string} 编译后的代码
40 */
41function 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 * sw Register 插件
65 *
66 * @constructor
67 * @param {Object} options 参数
68 */
69function 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
84SwRegisterPlugin.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/* eslint-disable */
132export default SwRegisterPlugin;
133