-
Notifications
You must be signed in to change notification settings - Fork 107
POC: Migrate build system from Babel to SWC #2199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat/pnpm-migration
Are you sure you want to change the base?
Conversation
Implement SWC-based build system for all component packages as a proof of concept: Build Configuration: - Add .swcrc with TypeScript/TSX parser, Emotion React support, and legacy decorators - Create packages/ui-scripts/lib/build/swc.js for SWC compilation (ES modules only) - Rename existing build command to build:babel in packages/ui-scripts/lib/build/babel.js - Update scripts/bootstrap.js to use SWC build by default Package Updates (92 packages): - Remove --modules flags from build scripts (SWC only builds ESM) - Change "main" field from "./lib/index.js" to "./es/index.js" - Update command-utils exports field to point to "./es/index.js" - Disable CommonJS builds (no lib/ directory generation) Tooling & Infrastructure: - Update scripts/clean.js to preserve es/ directories for pre-built tooling packages - Copy lib/ to es/ for tooling packages (pkg-utils, command-utils, ui-scripts) - Update vitest.config.mts to prefer ESM entry points - Add scripts/disable-cjs-build.js to automate --modules flag removal - Add scripts/update-main-to-esm.js to automate main field updates - Add scripts/remove-decorators.js (unused - decorators are supported by SWC) TypeScript Configuration: - Update tsconfig.build.json files across all packages for ESM builds Build Results: - All 97 component packages successfully build with SWC - ESM-only output in es/ directories - Babel build system preserved as build:babel for reference 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
…n generation ES modules require explicit file extensions in import statements. Added .js extensions to all relative imports in ui-themes source files to fix token generation with ESM-only builds. Changes: - Added .js extensions to 25 import statements across ui-themes package - Updated generate-all-tokens to use /es/ paths instead of /lib/ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Remove obsolete lib/ directory deletion logic since packages now only build to es/ directory with SWC. The script now: - Deletes es/ for component packages (rebuilt on bootstrap) - Preserves es/ for tooling packages (pre-built code needed for bootstrap) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Clean script improvements: - Add 'lib' to DIRS_TO_DELETE for cleaning legacy Babel builds - Preserve both 'lib' and 'es' directories in tooling packages - Handles branch switching between Babel and SWC builds Bootstrap script improvements: - Add summary table showing phase timings and status - Track individual phases: Clean, Icon build, SWC compilation, Token generation, TypeScript declarations - Calculate total time using wall-clock time to properly account for parallel execution - Display errors with detailed messages if any phase fails 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Performance improvements: - Run SWC compilation and TypeScript declarations in parallel - Move token generation after parallel build phase (requires SWC output) - Add "type": "module" to ui-themes to eliminate Node.js reparse overhead Results: - Bootstrap time reduced from ~50s to ~35s (30% faster) - SWC (24s) + TypeScript (31s) now run concurrently (31s total) - Token generation optimized to 0.8s 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
| allPackages = allPackages || getPackages() // eslint-disable-line no-param-reassign | ||
|
|
||
| const result = childProcess | ||
| .execSync('git diff ' + commitIsh + ' --name-only', { stdio: 'pipe' }) |
Check warning
Code scanning / CodeQL
Unsafe shell command constructed from library input Medium
library input
shell command
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 17 days ago
The correct fix is to avoid using shell-interpreted command strings for arguments coming from function input. This means replacing childProcess.execSync('git diff ' + commitIsh + ' --name-only', ...) with an invocation of childProcess.execFileSync, which accepts the command and arguments as an array. This prevents shell interpretation of commitIsh and ensures only the intended git command is executed. Modify line 36 of packages/pkg-utils/es/get-changed-packages.js to use execFileSync or, if you wish to keep using execSync for stream control or compatibility, use a quoting library like shell-quote to escape commitIsh (though using an argument array is better security practice and follows recommended patterns). No additional imports are needed unless the quoting library option is chosen, but the preferred fix is to change the API to use the argument array.
-
Copy modified line R36
| @@ -33,7 +33,7 @@ | ||
| allPackages = allPackages || getPackages() // eslint-disable-line no-param-reassign | ||
|
|
||
| const result = childProcess | ||
| .execSync('git diff ' + commitIsh + ' --name-only', { stdio: 'pipe' }) | ||
| .execFileSync('git', ['diff', commitIsh, '--name-only'], { stdio: 'pipe' }) | ||
| .toString() | ||
| const changedFiles = result.split('\n') | ||
|
|
Attempted to fix dev server by adjusting paths for TypeScript compilation output structure. These changes will be reverted in favor of fixing tsconfig.node.build.json with rootDir. Changes: - Updated paths in build-docs.mts to account for lib/buildScripts/ structure - Fixed package.json and webpack.config.mjs import paths - Added ui-babel-preset/es/ directory for docs build - Added DEV_SERVER_INVESTIGATION.md analysis This commit preserves the work before reverting to simpler solution.
Work in progress on fixing the dev server after adding rootDir to tsconfig. Changes: - Added rootDir: "./buildScripts" to tsconfig.node.build.json to flatten output - Fixed paths in build-docs.mts to work with flat lib/ structure - Changed packagesDir to use absolute projectRoot path - Fixed package.json require to use path.join with projectRoot - Removed NODE_OPTIONS memory flag (not needed) Current Status: - TypeScript compiles correctly with flat output structure - build-docs.mjs is in lib/ (not lib/buildScripts/) - Dev server not yet verified to be working - Need to test if dev server starts without errors Next Steps: - Verify dev server starts and processes correct number of files (~600) - Test webpack compilation completes without memory errors - Use Playwright to verify the site loads at http://localhost:9090
Summary
This is a proof-of-concept migration from Babel to SWC for faster build times. The POC demonstrates:
Key Changes
Build System:
.swcrc)--modulesflags from all package build scriptses/instead oflib/.jsextensions to all ESM imports in ui-themes for proper module resolutionTooling:
generate-all-tokens.jsto use/es/paths instead of/lib/lib/andes/directoriesPerformance:
Test Results
Unit Tests: 2365 passing / 3 failing (99.87% pass rate)
Known Issues:
TopNavBarItem- 5 unexpected "No theme provided" warningsColorPicker- Theme warning before expected validation warningColorMixer- Theme warning before expected validation warningTest Plan
pnpm run bootstrappnpm run build:tokenspnpm run test:vitestpnpm run dev(optional)Dependencies
Note: This branch is built on top of the pnpm migration branch which has not yet been merged to master. The first 3 commits are from that work:
57b6c70736- pnpm Phase 1 migration8f3378f4b7- Clean script optimizationc4a8aa957b- Revert unrelated changesThe SWC-specific commits start from
ca350f5a72.Notes
build:babelcommands🤖 Generated with Claude Code