-
Notifications
You must be signed in to change notification settings - Fork 0
/
tasks.js
100 lines (83 loc) · 3.32 KB
/
tasks.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
const fs = require("fs");
const { execSync } = require("child_process");
const { argv } = require("process");
const jsDom = require("jsdom").JSDOM;
//todo: use async : if(isPromise(result))result.then->log(done)
const task = argv.slice(2)[0];
if (!task) console.error("enter a task");
else if (!(task in tasks)) console.error(`task ${task} not found`);
else
try {
console.log(`>> running the task: ${task}`);
argv.slice(3).forEach(el => console.log(` > ${el}`));
tasks[task](...argv.slice(3));
console.log(">> Done");
} catch (err) {
console.error(`>> error in task ${task}\n`, err);
}
let tasks = {
optimize: function(options = {}) {
//optimize the bundle for production mode
/*
copy package.json to ./dist for firebase
from cmd:
- linux cp firebase/package.json dist/package.json
- windows copy firebase\package.json dist\package.json
*/
let package = JSON.parse(
fs.readFileSync(`./package.json`, "utf8").toString()
);
package.main = package.main.replace("dist/", "");
fs.writeFileSync(`${dist}/package.json`, JSON.stringify(package));
//minify js files using terser
//todo: minifying main-es2015.*.js causes 'null injector error' in /$type/editor
let terser = function(dir) {
fs.readdirSync(dir)
.filter(el => el.endsWith(".js") && !el.includes("main-es2015."))
.forEach(el => {
el = `${dir}/${el}`;
if (fs.statSync(el).isDirectory()) return this.terser(el);
//todo: terser runtime-es2015 -> error: ngDevMode is not defined
console.log(`>> terser ${el}`);
execSync(
`npx terser ${el} --output ${el} --compress --mangle --keep-fnames --ie8 --safari10`
);
});
};
terser("./dist");
//transform index.html (lazy-load resources, and move them after 'load' event)
//DOMParser() is not available in nodejs, so we use `jsdom`
let content = fs.readFileSync(path, "utf8").toString();
fs.writeFileSync(path + ".bkp", content);
let dom = new jsDom(content).window.document,
mainScript = dom.getElementById("main-script"),
txt = "";
dom.querySelectorAll("script").forEach(script => {
if (!script.src) return; //todo: ||classList.includes["keep"]
//todo: converting <script type="module"> to load() causes a blank page displayed.
//even if they loaded.
//let type = script.getAttribute("type");
if (type == "module") return;
/*
- nomodule prevents the modern browsers to load the script,
it instead, will load the "module" version
https://stackoverflow.com/a/45947601/12577650
*/
txt += `load("${script.src}","${type || "script"}",{${
type === "module" ? "" : "nomodule:true,defer:true"
}});\n`;
script.remove();
});
dom.querySelectorAll("link").forEach(el => {
if (el.rel !== "stylesheet") return;
txt += `load("${el.href}","css");`;
el.remove();
});
txt = `document.addEventListener("load", () => {${txt}});`;
dom.createTextNode(txt);
mainScript.append(txt);
fs.writeFileSync(path, dom.documentElement.outerHTML);
//the hashes for modified files is changed, so we need to rebuild ngsw-config with the new hashes
execSync(`npx ngsw-config dist/browser ngsw-config.json`);
}
};