vibetunnel/web/scripts/dev.js
Helmut Januschka f3b2022d48
Integrate screencap functionality for remote screen sharing (#209)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2025-07-06 03:31:34 +01:00

129 lines
No EOL
3.7 KiB
JavaScript

const { spawn } = require('child_process');
const path = require('path');
const esbuild = require('esbuild');
const { devOptions } = require('./esbuild-config.js');
console.log('Starting development mode...');
// Validate version sync first
require('child_process').execSync('node scripts/validate-version-sync.js', { stdio: 'inherit' });
// Parse command line arguments using Node's built-in parseArgs
const { parseArgs } = require('util');
const { values, positionals } = parseArgs({
options: {
'client-only': {
type: 'boolean',
default: false,
},
port: {
type: 'string',
},
bind: {
type: 'string',
},
},
allowPositionals: true,
});
const watchServer = !values['client-only'];
// Build server args from parsed values
const serverArgs = [];
if (values.port) {
serverArgs.push('--port', values.port);
}
if (values.bind) {
serverArgs.push('--bind', values.bind);
}
// Initial build of assets and CSS
console.log('Initial build...');
require('child_process').execSync('node scripts/ensure-dirs.js', { stdio: 'inherit' });
require('child_process').execSync('node scripts/copy-assets.js', { stdio: 'inherit' });
require('child_process').execSync('pnpm exec tailwindcss -i ./src/client/styles.css -o ./public/bundle/styles.css', { stdio: 'inherit' });
// Build the command parts
const commands = [
// Watch CSS
['pnpm', ['exec', 'tailwindcss', '-i', './src/client/styles.css', '-o', './public/bundle/styles.css', '--watch']],
// Watch assets
['pnpm', ['exec', 'chokidar', 'src/client/assets/**/*', '-c', 'node scripts/copy-assets.js']],
];
// Add server watching if not client-only
if (watchServer) {
const serverCommand = ['pnpm', ['exec', 'tsx', 'watch', 'src/cli.ts', '--no-auth', ...serverArgs]];
commands.push(serverCommand);
}
// Set up esbuild contexts for watching
async function startBuilding() {
try {
// Create esbuild contexts
const clientContext = await esbuild.context({
...devOptions,
entryPoints: ['src/client/app-entry.ts'],
outfile: 'public/bundle/client-bundle.js',
});
const testContext = await esbuild.context({
...devOptions,
entryPoints: ['src/client/test-entry.ts'],
outfile: 'public/bundle/test.js',
});
const screencapContext = await esbuild.context({
...devOptions,
entryPoints: ['src/client/screencap-entry.ts'],
outfile: 'public/bundle/screencap.js',
});
const swContext = await esbuild.context({
...devOptions,
entryPoints: ['src/client/sw.ts'],
outfile: 'public/sw.js',
format: 'iife', // Service workers need IIFE format
});
// Start watching
await clientContext.watch();
await testContext.watch();
await screencapContext.watch();
await swContext.watch();
console.log('ESBuild watching client bundles...');
// Start other processes
const processes = commands.map(([cmd, args], index) => {
const proc = spawn(cmd, args, {
stdio: 'inherit',
shell: process.platform === 'win32'
});
proc.on('error', (err) => {
console.error(`Process ${index} error:`, err);
});
return proc;
});
// Handle exit
process.on('SIGINT', async () => {
console.log('\nStopping all processes...');
await clientContext.dispose();
await testContext.dispose();
await screencapContext.dispose();
await swContext.dispose();
processes.forEach(proc => proc.kill());
process.exit(0);
});
console.log(`Development mode started (${watchServer ? 'full' : 'client only'})`);
} catch (error) {
console.error('Failed to start build:', error);
process.exit(1);
}
}
startBuilding();