-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathbuild.ts
More file actions
100 lines (90 loc) · 2.98 KB
/
build.ts
File metadata and controls
100 lines (90 loc) · 2.98 KB
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
import { basename } from "node:path";
import * as lightningcss from "lightningcss";
import * as terser from "terser";
import { createManifest } from "./manifest.config.ts";
const mode = Bun.env.NODE_ENV;
const dev = mode === "development";
// TODO: Use bun to bundle CSS once it's configurable e.g., targets, include.
async function compileCSS(path: string) {
const source = await Bun.file(path).bytes();
const result = await lightningcss.bundleAsync({
filename: path,
// @ts-expect-error - bundle does accept code, same as transform
code: source,
minify: !dev,
// oxlint-disable-next-line no-bitwise
targets: { chrome: 134 << 16 }, // matches manifest minimum_chrome_version
include: lightningcss.Features.Nesting,
});
if (result.warnings.length > 0) console.error(result.warnings);
return result.code;
}
async function makeThemes(pattern: string) {
const paths = [...new Bun.Glob(pattern).scanSync()].sort();
const compiled = await Promise.all(paths.map(compileCSS));
const entries = paths.map((path, index) => [basename(path, ".css"), compiled[index].toString()]);
return JSON.stringify(Object.fromEntries(entries));
}
async function minify(artifacts: Bun.BuildArtifact[]) {
for (const artifact of artifacts) {
if (artifact.path.endsWith(".js")) {
const source = await artifact.text();
const result = await terser.minify(source, {
ecma: 2020,
module: true,
compress: {
reduce_funcs: false,
passes: 2,
// NOTE: Comment out to keep performance markers for debugging.
pure_funcs: ["performance.mark", "performance.measure"],
},
format: {
semicolons: false,
},
mangle: {
properties: {
regex: String.raw`^\$\$`,
},
},
});
await Bun.write(artifact.path, result.code!);
}
}
}
console.time("prebuild");
await Bun.$`rm -rf dist`;
await Bun.$`cp -r static dist`;
console.timeEnd("prebuild");
console.time("manifest");
await Bun.write("dist/manifest.json", JSON.stringify(createManifest()));
console.timeEnd("manifest");
console.time("themes");
await Bun.write("dist/newtab.css", await compileCSS("src/newtab.css"));
await Bun.write("dist/settings.css", await compileCSS("src/settings.css"));
await Bun.write("dist/themes.json", await makeThemes("src/themes/*.css"));
console.timeEnd("themes");
console.time("build:apps");
const out1 = await Bun.build({
entrypoints: ["src/newtab.ts", "src/settings.ts"],
outdir: "dist",
naming: "[dir]/[name].[ext]",
target: "browser",
minify: !dev,
sourcemap: dev ? "linked" : "none",
});
console.timeEnd("build:apps");
console.time("build:worker");
const out2 = await Bun.build({
entrypoints: ["src/sw.ts"],
outdir: "dist",
target: "browser",
minify: !dev,
sourcemap: dev ? "linked" : "none",
});
console.timeEnd("build:worker");
if (!dev) {
console.time("minify");
await minify(out1.outputs);
await minify(out2.outputs);
console.timeEnd("minify");
}