summaryrefslogtreecommitdiff
path: root/packages/frontend-shared/build.js
blob: 9941114757928c4058d92d2c1f523d1554f47029 (plain)
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
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import * as esbuild from 'esbuild';
import { build } from 'esbuild';
import { globSync } from 'glob';
import { execa } from 'execa';

const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
const _package = JSON.parse(fs.readFileSync(_dirname + '/package.json', 'utf-8'));

const entryPoints = globSync('./js/**/**.{ts,tsx}');

/** @type {import('esbuild').BuildOptions} */
const options = {
	entryPoints,
	minify: process.env.NODE_ENV === 'production',
	outdir: './js-built',
	target: 'es2022',
	platform: 'browser',
	format: 'esm',
	sourcemap: 'linked',
};

const args = process.argv.slice(2).map(arg => arg.toLowerCase());

// js-built配下をすべて削除する
if (!args.includes('--no-clean')) {
	fs.rmSync('./js-built', { recursive: true, force: true });
}

if (args.includes('--watch')) {
	await watchSrc();
} else {
	await buildSrc();
}

async function buildSrc() {
	console.log(`[${_package.name}] start building...`);

	await build(options)
		.then(() => {
			console.log(`[${_package.name}] build succeeded.`);
		})
		.catch((err) => {
			process.stderr.write(err.stderr);
			process.exit(1);
		});

	if (process.env.NODE_ENV === 'production') {
		console.log(`[${_package.name}] skip building d.ts because NODE_ENV is production.`);
	} else {
		await buildDts();
	}

	fs.copyFileSync('./js/emojilist.json', './js-built/emojilist.json');

	console.log(`[${_package.name}] finish building.`);
}

function buildDts() {
	return execa(
		'tsc',
		[
			'--project', 'tsconfig.json',
			'--outDir', 'js-built',
			'--declaration', 'true',
			'--emitDeclarationOnly', 'true',
		],
		{
			stdout: process.stdout,
			stderr: process.stderr,
		},
	);
}

async function watchSrc() {
	const plugins = [{
		name: 'gen-dts',
		setup(build) {
			build.onStart(() => {
				console.log(`[${_package.name}] detect changed...`);
			});
			build.onEnd(async result => {
				if (result.errors.length > 0) {
					console.error(`[${_package.name}] watch build failed:`, result);
					return;
				}
				await buildDts();
			});
		},
	}];

	console.log(`[${_package.name}] start watching...`);

	const context = await esbuild.context({ ...options, plugins });
	await context.watch();

	await new Promise((resolve, reject) => {
		process.on('SIGHUP', resolve);
		process.on('SIGINT', resolve);
		process.on('SIGTERM', resolve);
		process.on('uncaughtException', reject);
		process.on('exit', resolve);
	}).finally(async () => {
		await context.dispose();
		console.log(`[${_package.name}] finish watching.`);
	});
}