From 12cce1abe6a8f493a6d21a529b4af8e61e2ced13 Mon Sep 17 00:00:00 2001 From: Linden <65407488+thelindat@users.noreply.github.com> Date: Fri, 6 Sep 2024 15:23:24 +1000 Subject: [PATCH] refactor(build): run tsc before building --- build.js | 156 +++++++++++++++++++++++++++-------------------- package.json | 1 - server/config.ts | 2 +- 3 files changed, 90 insertions(+), 69 deletions(-) diff --git a/build.js b/build.js index 3883096f..b76ef15c 100644 --- a/build.js +++ b/build.js @@ -1,48 +1,79 @@ +//@ts-check + import esbuild from 'esbuild'; -import { readFile, readFileSync, writeFileSync } from 'fs'; +import { readFile, writeFile } from 'fs/promises'; +import { spawn } from 'child_process'; + +const production = process.argv.includes('--mode=production'); +const pkg = JSON.parse(await readFile('package.json', 'utf8')); +const copyright = await readFile('README.md', 'utf8').then((value) => { + return value + ?.replace(/[\s\S]*?## Copyright/, '') + ?.match(/.{1,65}\s+|\S+/g) + ?.join('\n * ') + .replace(/\n{2,}/g, '\n') + .split('\n')[0]; +}); + +console.log(copyright); + +/** + * @param {string} name + * @param {import('esbuild').BuildOptions} options + */ +function getContext(name, options) { + return esbuild + .context({ + bundle: true, + entryPoints: [`${name}/index.ts`], + outfile: `dist/${name}.js`, + keepNames: true, + dropLabels: production ? ['DEV'] : undefined, + legalComments: 'inline', + banner: { + js: `/**\n * ${copyright} */`, + }, + plugins: [ + { + name: 'build', + setup(build) { + build.onEnd((result) => { + if (!result || result.errors.length === 0) console.log(`Successfully built ${name}`); + }); + }, + }, + ], + ...options, + }) + .catch(() => process.exit(1)); +} -/** @type {import('esbuild').BuildOptions} */ -const server = { +const server = await getContext('server', { platform: 'node', target: ['node16'], format: 'cjs', -}; +}); -/** @type {import('esbuild').BuildOptions} */ -const client = { +const client = await getContext('client', { platform: 'browser', target: ['es2021'], format: 'iife', -}; +}); -const production = process.argv.includes('--mode=production'); -const buildCmd = production ? esbuild.build : esbuild.context; -const wordWrap = new RegExp(`.{1,65}\\s+|\\S+`, 'g'); -const packageJson = JSON.parse(readFileSync('package.json', { encoding: 'utf8' })); -const copyright = readFileSync('README.md', { encoding: 'utf8' }) - .replace(/[\s\S]*?## Copyright/, '') - .match(wordWrap) - .join('\n * ') - .replace(/\n{2,}/g, '\n'); - -console.log(copyright.split('\n')[0]); - -writeFileSync( - '.yarn.installed', - new Date().toLocaleString('en-AU', { timeZone: 'UTC', timeStyle: 'long', dateStyle: 'full' }) -); - -writeFileSync( - 'fxmanifest.lua', - `fx_version 'cerulean' +async function build() { + return Promise.all([server.rebuild(), client.rebuild()]).then(() => { + writeFile('.yarn.installed', new Date().toISOString()); + writeFile( + 'fxmanifest.lua', + `fx_version 'cerulean' game 'gta5' -name '${packageJson.name}' -author '${packageJson.author}' -version '${packageJson.version}' -license '${packageJson.license}' -repository '${packageJson.repository.url}' -description '${packageJson.description}' +name '${pkg.name}' +author '${pkg.author}' +version '${pkg.version}' +license '${pkg.license}' +repository '${pkg.repository.url}' +description '${pkg.description}' dependencies { '/server:7290', @@ -52,7 +83,6 @@ dependencies { files { 'lib/init.lua', 'lib/client/**.lua', - 'imports/client.lua', 'locales/*.json', 'common/data/*.json', } @@ -61,38 +91,30 @@ client_script 'dist/client.js' server_script 'dist/server.js' ` -); - -for (const context of ['client', 'server']) { - buildCmd({ - bundle: true, - entryPoints: [`${context}/index.ts`], - outfile: `dist/${context}.js`, - keepNames: true, - dropLabels: production ? ['DEV'] : undefined, - legalComments: 'inline', - banner: { - js: `/**\n * ${copyright} */`, - }, - plugins: production - ? undefined - : [ - { - name: 'rebuild', - setup(build) { - const cb = (result) => { - if (!result || result.errors.length === 0) console.log(`Successfully built ${context}`); - }; - build.onEnd(cb); - }, - }, - ], - ...(context === 'client' ? client : server), - }) - .then((build) => { - if (production) return console.log(`Successfully built ${context}`); + ); + }); +} - build.watch(); - }) - .catch(() => process.exit(1)); +const tsc = spawn(`tsc --build ${production ? '' : '--watch --preserveWatchOutput'} && tsc-alias`, { + stdio: ['inherit', 'pipe', 'inherit'], + shell: true, +}); + +if (production) { + tsc.on('close', async (code) => { + if (code !== 0) return process.exit(code); + + await build(); + + process.exit(0); + }); } + +tsc.stdout.on('data', async (data) => { + const output = data.toString(); + process.stdout.write(output); + + if (output.includes('Found 0 errors.')) { + await build(); + } +}); diff --git a/package.json b/package.json index bff48501..1a208dea 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "./server": "./package/lib/server/index.js" }, "scripts": { - "prepare": "tsc --build && tsc-alias", "build": "node build.js --mode=production", "watch": "node build.js" }, diff --git a/server/config.ts b/server/config.ts index f7778944..62c2c2f0 100644 --- a/server/config.ts +++ b/server/config.ts @@ -1,3 +1,3 @@ export * from '../common/config'; -export const CREATE_DEFAULT_ACCOUNT = GetConvarInt('ox:createDefaultAccount', 1) === 1; \ No newline at end of file +export const CREATE_DEFAULT_ACCOUNT = GetConvarInt('ox:createDefaultAccount', 1) === 1;