1 | 'use strict';
|
2 |
|
3 | const EntryPoint = require('./entry-point');
|
4 | const Funnel = require('broccoli-funnel');
|
5 | const Rollup = require('./rollup-with-dependencies');
|
6 | const fs = require('fs');
|
7 | const mergeTrees = require('broccoli-merge-trees');
|
8 | const path = require('path');
|
9 | const rollupReplace = require('rollup-plugin-replace');
|
10 | const uglify = require('broccoli-uglify-sourcemap');
|
11 |
|
12 | const TREE_FOR_METHODS = {
|
13 | 'service-worker': 'treeForServiceWorker',
|
14 | 'service-worker-registration': 'treeForServiceWorkerRegistration'
|
15 | };
|
16 |
|
17 | module.exports = class ServiceWorkerBuilder {
|
18 | constructor(options) {
|
19 | this.options = options || {};
|
20 |
|
21 | this.plugins = options.plugins;
|
22 | this.appTree = options.appTree;
|
23 | this.app = options.app;
|
24 | }
|
25 |
|
26 | build(type) {
|
27 | let trees = this._treesForPlugins(type);
|
28 | return this._compileTrees(trees, this._entryPointFilenameByType(type));
|
29 | }
|
30 |
|
31 | _treesForPlugins(type) {
|
32 | return this.plugins.reduce((trees, plugin) => {
|
33 | let pluginTree = this._treeForPlugin(plugin, type);
|
34 |
|
35 | if (pluginTree) {
|
36 | return trees.concat(pluginTree);
|
37 | }
|
38 |
|
39 | return trees
|
40 | }, []);
|
41 | }
|
42 |
|
43 | _treeForPlugin(plugin, type) {
|
44 | let pluginPath = path.resolve(plugin.root, type);
|
45 | let treeForMethod = TREE_FOR_METHODS[type];
|
46 |
|
47 | let tree;
|
48 |
|
49 | if (fs.existsSync(pluginPath)) {
|
50 | tree = this.app.treeGenerator(pluginPath);
|
51 | }
|
52 |
|
53 | if (plugin[treeForMethod]) {
|
54 | tree = plugin[treeForMethod](tree, this.appTree);
|
55 | }
|
56 |
|
57 | if (tree) {
|
58 | return new Funnel(tree, {
|
59 | destDir: plugin.pkg.name + '/' + type
|
60 | });
|
61 | }
|
62 | }
|
63 |
|
64 | _compileTrees(trees, treeName) {
|
65 | let entryPoint = new EntryPoint(trees, { entryPoint: `${treeName}` });
|
66 | let tree = mergeTrees(trees.concat(entryPoint), { overwrite: true });
|
67 |
|
68 | let registrationDistPath = this.options.registrationDistPath;
|
69 | let treeDistPath = treeName;
|
70 | if (treeName === 'sw-registration.js' && registrationDistPath) {
|
71 | treeDistPath = path.join(registrationDistPath, treeName);
|
72 | }
|
73 |
|
74 | tree = this._babelTranspile(tree);
|
75 | tree = this._rollupTree(tree, `${treeName}`, treeDistPath);
|
76 | tree = this._uglifyTree(tree);
|
77 |
|
78 | return tree;
|
79 | }
|
80 |
|
81 | _rollupTree(tree, entryFile, destFile) {
|
82 | let rollupReplaceConfig = {
|
83 | include: [
|
84 | '/**/ember-service-worker/**/*.js',
|
85 |
|
86 |
|
87 |
|
88 | /^[a-z]:\/(?:[^\/:*?"<>|\r\n]+\/)*ember-service-worker\/(?:[^\/:*?"<>|\r\n]+\/)*[^\/:*?"<>|\r\n]*\.js$/i
|
89 | ],
|
90 | delimiters: ['{{', '}}'],
|
91 | ROOT_URL: this.options.rootURL,
|
92 | SERVICE_WORKER_FILENAME: this.options.serviceWorkerFilename
|
93 | };
|
94 |
|
95 | return new Rollup(tree, {
|
96 | inputFiles: '**/*.js',
|
97 | rollup: {
|
98 | input: entryFile,
|
99 | output: {
|
100 | file: destFile || entryFile,
|
101 | format: 'iife',
|
102 | exports: 'none',
|
103 | },
|
104 | plugins: [
|
105 | rollupReplace(rollupReplaceConfig)
|
106 | ]
|
107 | }
|
108 | });
|
109 | }
|
110 |
|
111 | _uglifyTree(tree) {
|
112 | if (this.options.minifyJS && this.options.minifyJS.enabled) {
|
113 | let options = this.options.minifyJS.options || {};
|
114 | options.sourceMapConfig = this.options.sourcemaps;
|
115 | return uglify(tree, options);
|
116 | }
|
117 |
|
118 | return tree;
|
119 | }
|
120 |
|
121 | _babelTranspile(tree) {
|
122 | let emberCliBabel = this.app.project.addons.filter((a) => a.name === 'ember-cli-babel')[0];
|
123 | return emberCliBabel.transpileTree(tree, { 'ember-cli-babel': { compileModules: false } });
|
124 | }
|
125 |
|
126 | _entryPointFilenameByType(type) {
|
127 | return type === 'service-worker' ? this.options.serviceWorkerFilename : 'sw-registration.js';
|
128 | }
|
129 | }
|