UNPKG

2.71 kBJavaScriptView Raw
1/** @typedef {import('./types').SpaOptions} SpaOptions */
2
3const merge = require('deepmerge');
4const path = require('path');
5const { createScript } = require('@open-wc/building-utils');
6const { parse, serialize } = require('parse5');
7const { append, predicates, query } = require('@open-wc/building-utils/dom5-fork');
8const Terser = require('terser');
9
10const isFalsy = _ => !!_;
11
12function dedupedBabelPlugin(babel, userConfig, defaultConfig) {
13 if (!userConfig) {
14 return undefined;
15 }
16
17 const config = merge(defaultConfig, typeof userConfig === 'object' ? userConfig : {});
18
19 const newPlugins = [];
20 const addedPlugins = new Set();
21 for (const plugin of [...config.plugins].reverse()) {
22 const name = Array.isArray(plugin) ? plugin[0] : plugin;
23 const resolvedName = require.resolve(name);
24 if (!addedPlugins.has(resolvedName)) {
25 addedPlugins.add(resolvedName);
26 newPlugins.unshift(plugin);
27 }
28 }
29
30 config.plugins = newPlugins;
31 return babel(config);
32}
33
34function pluginWithOptions(plugin, userConfig, defaultConfig, ...otherParams) {
35 if (!userConfig) {
36 return undefined;
37 }
38
39 const config = merge(defaultConfig, typeof userConfig === 'object' ? userConfig : {});
40 return plugin(config, ...otherParams);
41}
42
43/**
44 *
45 * @param {SpaOptions} userOptions
46 * @param {string} outputDir
47 * @param {string} htmlFileName
48 */
49function createSwPath(userOptions, outputDir, htmlFileName) {
50 let swPath;
51 if (typeof userOptions.workbox === 'object' && userOptions.workbox.swDest) {
52 swPath = userOptions.workbox.swDest.replace(`${outputDir}/`, '');
53 } else {
54 swPath = './sw.js';
55 }
56
57 swPath = path.relative(path.dirname(htmlFileName), swPath);
58 return swPath;
59}
60
61/**
62 * @param {string} htmlString
63 * @returns {string}
64 */
65function applyServiceWorkerRegistration(htmlString, transformOptions, userOptions, outputDir) {
66 const swPath = createSwPath(userOptions, outputDir, transformOptions.htmlFileName);
67 const documentAst = parse(htmlString);
68 const body = query(documentAst, predicates.hasTagName('body'));
69 const swRegistration = createScript(
70 {},
71 Terser.minify(`
72 if ('serviceWorker' in navigator) {
73 window.addEventListener('load', function() {
74 navigator.serviceWorker
75 .register('${swPath}')
76 .then(function() {
77 console.log('ServiceWorker registered.');
78 })
79 .catch(function(err) {
80 console.log('ServiceWorker registration failed: ', err);
81 });
82 });
83 }
84 `).code,
85 );
86
87 append(body, swRegistration);
88 return serialize(documentAst);
89}
90
91module.exports = {
92 isFalsy,
93 pluginWithOptions,
94 dedupedBabelPlugin,
95 applyServiceWorkerRegistration,
96 createSwPath,
97};