@@ -8,185 +8,145 @@ import staticData from './data.mjs';
88 * Asynchronously bundles JavaScript source code (and its CSS imports),
99 * targeting either browser (client) or server (Node.js) environments.
1010 *
11- * @param {Map<string, string> | string } codeOrMap - Map of {fileName: code} or single code string for server builds.
12- * @param {{ server: boolean } } options - Build configuration object.
11+ * @param {Map<string, string> } codeMap - Map of {fileName: code} for all builds.
12+ * @param {Object } [options] - Build configuration object.
13+ * @param {boolean } [options.server=false] - Whether this is a server-side build.
1314 */
14- export default async function bundleCode ( codeOrMap , { server = false } = { } ) {
15+ export default async function bundleCode ( codeMap , { server = false } = { } ) {
1516 // Store the import map HTML for later extraction
1617 let importMapHtml = '' ;
1718
18- // Convert input to Map format
19- const codeMap =
20- codeOrMap instanceof Map
21- ? codeOrMap
22- : new Map ( [ [ 'entrypoint.jsx' , codeOrMap ] ] ) ;
23-
2419 /** @type {import('rolldown').OutputOptions } */
2520 const serverOutputConfig = {
21+ // Inline all dynamic imports to create a single self-contained bundle
2622 inlineDynamicImports : true ,
2723 } ;
2824
2925 /** @type {import('rolldown').InputOptions['experimental'] } */
3026 const clientExperimentalConfig = {
27+ // Generate an import map for cache-busted module resolution in browsers
28+ // https://rolldown.rs/options/experimental#chunkimportmap
3129 chunkImportMap : ! server && {
3230 baseUrl : './' ,
3331 fileName : 'importmap.json' ,
3432 } ,
3533 } ;
3634
3735 const result = await build ( {
38- // Define the entry point module names — these are virtual (not real files).
39- // The virtual plugin will provide the actual code string under these names.
36+ // Entry points: array of virtual module names that the virtual plugin provides
4037 input : Array . from ( codeMap . keys ( ) ) ,
4138
42- // Enable experimental chunk import map for cache-busted module resolution
43- // https://rolldown.rs/options/experimental#chunkimportmap
44- // Also enable incremental builds for faster rebuilds (similar to Rollup's cache)
45- // https://rolldown.rs/options/experimental#incrementalbuild
39+ // Experimental features: import maps for client, none for server
4640 experimental : server ? { } : clientExperimentalConfig ,
4741
48- // Configuration for the output bundle
42+ // Output configuration
4943 output : {
50- // Output module format:
51- // - "cjs" for CommonJS (used in Node.js environments)
52- // - "esm" for browser with dynamic imports (allows code splitting)
44+ // CommonJS for Node.js server, ESM for browser with code splitting support
5345 format : server ? 'cjs' : 'esm' ,
5446
55- // Minify output only for browser builds to optimize file size.
56- // Server builds are usually not minified to preserve stack traces and debuggability.
47+ // Minify only browser builds to reduce file size
5748 minify : ! server ,
5849
59- // Enable code splitting for client builds to allow dynamic imports
60- // For server builds, inline everything into a single bundle
50+ // Environment-specific output configuration
6151 ...( server ? serverOutputConfig : { } ) ,
6252 } ,
6353
64- // Platform informs Rolldown of the environment-specific code behavior:
65- // - 'node' enables things like `require`, and skips polyfills.
66- // - 'browser' enables inlining of polyfills and uses native browser features.
54+ // Target platform affects polyfills, globals, and bundling behavior
6755 platform : server ? 'node' : 'browser' ,
6856
69- // External dependencies to exclude from bundling.
70- // These are expected to be available at runtime in the server environment.
71- // This reduces bundle size and avoids bundling shared server libs.
57+ // External dependencies (not bundled) for server builds
58+ // These must be available in the Node.js runtime environment
7259 external : server
7360 ? [ 'preact' , 'preact-render-to-string' , '@node-core/ui-components' ]
7461 : [ ] ,
7562
76- // Transform configuration
63+ // Transform and define configuration
7764 transform : {
78- // Inject global compile-time constants that will be replaced in code.
79- // These are useful for tree-shaking and conditional branching.
80- // Be sure to update type declarations (`types.d.ts`) if these change.
65+ // Compile-time constants replaced during bundling
66+ // Update types.d.ts if these change
8167 define : {
82- // Static data injected directly into the bundle ( as a literal or serialized JSON).
68+ // Static data as a JSON literal
8369 __STATIC_DATA__ : staticData ,
8470
85- // Boolean flags used for conditional logic in source code:
86- // Example: `if (SERVER) {...}` or `if (CLIENT) {...}`
87- // These flags help split logic for server/client environments.
88- // Unused branches will be removed via tree-shaking.
71+ // Environment flags for conditional logic and tree-shaking
8972 SERVER : String ( server ) ,
9073 CLIENT : String ( ! server ) ,
9174 } ,
9275
93- // JSX transformation configuration.
94- // `'react-jsx'` enables the automatic JSX runtime, which doesn't require `import React`.
95- // Since we're using Preact via aliasing, this setting works well with `preact/compat`.
76+ // Use automatic JSX runtime (no need to import React/Preact)
9677 jsx : 'react-jsx' ,
9778 } ,
9879
99- // Module resolution aliases.
100- // This tells the bundler to use `preact/compat` wherever `react` or `react-dom` is imported.
101- // Allows you to write React-style code but ship much smaller Preact bundles.
80+ // Module resolution: alias React imports to Preact
10281 resolve : {
10382 alias : {
10483 react : 'preact/compat' ,
10584 'react-dom' : 'preact/compat' ,
10685 } ,
10786 } ,
10887
109- // Array of plugins to apply during the build.
88+ // Build plugins
11089 plugins : [
111- // The virtual plugin lets us define virtual files
112- // with the contents provided by the `codeMap` argument.
113- // These become the root modules for the bundler.
90+ // Virtual plugin: provides in-memory modules from codeMap
11491 virtual ( Object . fromEntries ( codeMap ) ) ,
11592
116- // Load CSS imports via the custom plugin.
117- // This plugin will collect imported CSS files and return them as `source` chunks.
93+ // CSS loader: collects and bundles imported CSS files
11894 cssLoader ( ) ,
11995
120- // Extract import map from Rolldown's chunkImportMap output
121- // https://rolldown.rs/options/experimental#chunkimportmap
96+ // Extract and transform the import map generated by Rolldown
12297 {
12398 name : 'extract-import-map' ,
12499 /**
125- * Extract import map from bundle
126- * @param {* } _ - Options (unused)
127- * @param {* } bundle - Bundle object
100+ * Extracts import map from bundle and converts to HTML script tag.
101+ *
102+ * @param {import('rolldown').NormalizedOutputOptions } _ - Output options (unused).
103+ * @param {import('rolldown').OutputBundle } bundle - Bundle object containing all output chunks.
128104 */
129105 generateBundle ( _ , bundle ) {
130106 const chunkImportMap = bundle [ 'importmap.json' ] ;
131107
132108 if ( chunkImportMap ?. type === 'asset' ) {
133- // Parse the import map and filter out virtual entries
134- const importMapData = JSON . parse ( chunkImportMap . source ) ;
135-
136- // Remove any references to _virtual_ or virtual entrypoint files
137- if ( importMapData . imports ) {
138- for ( const key in importMapData . imports ) {
139- if ( key . includes ( '_virtual_' ) || key . includes ( 'entrypoint' ) ) {
140- delete importMapData . imports [ key ] ;
141- }
142- }
143- }
144-
145- // Extract the import map and convert to HTML script tag
146- importMapHtml = `<script type="importmap">${ JSON . stringify ( importMapData ) } </script>` ;
147-
148- // Remove from bundle so it's not written as a separate file
109+ // Convert to HTML script tag for inline inclusion
110+ importMapHtml = `<script type="importmap">${ chunkImportMap . source } </script>` ;
111+
112+ // Remove from bundle to prevent writing as separate file
149113 delete bundle [ 'importmap.json' ] ;
150114 }
151115 } ,
152116 } ,
153117 ] ,
154118
155- // Enable tree-shaking to eliminate unused imports, functions, and branches.
156- // This works best when all dependencies are marked as having no side effects.
157- // `sideEffects: false` in the package.json confirms this is safe to do.
119+ // Enable tree-shaking to remove unused code
158120 treeshake : true ,
159121
160- // Disable writing output to disk.
161- // Instead, the compiled chunks are returned in memory (ideal for dev tools or sandboxing).
122+ // Return chunks in memory instead of writing to disk
162123 write : false ,
163124 } ) ;
164125
165- // Destructure the result to get the output chunks.
166- // Separate entry chunks from other chunks (CSS and code-split JS)
126+ // Separate entry chunks (main modules) from other chunks (CSS, code-split JS)
167127 const entryChunks = [ ] ;
168128 const otherChunks = [ ] ;
169129
170- // Separate the entrypoints from remaining JavaScript files
171130 for ( const chunk of result . output ) {
172131 const chunkTarget =
173132 chunk . type === 'chunk' && chunk . isEntry ? entryChunks : otherChunks ;
174133
175- chunkTarget [ ' push' ] ( chunk ) ;
134+ chunkTarget . push ( chunk ) ;
176135 }
177136
178- // Separate CSS files from JS chunks
137+ // Separate CSS assets from JavaScript chunks
179138 const cssFiles = otherChunks . filter ( chunk => chunk . type === 'asset' ) ;
180139 const jsChunks = otherChunks . filter ( chunk => chunk . type === 'chunk' ) ;
181140
182- // For client builds, create a map of entry code by original fileName
141+ // Create a map of entry code by original fileName
183142 const jsMap = { } ;
184143
185144 for ( const chunk of entryChunks ) {
186- // Map back to original fileName from facadeModuleId
145+ // Extract original fileName from virtual module ID
187146 const originalFileName =
188147 chunk . facadeModuleId ?. split ( '/' ) . pop ( ) || chunk . fileName ;
189148
149+ // Remove virtual: prefix from module IDs
190150 jsMap [ originalFileName . replace ( '\x00virtual:' , '' ) ] = chunk . code ;
191151 }
192152
0 commit comments