|
1 | 1 | import assert from 'node:assert';
|
2 |
| -import { existsSync } from 'node:fs'; |
| 2 | +import path from 'node:path'; |
| 3 | +import { existsSync, rmSync, copyFileSync } from 'node:fs'; |
3 | 4 | import { cp, rm } from 'node:fs/promises';
|
4 | 5 | import { execa } from 'execa';
|
| 6 | +import chokidar from 'chokidar'; |
5 | 7 | import esbuild from 'esbuild';
|
6 |
| -import glob from 'fast-glob'; |
7 | 8 | import { nodeExternalsPlugin } from 'esbuild-node-externals';
|
8 | 9 |
|
9 |
| -// clean dist |
10 |
| -await rm('dist', { recursive: true, force: true }); |
11 |
| - |
12 |
| -// only do typechecking and emit the type declarations with tsc |
13 |
| -execa('tsc', ['--emitDeclarationOnly', '--project', './tsconfig.build.json'], { |
14 |
| - stdio: 'inherit', |
15 |
| - preferLocal: true, |
16 |
| -}); |
17 |
| - |
18 |
| -// build with esbuild |
19 |
| -await esbuild.build({ |
20 |
| - entryPoints: ['src/index.ts'], |
21 |
| - bundle: true, |
22 |
| - tsconfig: './tsconfig.build.json', |
23 |
| - platform: 'node', |
24 |
| - format: 'esm', |
25 |
| - outdir: 'dist', |
26 |
| - define: { |
27 |
| - 'process.env.TUTORIALKIT_DEV': JSON.stringify(process.env.TUTORIALKIT_DEV ?? null), |
28 |
| - }, |
29 |
| - plugins: [nodeExternalsPlugin()], |
30 |
| -}); |
31 |
| - |
32 |
| -if (existsSync('./dist/default')) { |
33 |
| - assert.fail('TypeScript transpiled the default folder, it means that the tsconfig has an issue'); |
| 10 | +const isWatch = process.argv.includes('--watch'); |
| 11 | + |
| 12 | +if (!isWatch) { |
| 13 | + // clean dist |
| 14 | + await rm('dist', { recursive: true, force: true }); |
| 15 | +} |
| 16 | + |
| 17 | +await generateTypes(); |
| 18 | +await buildJS(); |
| 19 | +await copyDefaultFolder(); |
| 20 | + |
| 21 | +async function generateTypes() { |
| 22 | + // only do typechecking and emit the type declarations with tsc |
| 23 | + const args = [ |
| 24 | + '--emitDeclarationOnly', |
| 25 | + '--project', |
| 26 | + './tsconfig.build.json', |
| 27 | + isWatch && '--watch', |
| 28 | + '--preserveWatchOutput', |
| 29 | + ].filter((s) => !!s); |
| 30 | + |
| 31 | + const promise = execa('tsc', args, { stdio: 'inherit', preferLocal: true }); |
| 32 | + |
| 33 | + if (!isWatch && existsSync('./dist/default')) { |
| 34 | + await promise; |
| 35 | + assert.fail('TypeScript transpiled the default folder, it means that the tsconfig has an issue'); |
| 36 | + } |
34 | 37 | }
|
35 | 38 |
|
36 |
| -// copy default folder unmodified |
37 |
| -await cp('./src/default', './dist/default', { recursive: true }); |
| 39 | +async function buildJS() { |
| 40 | + const context = await esbuild.context({ |
| 41 | + entryPoints: ['src/index.ts'], |
| 42 | + bundle: true, |
| 43 | + tsconfig: './tsconfig.build.json', |
| 44 | + platform: 'node', |
| 45 | + format: 'esm', |
| 46 | + outdir: 'dist', |
| 47 | + define: { |
| 48 | + 'process.env.TUTORIALKIT_DEV': JSON.stringify(process.env.TUTORIALKIT_DEV ?? null), |
| 49 | + }, |
| 50 | + plugins: [nodeExternalsPlugin()], |
| 51 | + }); |
38 | 52 |
|
39 |
| -// remove test files |
40 |
| -await glob('./dist/default/**/*.spec.ts').then((testFiles) => Promise.all(testFiles.map((testFile) => rm(testFile)))); |
| 53 | + if (isWatch) { |
| 54 | + context.watch(); |
| 55 | + } else { |
| 56 | + await context.rebuild(); |
| 57 | + await context.dispose(); |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +async function copyDefaultFolder() { |
| 62 | + const src = './src/default'; |
| 63 | + const dist = './dist/default'; |
| 64 | + await rm(dist, { recursive: true, force: true }); |
| 65 | + |
| 66 | + // copy default folder unmodified, without test files |
| 67 | + await cp(src, dist, { |
| 68 | + recursive: true, |
| 69 | + filter: (filename) => !filename.endsWith('.spec.ts'), |
| 70 | + }); |
| 71 | + |
| 72 | + if (isWatch) { |
| 73 | + chokidar.watch(src).on('all', (event, filePath, stats) => { |
| 74 | + if (stats?.isDirectory() !== true) { |
| 75 | + const target = path.join(dist, path.relative(src, filePath)); |
| 76 | + |
| 77 | + if (event === 'unlink') { |
| 78 | + rmSync(target); |
| 79 | + } else { |
| 80 | + copyFileSync(filePath, target); |
| 81 | + } |
| 82 | + } |
| 83 | + }); |
| 84 | + } |
| 85 | +} |
0 commit comments