-
Notifications
You must be signed in to change notification settings - Fork 1
/
build.js
120 lines (110 loc) · 2.88 KB
/
build.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
import { context, build as esbuild } from "esbuild"
import { readFile, readdir, rm } from "fs/promises"
import { minify as minifyHtml } from "html-minifier-terser"
import path from "path"
const watch = process.argv.includes("-w")
const entry = "./src/**"
const outDir = "./dist/"
const libDir = "/lib/"
const outLibDir = outDir.slice(0, -1) + libDir
const externals = new Set(["zoomist/css"])
console.info(time(), "cleaning")
for (const file of await readdir(outDir).catch(() => { }) ?? [])
await rm(path.join(outDir, file), { recursive: true })
const srcCtx = await context({
packages: "external",
entryPoints: [entry],
loader: {
".css": "copy", // no sourcemap
".webmanifest": "copy",
".json": "copy",
".html": "copy",
".ejs": "copy",
".woff": "copy",
".png": "copy",
".webp": "copy",
},
outdir: outDir,
target: "es2022",
format: "esm",
platform: "browser",
bundle: true,
minify: true,
sourcemap: true,
plugins: [resolvePackagesPl(), minifyHtmlPl(), buildLogsPl()]
})
if (watch) {
console.info(time(), "watching for changes\n")
await srcCtx.watch()
} else {
await srcCtx.rebuild()
process.exit(0)
}
//
function resolvePackagesPl() {
return {
name: "resolvePackages",
setup(build) {
// filter out non-module imports
build.onResolve({ filter: /^[^./]|^[^.][^.]?$/ }, async args => {
if (args.external || !args.kind.includes("import") || /\.\w*$/.test(args.path))
return
// collect the import name and edit in the import statement
externals.add(args.path)
return {
path: libDir + args.path + ".js",
external: true
}
})
}
}
}
function minifyHtmlPl() {
return {
name: "minifyHtml",
setup(build) {
build.onLoad({ filter: /\.(html|ejs)$/ }, async args => {
let contents = await readFile(args.path, "utf8")
contents = await minifyHtml(contents, {
collapseWhitespace: true,
conservativeCollapse: true,
preserveLineBreaks: true,
collapseBooleanAttributes: true,
minifyCSS: true,
minifyJS: { module: true },
quoteCharacter: "\"",
removeComments: true,
removeRedundantAttributes: true,
sortAttributes: true,
sortClassName: true
})
return { contents, loader: "default" }
})
}
}
}
function buildLogsPl() {
return {
name: "buildLogs",
setup(build) {
build.onEnd(async result => {
// put dist files of externals into outLibDir
const libResult = await esbuild({
entryPoints: Array.from(externals),
outdir: outLibDir,
target: "es2022",
format: "esm",
platform: "browser"
})
const warns = result.warnings.length + libResult.warnings.length
const errs = result.errors.length + libResult.errors.length
console.info(time(), (watch ? "[watch] " : "")
+ `${errs ? "build failed" : "built"} with`
+ ` ${warns} warnings ${errs} errors`)
})
}
}
}
function time() {
return new Date().toISOString().substring(14, 23)
}