-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathbundle.mjs
More file actions
119 lines (100 loc) · 4.33 KB
/
bundle.mjs
File metadata and controls
119 lines (100 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import virtual from '@rollup/plugin-virtual';
import { build } from 'rolldown';
import cssLoader from './css.mjs';
import staticData from './data.mjs';
/**
* Asynchronously bundles JavaScript source code (and its CSS imports),
* targeting either browser (client) or server (Node.js) environments.
*
* @param {Map<string, string>} codeMap - Map of {fileName: code} for all builds.
* @param {Object} [options] - Build configuration object.
* @param {boolean} [options.server=false] - Whether this is a server-side build.
*/
export default async function bundleCode(codeMap, { server = false } = {}) {
const result = await build({
// Entry points: array of virtual module names that the virtual plugin provides
input: Array.from(codeMap.keys()),
// Experimental features: import maps for client, none for server
experimental: {
chunkImportMap: !server,
},
// Output configuration
output: {
// Output module format:
// - "cjs" for CommonJS (used in Node.js environments)
// - "esm" for browser environments (Using Chunk Code-Splitting)
format: server ? 'cjs' : 'esm',
// Minify output only for browser builds to optimize file size.
// Server builds are usually not minified to preserve stack traces and debuggability.
minify: !server,
// Within server builds we want to ensure dynamic imports get inlined whenever possible.
inlineDynamicImports: server,
},
// Platform informs Rolldown of the environment-specific code behavior:
// - 'node' enables things like `require`, and skips polyfills.
// - 'browser' enables inlining of polyfills and uses native browser features.
platform: server ? 'node' : 'browser',
// External dependencies to exclude from bundling.
// These are expected to be available at runtime in the server environment.
// This reduces bundle size and avoids bundling shared server libs.
external: server
? ['preact', 'preact-render-to-string', '@node-core/ui-components']
: [],
transform: {
// Inject global compile-time constants that will be replaced in code.
// These are useful for tree-shaking and conditional branching.
// Be sure to update type declarations (`types.d.ts`) if these change.
define: {
// Static data injected directly into the bundle (as a literal or serialized JSON).
__STATIC_DATA__: staticData,
// Boolean flags used for conditional logic in source code:
// Example: `if (SERVER) {...}` or `if (CLIENT) {...}`
// These flags help split logic for server/client environments.
// Unused branches will be removed via tree-shaking.
SERVER: String(server),
CLIENT: String(!server),
},
// JSX transformation configuration.
// `'react-jsx'` enables the automatic JSX runtime, which doesn't require `import React`.
// Since we're using Preact via aliasing, this setting works well with `preact/compat`.
jsx: 'react-jsx',
},
// Module resolution aliases.
// This tells the bundler to use `preact/compat` wherever `react` or `react-dom` is imported.
// Allows you to write React-style code but ship much smaller Preact bundles.
resolve: {
alias: {
react: 'preact/compat',
'react-dom': 'preact/compat',
},
},
// Array of plugins to apply during the build.
plugins: [
// Virtual plugin: provides in-memory modules from codeMap
virtual(Object.fromEntries(codeMap)),
// Load CSS imports via the custom plugin.
// This plugin will collect imported CSS files and return them as `source` chunks.
cssLoader(),
],
// Enable tree-shaking to remove unused code
treeshake: true,
// Return chunks in memory instead of writing to disk
write: false,
});
// Separate CSS assets from JavaScript chunks
const assets = result.output.filter(c => c.type === 'asset');
const chunks = result.output.filter(c => c.type === 'chunk');
const importMap = assets.find(c => c.fileName === 'importmap.json');
return {
css: assets
.filter(c => c.fileName.endsWith('.css'))
.map(f => f.source)
.join(''),
chunks: chunks.map(({ fileName, code, isEntry }) => ({
fileName: fileName.replace('_virtual_', ''),
isEntry,
code,
})),
importMap: importMap?.source.toString(),
};
}