UNPKG

6.76 kBJavaScriptView Raw
1import {
2 operatingSystemPathToPathname,
3 pathnameToOperatingSystemPath,
4} from "@jsenv/operating-system-path"
5import { generateGroupMap } from "@jsenv/grouping"
6import {
7 catchAsyncFunctionCancellation,
8 createProcessInterruptionCancellationToken,
9} from "@dmail/cancellation"
10import { LOG_LEVEL_ERRORS_WARNINGS_AND_LOGS } from "./logger.js"
11import { bundleWithoutBalancing } from "./bundle-without-balancing.js"
12import { bundleWithBalancing } from "./bundle-with-balancing.js"
13import { bundleBalancer } from "./bundle-balancer.js"
14import { removeFolder } from "./removeFolder.js"
15import {
16 DEFAULT_IMPORT_MAP_RELATIVE_PATH,
17 DEFAULT_ENTRY_POINT_MAP,
18 DEFAULT_NATIVE_MODULE_PREDICATE,
19 DEFAULT_BABEL_PLUGIN_MAP,
20 DEFAULT_PLATFORM_SCORE_MAP,
21} from "./generate-bundle-constant.js"
22
23export const generateBundle = ({
24 projectPath,
25 bundleIntoRelativePath,
26 cleanBundleInto = false,
27 importMapRelativePath = DEFAULT_IMPORT_MAP_RELATIVE_PATH,
28 importDefaultExtension,
29 importMapForBundle,
30 specifierMap,
31 specifierDynamicMap,
32 nativeModulePredicate = DEFAULT_NATIVE_MODULE_PREDICATE,
33 entryPointMap = DEFAULT_ENTRY_POINT_MAP,
34 babelPluginMap = DEFAULT_BABEL_PLUGIN_MAP,
35 convertMap,
36 logLevel = LOG_LEVEL_ERRORS_WARNINGS_AND_LOGS,
37 minify = false,
38 writeOnFileSystem = true,
39 throwUnhandled = true,
40 format,
41 formatOutputOptions = {},
42 // balancing
43 compileGroupCount = 1,
44 platformAlwaysInsidePlatformScoreMap,
45 balancerTemplateRelativePath,
46 balancerDataClientPathname,
47 platformScoreMap = DEFAULT_PLATFORM_SCORE_MAP,
48}) => {
49 const promise = catchAsyncFunctionCancellation(async () => {
50 if (typeof projectPath !== "string")
51 throw new TypeError(`projectPath must be a string, got ${projectPath}`)
52 if (typeof bundleIntoRelativePath !== "string")
53 throw new TypeError(`bundleIntoRelativePath must be a string, got ${bundleIntoRelativePath}`)
54 if (typeof entryPointMap !== "object")
55 throw new TypeError(`entryPointMap must be an object, got ${entryPointMap}`)
56 if (typeof compileGroupCount !== "number")
57 throw new TypeError(`compileGroupCount must be a number, got ${compileGroupCount}`)
58 if (compileGroupCount < 1)
59 throw new Error(`compileGroupCount must be >= 1, got ${compileGroupCount}`)
60
61 const cancellationToken = createProcessInterruptionCancellationToken()
62 const projectPathname = operatingSystemPathToPathname(projectPath)
63
64 if (cleanBundleInto)
65 await removeFolder(
66 pathnameToOperatingSystemPath(`${projectPathname}${bundleIntoRelativePath}`),
67 )
68
69 if (compileGroupCount === 1) {
70 return bundleWithoutBalancing({
71 cancellationToken,
72 projectPathname,
73 bundleIntoRelativePath,
74 importDefaultExtension,
75 importMapRelativePath,
76 importMapForBundle,
77 specifierMap,
78 specifierDynamicMap,
79 nativeModulePredicate,
80 entryPointMap,
81 babelPluginMap,
82 convertMap,
83 minify,
84 logLevel,
85 format,
86 formatOutputOptions,
87 writeOnFileSystem,
88 })
89 }
90
91 if (!balancerTemplateRelativePath) {
92 throw createFormatIncompatibleWithBalancingError({ format })
93 }
94
95 const groupMap = generateGroupMap({
96 babelPluginMap,
97 platformScoreMap,
98 groupCount: compileGroupCount,
99 platformAlwaysInsidePlatformScoreMap,
100 })
101
102 return await Promise.all([
103 generateEntryPointsFolders({
104 cancellationToken,
105 projectPathname,
106 bundleIntoRelativePath,
107 importDefaultExtension,
108 importMapRelativePath,
109 importMapForBundle,
110 specifierMap,
111 specifierDynamicMap,
112 nativeModulePredicate,
113 entryPointMap,
114 babelPluginMap,
115 convertMap,
116 minify,
117 logLevel,
118 writeOnFileSystem,
119 format,
120 formatOutputOptions,
121 groupMap,
122 }),
123 generateEntryPointsBalancerFiles({
124 cancellationToken,
125 projectPathname,
126 bundleIntoRelativePath,
127 importDefaultExtension,
128 importMapRelativePath,
129 importMapForBundle,
130 specifierMap,
131 specifierDynamicMap,
132 nativeModulePredicate,
133 entryPointMap,
134 babelPluginMap,
135 convertMap,
136 minify,
137 logLevel,
138 writeOnFileSystem,
139 format,
140 balancerTemplateRelativePath,
141 balancerDataClientPathname,
142 groupMap,
143 }),
144 ])
145 })
146
147 if (!throwUnhandled) return promise
148 return promise.catch((e) => {
149 setTimeout(() => {
150 throw e
151 })
152 })
153}
154
155const generateEntryPointsFolders = async ({
156 cancellationToken,
157 projectPathname,
158 bundleIntoRelativePath,
159 importDefaultExtension,
160 importMapRelativePath,
161 importMapForBundle,
162 specifierMap,
163 specifierDynamicMap,
164 nativeModulePredicate,
165 entryPointMap,
166 babelPluginMap,
167 convertMap,
168 minify,
169 logLevel,
170 writeOnFileSystem,
171 format,
172 formatOutputOptions,
173 groupMap,
174}) =>
175 Promise.all(
176 Object.keys(groupMap).map(async (compileId) =>
177 bundleWithBalancing({
178 cancellationToken,
179 projectPathname,
180 bundleIntoRelativePath,
181 importDefaultExtension,
182 importMapRelativePath,
183 importMapForBundle,
184 specifierMap,
185 specifierDynamicMap,
186 nativeModulePredicate,
187 entryPointMap,
188 babelPluginMap,
189 convertMap,
190 minify,
191 logLevel,
192 format,
193 formatOutputOptions,
194 groupMap,
195 compileId,
196 writeOnFileSystem,
197 }),
198 ),
199 )
200
201const generateEntryPointsBalancerFiles = ({
202 cancellationToken,
203 projectPathname,
204 bundleIntoRelativePath,
205 importDefaultExtension,
206 importMapRelativePath,
207 importMapForBundle,
208 specifierMap,
209 specifierDynamicMap,
210 nativeModulePredicate,
211 entryPointMap,
212 babelPluginMap,
213 convertMap,
214 minify,
215 logLevel,
216 writeOnFileSystem,
217 format,
218 balancerTemplateRelativePath,
219 balancerDataClientPathname,
220 groupMap,
221}) =>
222 Promise.all(
223 Object.keys(entryPointMap).map(async (entryPointName) =>
224 bundleBalancer({
225 cancellationToken,
226 projectPathname,
227 bundleIntoRelativePath,
228 importDefaultExtension,
229 importMapRelativePath,
230 importMapForBundle,
231 specifierMap,
232 specifierDynamicMap,
233 nativeModulePredicate,
234 entryPointMap: {
235 [entryPointName]: balancerTemplateRelativePath,
236 },
237 babelPluginMap,
238 convertMap,
239 minify,
240 logLevel,
241 format,
242 balancerDataClientPathname,
243 groupMap,
244 writeOnFileSystem,
245 }),
246 ),
247 )
248
249const createFormatIncompatibleWithBalancingError = ({ format }) =>
250 new Error(`format not compatible with balancing.
251format: ${format}`)