-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.mjs
133 lines (116 loc) · 3.28 KB
/
build.mjs
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
133
import fs from "fs/promises";
import path from "path";
import * as esbuild from "esbuild";
/**
* Build config for esbuild
* @typedef {import("esbuild").BuildOptions} BuildOptions
* @type {BuildOptions}
*/
const config = {
bundle: false,
platform: "node",
packages: "external",
outdir: "dist",
minify: false,
target: "node16"
};
const __dirname = new URL(".", import.meta.url).pathname.slice(0, -1);
/**
* Removes old build directory and creates a fresh one
*/
async function handleClean() {
console.log("Cleaning");
await fs.rm(config.outdir, { recursive: true, force: true });
await fs.mkdir(config.outdir);
}
/**
* finds all js files in a directory
*/
async function discoverDirectory(dirPath) {
const dir = await fs.readdir(dirPath);
return dir
.filter(str => str.endsWith(".js"))
.map(file => path.relative(__dirname, path.join(dirPath, file)));
}
async function handlePkgJson() {
const pkg = await fs
.readFile("package.json", "utf-8")
.then(file => JSON.parse(file));
if (typeof pkg != "object" || pkg === null) {
throw new Error("Could not read package.json");
}
console.log("Processing package.json");
const { publishConfig, "clean-publish": cleanPublish, ...pkgRest } = pkg;
const pkgProcessed = Object.assign({}, pkgRest, publishConfig);
// handle removing fields
const removeFields = ["devDependencies", ...cleanPublish.fields];
for (const field of removeFields) {
delete pkgProcessed[field];
}
return fs.writeFile(
path.join(config.outdir, "package.json"),
JSON.stringify(pkgProcessed, null, 2),
"utf-8"
);
}
/**
* Statically copy files to the outdir
* @typedef {string | [string, string]} File
* @typedef {File[]} Files
* @param {Files} files Array of files to copy to outdir. Use nested array to change filename such as ["foo.build.json", "foo.json"].
* @returns
*/
async function copyFiles(files) {
const res = await Promise.allSettled(
files.map(file => {
const [fileIn, fileOut] = Array.isArray(file) ? file : [file, file];
const outPath = path.join(config.outdir, fileOut);
console.log(`Copying ${fileIn} to ${outPath}`);
return fs.cp(fileIn, outPath, { force: true });
})
);
const err = res.find(r => r.status == "rejected");
if (err) {
throw new Error(`Error while copying files: ${err.reason}`);
}
return;
}
/**
* Handle build of CJS bundle
* @returns Promise
*/
function buildCJS(entryPoints) {
console.log("Building cjs bundles");
return esbuild.build({
...config,
entryPoints,
format: "cjs"
});
}
async function build() {
// Clean dist directory
await handleClean();
console.log("Discovering source files");
const dirs = await Promise.all([
discoverDirectory("src"),
discoverDirectory("src/configs"),
discoverDirectory("src/rules"),
discoverDirectory("src/legacy")
]);
const entryPoints = dirs.flat();
console.log("Starting build");
const res = await Promise.allSettled([
buildCJS(entryPoints),
copyFiles(["README.md", "LICENSE"]),
handlePkgJson()
]);
// handle logging errors
const err = res.filter(r => r.status === "rejected");
for (const e of err) {
console.error(`BuildError: ${e.reason}`);
}
if (err.length > 0) process.exit(1);
}
build().then(() => {
console.log("Completed build");
});