refactor(website-server): Replace esbuild with Rolldown for bundling#1070
refactor(website-server): Replace esbuild with Rolldown for bundling#1070
Conversation
Migrate the website server bundling from esbuild to Rolldown 1.0.0-beta.58. Rolldown produces a 5% smaller bundle (10.32MB → 9.8MB) while maintaining the same functionality. Key changes: - Update bundle.mjs to use Rolldown's API with inlineDynamicImports - Remove esbuild dependency, add rolldown ^1.0.0-beta.58
Apply aggressive tree-shaking and minification options: - treeshake.moduleSideEffects: false for aggressive dead code elimination - compress.dropConsole/dropDebugger: true (winston handles logging) - mangle.toplevel: true for maximum size reduction - legalComments: 'none' to strip license comments - minifyInternalExports: true Bundle size reduced from 10.32 MB (esbuild) to 6.0 MB (42% reduction).
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughThe pull request replaces esbuild with Rolldown as the bundler for the website server. The bundler dependency is updated in package.json, and the bundling script is reimplemented to use Rolldown with equivalent configuration parameters for tree-shaking, minification, and output formatting. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @yamadashy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request refactors the website server's bundling process by migrating from Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request refactors the bundling process by replacing esbuild with Rolldown. The changes are well-contained and the new bundling script implements aggressive optimization and minification as intended. My review focuses on the implications of this change. I've suggested pinning the rolldown dependency since it's a beta version to ensure build stability. I've also added comments regarding the new rolldown configuration: one about the missing target option (which was present in the esbuild config) that could affect runtime compatibility, and another about the aggressive moduleSideEffects setting for tree-shaking which could have unintended consequences. Overall, this is a good exploratory change, and my comments are intended to highlight important considerations for using Rolldown in production.
| const build = await rolldown({ | ||
| input: join(rootDir, 'dist/index.js'), | ||
| platform: 'node', | ||
| target: 'node24', | ||
| format: 'esm', | ||
| outfile: join(distBundledDir, 'server.mjs'), | ||
| external: ['tinypool', 'tiktoken'], | ||
| banner: { js: banner }, | ||
| // Aggressive tree-shaking | ||
| treeshake: { | ||
| moduleSideEffects: false, | ||
| annotations: true, | ||
| }, | ||
| }); | ||
|
|
||
| await build.write({ | ||
| dir: distBundledDir, | ||
| format: 'esm', | ||
| entryFileNames: 'server.mjs', | ||
| inlineDynamicImports: true, | ||
| banner, | ||
| // Minification & optimization | ||
| minify: { | ||
| compress: { | ||
| dropConsole: true, | ||
| dropDebugger: true, | ||
| unused: true, | ||
| }, | ||
| mangle: { | ||
| toplevel: true, | ||
| }, | ||
| }, | ||
| legalComments: 'none', | ||
| minifyInternalExports: true, | ||
| sourcemap: false, | ||
| }); |
There was a problem hiding this comment.
The previous esbuild configuration included target: 'node24', which ensures the bundled code is compatible with Node.js v24 by transpiling newer JavaScript syntax. The new rolldown configuration doesn't have an equivalent target option.
This means that if your source code or its dependencies use JavaScript features newer than what's supported by your target Node.js environment, the bundle might fail at runtime. While tsc handles transpilation for your own code, it might not for dependencies.
Since this PR is for comparison, this might be an acceptable difference, but it's a critical point to be aware of for production builds. You might need to ensure your tsconfig.json is configured to output compatible JavaScript, and that all dependencies are also compatible.
| "@typescript/native-preview": "^7.0.0-dev.20251226.1", | ||
| "esbuild": "^0.27.2", | ||
| "rimraf": "^6.1.2", | ||
| "rolldown": "^1.0.0-beta.58", |
There was a problem hiding this comment.
Using a caret ^ with a beta version like ^1.0.0-beta.58 can be risky. Beta versions often introduce breaking changes without a major version bump. It's safer to pin the exact version to ensure reproducible builds and avoid unexpected issues. This is especially important for a bundler, which is a critical part of your build process.
| "rolldown": "^1.0.0-beta.58", | |
| "rolldown": "1.0.0-beta.58", |
| treeshake: { | ||
| moduleSideEffects: false, | ||
| annotations: true, | ||
| }, |
There was a problem hiding this comment.
Setting moduleSideEffects: false is a very aggressive tree-shaking strategy. It assumes that no modules in your dependency graph have side effects, which can be unsafe. If any dependency relies on module-level code execution for initialization (e.g., polyfills, global setup), it might be incorrectly removed, leading to runtime errors.
Consider using a more granular approach, like 'no-external', or providing an array of modules that are known to have side effects if you encounter issues. For a library bundle, 'no-external' is often a safer default. For an application, you need to be sure about your dependencies.
Align Rolldown minification settings with esbuild for fair comparison: - Use simple `minify: true` instead of complex options - Use `legalComments: 'inline'` (Rolldown doesn't support 'eof') - Keep aggressive tree-shaking as Rolldown's strength Bundle size comparison: - esbuild + minify: 5.14 MB - Rolldown + minify: 6.0 MB
Deploying repomix with
|
| Latest commit: |
ae99656
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://0ed65daa.repomix.pages.dev |
| Branch Preview URL: | https://feat-website-rolldown-bundle.repomix.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
website/server/package.json (1)
29-29: Rolldown is beta; consider pinning version for consistency.The beta version
1.0.0-beta.58exists and resolves correctly. However, the caret range (^) allows automatic updates to future beta releases (e.g., beta.59, beta.60), which may introduce breaking changes.For a devDependency (build tool), consider pinning to the exact version to prevent unexpected updates during development.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
website/server/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (2)
website/server/package.jsonwebsite/server/scripts/bundle.mjs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (7)
website/server/scripts/bundle.mjs (7)
13-13: LGTM!The import statement correctly references the Rolldown package.
29-42: LGTM!The function rename is appropriate, and the ESM banner for CommonJS compatibility is correctly preserved.
114-114: LGTM!The function call correctly references the new Rolldown bundler function.
44-75: Remove verification request — the actual code does not match the review snippet.The code snippet in the review shows a nested
minifyobject withcompressandmanglefields. However, the actual code in website/server/scripts/bundle.mjs (lines 44-75) usesminify: true(a boolean) andlegalComments: 'inline'instead. While Rolldown 1.0.0-beta.58 does support the nested structure described in the review, that configuration is not present in the codebase.Likely an incorrect or invalid review comment.
62-67: The code snippet referenced in this review comment does not exist in the file. The actualbundle.mjsusesminify: true(a boolean) with Rolldown, not an object withcompress: { dropConsole: true, ... }. Rolldown does not support the detailed minification configuration (dropConsole, dropDebugger, etc.) that this comment addresses.The concern about console.log removal is not applicable here since there is no
dropConsolesetting configured in this build script.Likely an incorrect or invalid review comment.
68-70: The code referenced in this review comment does not exist in the current state of bundle.mjs. Lines 68-70 contain a console.log statement and function documentation, not a mangle configuration. A search of the entire codebase confirms that nomangle: { toplevel: true }configuration exists. The bundler configuration in bundle.mjs uses Rolldown'sminify: truewithout any mangle settings.Likely an incorrect or invalid review comment.
48-52: Tree-shaking configuration is safe for this codebase.
moduleSideEffects: falseis appropriate here because:
- Hono middleware (compress, timeout, cors) are function imports explicitly called via
app.use(), not import-time side-effect registration- Dependencies like
honoand@hono/node-serverdo not declare"sideEffects": falsein their package.json, so Rolldown respects their own side-effect requirements- No decorator patterns, global polyfills, or import-time initialization in the source code
The configuration is not aggressive in an unsafe way; it aligns with how Hono and its middleware are actually used.
Likely an incorrect or invalid review comment.
Summary
Detailed Bundle Size Comparison
Overall Results
Tree Shaking Comparison (No Minify)
Winner: Rolldown (6.5% smaller, 0.67 MB difference)
Rolldown's aggressive
treeshake: { moduleSideEffects: false }removes more unused code.Minification Comparison
Winner: esbuild (13.1% smaller, 0.78 MB difference)
esbuild's minifier (5+ years mature) produces significantly better compression than Rolldown's oxc-based minifier.
Technical Analysis
Why Rolldown has better tree-shaking
moduleSideEffects: falseaggressively marks modules as side-effect-freeWhy esbuild has better minification
Conclusion
For Cloud Run cold start optimization, final bundle size matters most. Despite Rolldown's superior tree-shaking, esbuild's mature minifier wins overall.
The esbuild + minify approach was adopted in PR #1069.
Checklist
npm run testnpm run lint