-
Notifications
You must be signed in to change notification settings - Fork 61
/
service-worker-builder.js
129 lines (106 loc) · 3.72 KB
/
service-worker-builder.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
128
129
'use strict';
const EntryPoint = require('./entry-point');
const Funnel = require('broccoli-funnel');
const Rollup = require('./rollup-with-dependencies');
const fs = require('fs');
const mergeTrees = require('broccoli-merge-trees');
const path = require('path');
const rollupReplace = require('rollup-plugin-replace');
const uglify = require('broccoli-uglify-sourcemap');
const TREE_FOR_METHODS = {
'service-worker': 'treeForServiceWorker',
'service-worker-registration': 'treeForServiceWorkerRegistration'
};
const ENTRY_POINT_FILENAMES = {
'service-worker': 'sw.js',
'service-worker-registration': 'sw-registration.js'
};
module.exports = class ServiceWorkerBuilder {
constructor(options) {
this.options = options || {};
this.plugins = options.plugins;
this.appTree = options.appTree;
this.app = options.app;
}
build(type) {
let trees = this._treesForPlugins(type);
return this._compileTrees(trees, ENTRY_POINT_FILENAMES[type]);
}
_treesForPlugins(type) {
return this.plugins.reduce((trees, plugin) => {
let pluginTree = this._treeForPlugin(plugin, type);
if (pluginTree) {
return trees.concat(pluginTree);
}
return trees
}, []);
}
_treeForPlugin(plugin, type) {
let pluginPath = path.resolve(plugin.root, type);
let treeForMethod = TREE_FOR_METHODS[type];
let tree;
if (fs.existsSync(pluginPath)) {
tree = this.app.treeGenerator(pluginPath);
}
if (plugin[treeForMethod]) {
tree = plugin[treeForMethod](tree, this.appTree);
}
if (tree) {
return new Funnel(tree, {
destDir: plugin.pkg.name + '/' + type
});
}
}
_compileTrees(trees, treeName) {
let entryPoint = new EntryPoint(trees, { entryPoint: `${treeName}` });
let tree = mergeTrees(trees.concat(entryPoint), { overwrite: true });
let registrationDistPath = this.options.registrationDistPath;
let treeDistPath = treeName;
if (treeName === 'sw-registration.js' && registrationDistPath) {
treeDistPath = path.join(registrationDistPath, treeName);
}
tree = this._babelTranspile(tree);
tree = this._rollupTree(tree, `${treeName}`, treeDistPath);
tree = this._uglifyTree(tree);
return tree;
}
_rollupTree(tree, entryFile, destFile) {
let rollupReplaceConfig = {
include: [
'/**/ember-service-worker/**/*.js',
// same as above but for windows paths like D:\my-ember\ember-service-worker\whatever\sw.js; which are updated before this step to D:/my-ember/ember-service/worker/whatever/sw.js
// the original one doesn't work when the source code and the %TMP% folder, which ember started to use after v3.5, are located on different logical drives
// which is quite common in Windows.
/^[a-z]:\/(?:[^\/:*?"<>|\r\n]+\/)*ember-service-worker\/(?:[^\/:*?"<>|\r\n]+\/)*[^\/:*?"<>|\r\n]*\.js$/i
],
delimiters: ['{{', '}}'],
ROOT_URL: this.options.rootURL
};
return new Rollup(tree, {
inputFiles: '**/*.js',
rollup: {
input: entryFile,
output: {
file: destFile || entryFile,
format: 'iife',
},
exports: 'none',
plugins: [
rollupReplace(rollupReplaceConfig)
]
}
});
}
_uglifyTree(tree) {
if (this.options.minifyJS && this.options.minifyJS.enabled) {
let options = this.options.minifyJS.options || {};
options.sourceMapConfig = this.options.sourcemaps;
return uglify(tree, options);
}
return tree;
}
_babelTranspile(tree) {
let emberCliBabel = this.app.project.addons.filter((a) => a.name === 'ember-cli-babel')[0];
return emberCliBabel.transpileTree(tree, { 'ember-cli-babel': { compileModules: false } });
}
}