Skip to content

Commit 495a16a

Browse files
committed
convert scripts to cjs extension, and begin conversion to esm format
1 parent 01d498e commit 495a16a

File tree

3 files changed

+225
-15
lines changed

3 files changed

+225
-15
lines changed
File renamed without changes.

scripts/build.cjs

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
const { basename } = require('path');
2+
//const { esbuildPluginDecorator } = require('esbuild-plugin-decorator');
3+
const {
4+
realpathSync, readFileSync, writeFileSync, renameSync, existsSync
5+
} = require('fs');
6+
const { spawnSync, execSync } = require('child_process');
7+
const esbuild = require('esbuild');
8+
9+
const buildConfig = {
10+
basePath: `${__dirname}/..`,
11+
bundle: true,
12+
constants: {},
13+
entry: 'src/index.ts',
14+
format: 'cjs',
15+
minify: false,
16+
outdir: 'dist',
17+
platform: {
18+
name: 'node',
19+
version: 18,
20+
},
21+
};
22+
23+
const pkg = require(realpathSync(`${buildConfig.basePath}/package.json`, { encoding: 'utf-8' }));
24+
25+
class Builder {
26+
config = {
27+
binaries: false,
28+
production: false,
29+
verbose: false,
30+
};
31+
32+
write(msg) {
33+
process.stdout.write(`${msg}`.toString());
34+
}
35+
36+
writeln(msg) {
37+
this.write(`${msg}\n`);
38+
}
39+
40+
async compile() {
41+
const result = await esbuild.build({
42+
absWorkingDir: buildConfig.basePath,
43+
allowOverwrite: true,
44+
bundle: buildConfig.bundle,
45+
define: {
46+
__APP_VERSION__: `'${pkg.version}'`,
47+
__COMPILED_AT__: `'${new Date().toUTCString()}'`,
48+
...buildConfig.constants,
49+
},
50+
entryPoints: [ buildConfig.entry ],
51+
format: buildConfig.format,
52+
logLevel: 'silent',
53+
metafile: true,
54+
minify: buildConfig.minify,
55+
outdir: buildConfig.outdir,
56+
platform: buildConfig.platform.name,
57+
experimentalOptimizeImports: true,
58+
plugins: [
59+
// esbuildPluginDecorator({
60+
// compiler: 'tsc',
61+
// tsconfigPath: `${buildConfig.basePath}/tsconfig.json`,
62+
// }),
63+
],
64+
target: `${buildConfig.platform.name}${buildConfig.platform.version}`,
65+
});
66+
67+
return new Promise(resolve => resolve(result));
68+
}
69+
70+
sizeForDisplay(bytes) {
71+
return `${`${bytes / 1024}`.slice(0, 4)} kb`;
72+
}
73+
74+
reportCompileResults(results) {
75+
results.errors.forEach(errorMsg => this.writeln(`* Error: ${errorMsg}`));
76+
results.warnings.forEach(msg => this.writeln(`* Warning: ${msg}`));
77+
78+
Object.keys(results.metafile.outputs).forEach(fn => {
79+
this.writeln(`* » created '${fn}' (${this.sizeForDisplay(results.metafile.outputs[fn].bytes)})`);
80+
});
81+
}
82+
83+
processArgv() {
84+
const argMap = {
85+
'--binaries': { name: 'binaries', value: true },
86+
'--prod': { name: 'production', value: true },
87+
'--production': { name: 'production', value: true },
88+
'--verbose': { name: 'verbose', value: true },
89+
'-p': { name: 'production', value: true },
90+
'-v': { name: 'verbose', value: true },
91+
};
92+
93+
process.argv
94+
.slice(2)
95+
.map(arg => {
96+
const hasMappedArg = typeof argMap[arg] === 'undefined';
97+
return hasMappedArg ? { name: arg.replace(/^-+/, ''), value: true } : argMap[arg];
98+
})
99+
.forEach(data => (this.config[data.name] = data.value));
100+
101+
console.log(this.config);
102+
}
103+
104+
convertToProductionFile() {
105+
const filename = basename(buildConfig.entry).replace(/\.ts$/, '.js');
106+
const newFilename = pkg.name;
107+
const binaryFilename = `${buildConfig.outdir}/${filename.replace(/.js$/, '')}`;
108+
const contents = readFileSync(`${buildConfig.outdir}/${filename}`, { encoding: 'utf-8' });
109+
110+
spawnSync('chmod', [ '+x', `${buildConfig.outdir}/${filename}` ], { stdio: 'ignore' });
111+
writeFileSync(`${buildConfig.outdir}/${filename}`, `#!/usr/bin/node\n\n${contents}`, { encoding: 'utf-8' });
112+
renameSync(`${buildConfig.outdir}/${filename}`, `${buildConfig.outdir}/${newFilename}`);
113+
114+
if (existsSync(binaryFilename)) {
115+
renameSync(binaryFilename, `${buildConfig.outdir}/${newFilename}-${pkg.version}`);
116+
}
117+
}
118+
119+
compileBinaries() {
120+
const platforms = [ 'linux', 'macos', 'win' ];
121+
const filename = basename(buildConfig.entry).replace(/\.ts$/, '.js');
122+
const targets = platforms.map(t => `node16-${t.toLowerCase()}-x64`);
123+
const cmd = `npx pkg --compress Brotli --targets ${targets.join(',')} --out-path ${buildConfig.outdir} ${buildConfig.outdir}/${filename}`;
124+
125+
execSync(cmd, { stdio: 'inherit' });
126+
127+
const origBinaries = platforms
128+
.map(os => `${buildConfig.outdir}/${filename.replace(/.js$/, '')}-${os}`)
129+
.map(fn => (fn.includes('-win') ? `${fn}.exe` : fn));
130+
131+
const newBinaries = platforms
132+
.map(os => `${buildConfig.outdir}/${pkg.name}-v${pkg.version}-${os}-x64`)
133+
.map(fn => (fn.includes('-win') ? `${fn}.exe` : fn));
134+
135+
for (const originalFn of origBinaries) {
136+
const newFn = newBinaries[origBinaries.indexOf(originalFn)];
137+
renameSync(originalFn, newFn);
138+
spawnSync('chmod', [ '+x', newFn ], { stdio: 'ignore' });
139+
}
140+
}
141+
142+
async run() {
143+
this.processArgv();
144+
145+
if (this.config.verbose) {
146+
this.writeln(`* Using esbuild v${esbuild.version}.`);
147+
}
148+
149+
this.write(`* Compiling application...${this.config.verbose ? '\n' : ''}`);
150+
151+
const startedTs = new Date().getTime();
152+
const results = await this.compile();
153+
154+
if (this.config.binaries) {
155+
this.compileBinaries();
156+
}
157+
158+
const finishedTs = new Date().getTime();
159+
160+
if (this.config.verbose) {
161+
this.reportCompileResults(results);
162+
}
163+
164+
this.writeln(`${this.config.verbose ? '* D' : 'd'}one. (${finishedTs - startedTs} ms)`);
165+
166+
if (this.config.production) {
167+
this.convertToProductionFile();
168+
}
169+
}
170+
}
171+
172+
new Builder().run();

scripts/build.js

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
const { basename } = require('path');
2-
//const { esbuildPluginDecorator } = require('esbuild-plugin-decorator');
3-
const {
4-
realpathSync, readFileSync, writeFileSync, renameSync, existsSync
5-
} = require('fs');
6-
const { spawnSync, execSync } = require('child_process');
7-
const esbuild = require('esbuild');
1+
import esbuild from 'esbuild';
2+
import { execSync, spawnSync } from 'node:child_process';
3+
import { existsSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
4+
import { basename, resolve } from 'node:path';
85

6+
import pkg from '../package.json';
7+
8+
const platformToTarget = platform => {
9+
return `${platform.name}${platform.version}`;
10+
};
11+
12+
const isValidFormat = format => [ 'esm', 'cjs', 'iife' ].includes(format);
13+
14+
/** @type { import('esbuild').BuildOptions } */
915
const buildConfig = {
10-
basePath: `${__dirname}/..`,
16+
basePath: resolve(import.meta.url, '..'),
1117
bundle: true,
1218
constants: {},
1319
entry: 'src/index.ts',
@@ -16,17 +22,17 @@ const buildConfig = {
1622
outdir: 'dist',
1723
platform: {
1824
name: 'node',
19-
version: 14,
25+
version: 18,
2026
},
2127
};
2228

23-
const pkg = require(realpathSync(`${buildConfig.basePath}/package.json`, { encoding: 'utf-8' }));
24-
2529
class Builder {
2630
config = {
2731
binaries: false,
2832
production: false,
2933
verbose: false,
34+
esm: false,
35+
cjs: false,
3036
};
3137

3238
write(msg) {
@@ -56,11 +62,12 @@ class Builder {
5662
platform: buildConfig.platform.name,
5763
plugins: [
5864
// esbuildPluginDecorator({
59-
// compiler: 'tsc',
60-
// tsconfigPath: `${buildConfig.basePath}/tsconfig.json`,
65+
// compiler: 'tsc',
66+
// tsconfigPath: `${buildConfig.basePath}/tsconfig.json`,
6167
// }),
6268
],
63-
target: `${buildConfig.platform.name}${buildConfig.platform.version}`,
69+
target: platformToTarget(buildConfig.platform),
70+
experimentalOptimizeImports: true,
6471
});
6572

6673
return new Promise(resolve => resolve(result));
@@ -75,12 +82,14 @@ class Builder {
7582
results.warnings.forEach(msg => this.writeln(`* Warning: ${msg}`));
7683

7784
Object.keys(results.metafile.outputs).forEach(fn => {
78-
this.writeln(`* » created '${fn}' (${this.sizeForDisplay(results.metafile.outputs[fn].bytes)})`);
85+
this.writeln(`* » created '${fn}' (${this.sizeForDisplay(results.metafile.outputs[fn].bytes)})`);
7986
});
8087
}
8188

8289
processArgv() {
8390
const argMap = {
91+
'--esm': { name: 'esm', value: true },
92+
'--cjs': { name: 'cjs', value: true },
8493
'--binaries': { name: 'binaries', value: true },
8594
'--prod': { name: 'production', value: true },
8695
'--production': { name: 'production', value: true },
@@ -89,14 +98,41 @@ class Builder {
8998
'-v': { name: 'verbose', value: true },
9099
};
91100

101+
const setConfigOutputFormat = format => {
102+
if (!isValidFormat(format)) {
103+
return;
104+
}
105+
106+
this.config.esm = format === 'esm';
107+
this.config.cjs = format === 'cjs';
108+
};
109+
110+
const getFormatType = () => {
111+
const key = Object.keys(this.config)
112+
.filter(key => isValidFormat(key))
113+
.filter(key => this.config[key] === true)
114+
.shift();
115+
116+
if (typeof key !== 'undefined' && isValidFormat(key)) {
117+
return key;
118+
}
119+
120+
return buildConfig.format;
121+
};
122+
92123
process.argv
93124
.slice(2)
94125
.map(arg => {
95126
const hasMappedArg = typeof argMap[arg] === 'undefined';
96127
return hasMappedArg ? { name: arg.replace(/^-+/, ''), value: true } : argMap[arg];
97128
})
129+
.forEach(data => {
130+
if ([ 'esm', 'cjs' ].includes(data.name)) setConfigOutputFormat(data.name);
131+
})
98132
.forEach(data => (this.config[data.name] = data.value));
99133

134+
buildConfig.format = getFormatType();
135+
100136
console.log(this.config);
101137
}
102138

@@ -107,7 +143,9 @@ class Builder {
107143
const contents = readFileSync(`${buildConfig.outdir}/${filename}`, { encoding: 'utf-8' });
108144

109145
spawnSync('chmod', [ '+x', `${buildConfig.outdir}/${filename}` ], { stdio: 'ignore' });
146+
110147
writeFileSync(`${buildConfig.outdir}/${filename}`, `#!/usr/bin/node\n\n${contents}`, { encoding: 'utf-8' });
148+
111149
renameSync(`${buildConfig.outdir}/${filename}`, `${buildConfig.outdir}/${newFilename}`);
112150

113151
if (existsSync(binaryFilename)) {

0 commit comments

Comments
 (0)