-
Notifications
You must be signed in to change notification settings - Fork 2
/
build.ts
132 lines (121 loc) · 3.74 KB
/
build.ts
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
121
122
123
124
125
126
127
128
129
130
131
132
import * as esbuild from 'esbuild';
import * as fs from 'fs';
import * as path from 'path';
import { gzipSync } from 'fflate';
const entryPoints = [
'src/dom/index.ts',
'src/state/index.ts',
'src/stdlib/index.ts',
'src/index.ts',
];
// About 100 characters saved this way. Strings of JS code, so numbers.
const define = {
S_RUNNING: '4',
S_SKIP_RUN_QUEUE: '2',
S_NEEDS_RUN: '1',
};
// This is explained in ./src/index.ts. Haptic's bundle entrypoint isn't a self
// contained bundle. This is to support unbundled developement workflows that
// are ESM-only. For production, your bundler can re-bundle it.
const external = [
'haptic',
'haptic/dom',
'haptic/state',
'haptic/stdlib',
];
const noComment = (a: Uint8Array) => a.subarray(0, -'\n//# sourceMappingURL=index.js.map'.length);
const gzip = (a: Uint8Array) => gzipSync(a, { level: 9 });
const relName = (filepath: string) => filepath.replace(/.*publish\//, '');
const pad = (x: unknown, n: number) => String(x).padEnd(n);
function walk(dir: string, ext: string, matches: string[] = []) {
const files = fs.readdirSync(dir);
for (const filename of files) {
const filepath = path.join(dir, filename);
if (fs.statSync(filepath).isDirectory()) {
walk(filepath, ext, matches);
} else if (path.extname(filename) === ext) {
matches.push(filepath);
}
}
return matches;
}
// Gather existing sizes to compare to later on
const prevJSFiles = walk('publish', '.js');
const prevJSSizes: { [k: string]: number } = {};
prevJSFiles.forEach((filepath) => {
prevJSSizes[relName(filepath)]
= gzip(noComment(fs.readFileSync(filepath))).length;
});
esbuild.build({
entryPoints,
outdir: 'publish',
external,
format: 'esm',
bundle: true,
sourcemap: true,
// This is better than Terser
minify: true,
write: false,
define,
}).then((build) => {
const byExt: { [filepath: string]: esbuild.OutputFile[] } = {};
for (const outFile of build.outputFiles) {
const x = path.extname(outFile.path);
(byExt[x] || (byExt[x] = [])).push(outFile);
}
// Fix path since esbuild does it wrong based off the Chrome debugger...
// TODO: Many values are _still_ undefined... I'll need to compare to rollup
for (const { text, path: filepath } of byExt['.map']!) {
fs.writeFileSync(filepath, text
.replace(/"\..*?\/(\w+)\.ts"/g, '"./$1.ts"')
);
}
for (const { contents, path: filepath } of byExt['.js']!) {
const name = relName(filepath);
const min = noComment(contents);
const mingz = gzip(min);
let delta = '';
if (prevJSSizes[name]) {
const num = mingz.length - prevJSSizes[name]!;
delta = `Δ:${num > 0 ? `+${num}` : num}`;
}
fs.writeFileSync(filepath, contents);
console.log(
`${pad(name, 16)} min:${pad(min.length, 5)} min+gzip:${pad(mingz.length, 4)} ${delta}`
);
}
}).catch((err) => {
console.error('ESM', err);
process.exit(1);
});
// CommonJS for older Node and require()
esbuild.build({
entryPoints,
outdir: 'publish',
outExtension: { '.js': '.cjs' },
external,
format: 'cjs',
bundle: true,
sourcemap: true,
minify: true,
define,
}).catch((err) => {
console.error('CJS', err);
process.exit(1);
});
// Other files for publishing
fs.copyFileSync('./license', './publish/license');
fs.copyFileSync('./src/jsx.d.ts', './publish/jsx.d.ts');
fs.writeFileSync('./publish/readme.md',
fs.readFileSync('./readme.md', 'utf-8')
.replace(
/.\/src\/(\w+)\/readme.md/g,
'https://github.com/heyheyhello/haptic/tree/main/src/$1/')
);
// Need to tweak package.json on write
fs.writeFileSync('./publish/package.json',
fs.readFileSync('./package.json', 'utf-8')
.replaceAll('./publish/', './')
.replace(/,?\s*"scripts": {.*?}/ms, '')
.replace(/,?\s*"devDependencies": {.*?}/ms, '')
);