diff --git a/package.json b/package.json index d427724687f838..8d1e63ba0deec5 100644 --- a/package.json +++ b/package.json @@ -154,6 +154,7 @@ "babel-plugin-transform-inline-environment-variables": "^0.4.4", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "chalk": "^5.4.1", + "chokidar": "^4.0.3", "compression-webpack-plugin": "^11.1.0", "concurrently": "^9.1.2", "cpy-cli": "^5.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 648a398060eadc..4db362cdf9fa7c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -184,6 +184,9 @@ importers: chalk: specifier: ^5.4.1 version: 5.4.1 + chokidar: + specifier: ^4.0.3 + version: 4.0.3 compression-webpack-plugin: specifier: ^11.1.0 version: 11.1.0(webpack@5.99.8) diff --git a/scripts/buildTypes.mts b/scripts/buildTypes.mts index 78ab604506f735..fd0e7fddf28c12 100644 --- a/scripts/buildTypes.mts +++ b/scripts/buildTypes.mts @@ -5,6 +5,7 @@ import yargs from 'yargs'; import { $ } from 'execa'; import * as babel from '@babel/core'; import { parse } from 'jsonc-parser'; +import chokidar from 'chokidar'; const $$ = $({ stdio: 'inherit' }); @@ -57,15 +58,10 @@ async function copyDeclarations(sourceDirectory: string, destinationDirectory: s await fs.cp(fullSourceDirectory, fullDestinationDirectory, { recursive: true, filter: async (src) => { - if (src.startsWith('.')) { - // ignore dotfiles - return false; - } + // eslint-disable-next-line curly + if (src.startsWith('.')) return false; const stats = await fs.stat(src); - if (stats.isDirectory()) { - return true; - } - return src.endsWith('.d.ts'); + return stats.isDirectory() || src.endsWith('.d.ts'); }, }); } @@ -74,9 +70,10 @@ interface HandlerArgv { skipTsc: boolean; copy: string[]; removeCss: boolean; + watch?: boolean; } -async function main(argv: HandlerArgv) { +async function buildOnce(argv: HandlerArgv) { const packageRoot = process.cwd(); const tsconfigPath = path.join(packageRoot, 'tsconfig.build.json'); const tsconfigExists = await fs.access(tsconfigPath).then( @@ -118,6 +115,41 @@ async function main(argv: HandlerArgv) { await Promise.all(tsbuildinfo.map(async (file) => fs.rm(file))); } +async function main(argv: HandlerArgv) { + if (argv.watch) { + // eslint-disable-next-line no-console + console.log('[watch] Starting in watch mode...'); + + let isBuilding = false; + const triggerBuild = async () => { + // eslint-disable-next-line curly + if (isBuilding) return; + isBuilding = true; + try { + await buildOnce(argv); + // eslint-disable-next-line no-console + console.log('[watch] Build complete'); + } catch (err) { + console.error('[watch] Build failed:', err); + } finally { + isBuilding = false; + } + }; + + await triggerBuild(); + + chokidar + .watch(['src/**/*.ts', 'src/**/*.d.ts'], { ignoreInitial: true }) + .on('all', async (event, tmpPath) => { + // eslint-disable-next-line no-console + console.log(`[watch] ${event}: ${tmpPath}`); + await triggerBuild(); + }); + } else { + await buildOnce(argv); + } +} + yargs(process.argv.slice(2)) .command( '$0', @@ -139,9 +171,16 @@ yargs(process.argv.slice(2)) type: 'boolean', default: false, describe: 'Set to `true` if you want to remove the css imports in the type definitions', + }) + .option('watch', { + type: 'boolean', + default: false, + describe: 'Watch mode: rebuild when source files change', }); }, - main, + async (argv) => { + await main(argv); + }, ) .help() .strict(true)