import { expect, tap } from '@git.zone/tstest/tapbundle'; import * as tsbundle from '../dist_ts/index.js'; import * as path from 'path'; import * as fs from 'fs'; const testBundler = async (bundlerName: 'esbuild' | 'rolldown' | 'rspack', mode: 'test' | 'production') => { const outputFile = `./dist_manual/${bundlerName}-${mode}.js`; const testDir = path.join(process.cwd(), 'test'); // Clean up output directory const outputDir = path.join(testDir, 'dist_manual'); if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } // Clean up output file if exists const outputPath = path.join(testDir, outputFile); if (fs.existsSync(outputPath)) { fs.rmSync(outputPath, { force: true }); } const tsbundleInstance = new tsbundle.TsBundle(); await tsbundleInstance.build( testDir, './ts_web/index.ts', outputFile, { bundler: bundlerName, production: mode === 'production' } ); // Verify output file was created expect(fs.existsSync(outputPath)).toBeTrue(); console.log(`āœ… ${bundlerName} ${mode} mode: success`); }; // Test esbuild tap.test('should bundle with esbuild in test mode', async () => { await testBundler('esbuild', 'test'); }); tap.test('should bundle with esbuild in production mode', async () => { await testBundler('esbuild', 'production'); }); // Test rolldown tap.test('should bundle with rolldown in test mode', async () => { await testBundler('rolldown', 'test'); }); tap.test('should bundle with rolldown in production mode', async () => { await testBundler('rolldown', 'production'); }); // Test rspack tap.test('should bundle with rspack in test mode', async () => { await testBundler('rspack', 'test'); }); tap.test('should bundle with rspack in production mode', async () => { await testBundler('rspack', 'production'); }); // Test size comparison tap.test('should show bundle size comparison', async () => { const testDir = path.join(process.cwd(), 'test'); const sizes: Record = { esbuild: { test: 0, production: 0 }, rolldown: { test: 0, production: 0 }, rspack: { test: 0, production: 0 } }; for (const bundler of ['esbuild', 'rolldown', 'rspack'] as const) { for (const mode of ['test', 'production'] as const) { const filePath = path.join(testDir, `dist_manual/${bundler}-${mode}.js`); if (fs.existsSync(filePath)) { const stats = fs.statSync(filePath); sizes[bundler][mode] = stats.size; } } } console.log('\nšŸ“Š Bundle Size Comparison:'); console.log('ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”'); console.log('│ Bundler │ Test Mode │ Production │'); console.log('ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤'); for (const bundler of ['esbuild', 'rolldown', 'rspack'] as const) { const testSize = (sizes[bundler].test / 1024).toFixed(1) + ' KB'; const prodSize = (sizes[bundler].production / 1024).toFixed(1) + ' KB'; console.log(`│ ${bundler.padEnd(11)} │ ${testSize.padEnd(10)} │ ${prodSize.padEnd(12)} │`); } console.log('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜'); // Verify all sizes are reasonable for (const bundler of ['esbuild', 'rolldown', 'rspack'] as const) { expect(sizes[bundler].test).toBeGreaterThan(0); expect(sizes[bundler].production).toBeGreaterThan(0); // Production bundles should generally be smaller due to minification // but rspack might be larger due to runtime overhead if (bundler !== 'rspack') { expect(sizes[bundler].production).toBeLessThan(sizes[bundler].test); } } }); tap.start();