gofront 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/vendor.js CHANGED
@@ -59,12 +59,13 @@ ${exports.join(",\n")}
59
59
  }
60
60
 
61
61
  export function findBundler(projectDir) {
62
- const pkgPath = join(projectDir, "package.json");
62
+ const root = resolve(projectDir);
63
+ const pkgPath = join(root, "package.json");
63
64
  let req;
64
65
  if (existsSync(pkgPath)) {
65
66
  req = createRequire(pkgPath);
66
67
  } else {
67
- req = createRequire(join(projectDir, "dummy.js"));
68
+ req = createRequire(join(root, "dummy.js"));
68
69
  }
69
70
 
70
71
  try {
@@ -162,47 +163,135 @@ export function resolveDestinationPaths(projectRoot, dest) {
162
163
  });
163
164
  }
164
165
 
165
- async function runBundler(
166
+ export const NODE_BUILTINS = [
167
+ "buffer",
168
+ "events",
169
+ "path",
170
+ "util",
171
+ "process",
172
+ "stream",
173
+ "crypto",
174
+ "fs",
175
+ "os",
176
+ "http",
177
+ "https",
178
+ "net",
179
+ "tls",
180
+ "zlib",
181
+ "url",
182
+ "assert",
183
+ "child_process",
184
+ ];
185
+
186
+ export const NODE_POLYFILLS_TIP =
187
+ "gofront: tip: npm package requires Node built-ins. Install @rolldown/plugin-node-polyfills:\n npm install --save-dev @rolldown/plugin-node-polyfills";
188
+
189
+ export function isNodeBuiltinError(errorMsg) {
190
+ if (typeof errorMsg !== "string") return false;
191
+ const lower = errorMsg.toLowerCase();
192
+ return NODE_BUILTINS.some(
193
+ (mod) =>
194
+ lower.includes(`"${mod}"`) ||
195
+ lower.includes(`'${mod}'`) ||
196
+ lower.includes(`node:${mod}`) ||
197
+ lower.includes(`module '${mod}'`) ||
198
+ lower.includes(`resolve "${mod}"`) ||
199
+ lower.includes(`resolve '${mod}'`),
200
+ );
201
+ }
202
+
203
+ export function findNodePolyfills(projectDir) {
204
+ const root = resolve(projectDir);
205
+ const pkgPath = join(root, "package.json");
206
+ let req;
207
+ if (existsSync(pkgPath)) {
208
+ req = createRequire(pkgPath);
209
+ } else {
210
+ req = createRequire(join(root, "dummy.js"));
211
+ }
212
+
213
+ try {
214
+ const path = req.resolve("@rolldown/plugin-node-polyfills");
215
+ return { name: "node-polyfills", path };
216
+ } catch {}
217
+
218
+ return null;
219
+ }
220
+
221
+ export async function loadNodePolyfillsPlugin(projectRoot, customPlugin) {
222
+ if (customPlugin !== undefined) {
223
+ if (customPlugin === null) return null;
224
+ return typeof customPlugin === "function" ? customPlugin() : customPlugin;
225
+ }
226
+ const info = findNodePolyfills(projectRoot);
227
+ if (!info) return null;
228
+ try {
229
+ const mod = await import(pathToFileURL(info.path).href);
230
+ const fn =
231
+ mod.nodePolyfills || mod.default?.nodePolyfills || mod.default || mod;
232
+ return typeof fn === "function" ? fn() : mod;
233
+ } catch {
234
+ return null;
235
+ }
236
+ }
237
+
238
+ async function bundleWithRolldown(
239
+ bundlerInfo,
240
+ { projectRoot, entryFile, destPath, minify, nodePolyfillsPlugin },
241
+ ) {
242
+ const rolldownModule =
243
+ bundlerInfo.instance ??
244
+ (await import(pathToFileURL(bundlerInfo.path).href));
245
+ const rolldownFn =
246
+ rolldownModule.rolldown ||
247
+ rolldownModule.default?.rolldown ||
248
+ rolldownModule.default;
249
+
250
+ const plugins = [];
251
+ if (nodePolyfillsPlugin) {
252
+ plugins.push(nodePolyfillsPlugin);
253
+ }
254
+
255
+ const bundle = await rolldownFn({
256
+ input: entryFile,
257
+ cwd: projectRoot,
258
+ plugins,
259
+ });
260
+ await bundle.write({
261
+ file: destPath,
262
+ format: "esm",
263
+ minify: Boolean(minify),
264
+ });
265
+ await bundle.close();
266
+ }
267
+
268
+ async function bundleWithEsbuild(
166
269
  bundlerInfo,
167
270
  { projectRoot, entryFile, destPath, minify },
168
271
  ) {
272
+ const esbuildModule =
273
+ bundlerInfo.instance ??
274
+ (await import(pathToFileURL(bundlerInfo.path).href));
275
+ const buildFn =
276
+ esbuildModule.build || esbuildModule.default?.build || esbuildModule;
277
+
278
+ await buildFn({
279
+ entryPoints: [entryFile],
280
+ bundle: true,
281
+ format: "esm",
282
+ outfile: destPath,
283
+ absWorkingDir: projectRoot,
284
+ minify: Boolean(minify),
285
+ });
286
+ }
287
+
288
+ async function runBundler(bundlerInfo, options) {
169
289
  if (bundlerInfo.name === "rolldown") {
170
- const rolldownModule =
171
- bundlerInfo.instance ??
172
- (await import(pathToFileURL(bundlerInfo.path).href));
173
- const rolldownFn =
174
- rolldownModule.rolldown ||
175
- rolldownModule.default?.rolldown ||
176
- rolldownModule.default;
177
-
178
- const bundle = await rolldownFn({
179
- input: entryFile,
180
- cwd: projectRoot,
181
- });
182
- await bundle.write({
183
- file: destPath,
184
- format: "esm",
185
- minify: Boolean(minify),
186
- });
187
- await bundle.close();
290
+ await bundleWithRolldown(bundlerInfo, options);
188
291
  return;
189
292
  }
190
-
191
293
  if (bundlerInfo.name === "esbuild") {
192
- const esbuildModule =
193
- bundlerInfo.instance ??
194
- (await import(pathToFileURL(bundlerInfo.path).href));
195
- const buildFn =
196
- esbuildModule.build || esbuildModule.default?.build || esbuildModule;
197
-
198
- await buildFn({
199
- entryPoints: [entryFile],
200
- bundle: true,
201
- format: "esm",
202
- outfile: destPath,
203
- absWorkingDir: projectRoot,
204
- minify: Boolean(minify),
205
- });
294
+ await bundleWithEsbuild(bundlerInfo, options);
206
295
  }
207
296
  }
208
297
 
@@ -227,8 +316,9 @@ export async function bundleVendor(projectDir = ".", options = {}) {
227
316
 
228
317
  const destPaths = resolveDestinationPaths(projectRoot, dest);
229
318
  const bundlerInfo = options.bundler ?? findBundler(projectRoot);
319
+ const warn = options.logger?.warn ?? console.warn;
230
320
  if (!bundlerInfo) {
231
- console.warn(
321
+ warn(
232
322
  "gofront: no bundler found (rolldown or esbuild). Run 'npm install --save-dev rolldown' to enable vendor bundling.",
233
323
  );
234
324
  return {
@@ -245,18 +335,36 @@ export async function bundleVendor(projectDir = ".", options = {}) {
245
335
  mkdirSync(dirname(p), { recursive: true });
246
336
  }
247
337
 
338
+ const customPlugin =
339
+ options.nodePolyfillsPlugin ??
340
+ bundlerInfo.nodePolyfillsPlugin ??
341
+ (options.nodePolyfills === false ? null : undefined);
342
+ const polyfillPlugin = await loadNodePolyfillsPlugin(
343
+ projectRoot,
344
+ customPlugin,
345
+ );
346
+
248
347
  if (typeof bundlerInfo.bundle === "function") {
249
- await bundlerInfo.bundle({
250
- projectRoot,
251
- packages,
252
- dest: destPaths.length === 1 ? destPaths[0] : destPaths,
253
- minify: Boolean(minify),
254
- });
348
+ try {
349
+ await bundlerInfo.bundle({
350
+ projectRoot,
351
+ packages,
352
+ dest: destPaths.length === 1 ? destPaths[0] : destPaths,
353
+ minify: Boolean(minify),
354
+ nodePolyfillsPlugin: polyfillPlugin,
355
+ });
356
+ } catch (err) {
357
+ if (!polyfillPlugin && isNodeBuiltinError(err.message)) {
358
+ warn(NODE_POLYFILLS_TIP);
359
+ }
360
+ throw err;
361
+ }
255
362
  return {
256
363
  bundled: packages,
257
364
  bundler: bundlerInfo.name ?? "custom",
258
365
  dest,
259
366
  minify: Boolean(minify),
367
+ nodePolyfills: Boolean(polyfillPlugin),
260
368
  };
261
369
  }
262
370
 
@@ -273,11 +381,17 @@ export async function bundleVendor(projectDir = ".", options = {}) {
273
381
  entryFile,
274
382
  destPath: destPaths[0],
275
383
  minify,
384
+ nodePolyfillsPlugin: polyfillPlugin,
276
385
  });
277
386
 
278
387
  for (let i = 1; i < destPaths.length; i++) {
279
388
  copyFileSync(destPaths[0], destPaths[i]);
280
389
  }
390
+ } catch (err) {
391
+ if (!polyfillPlugin && isNodeBuiltinError(err.message)) {
392
+ warn(NODE_POLYFILLS_TIP);
393
+ }
394
+ throw err;
281
395
  } finally {
282
396
  if (existsSync(entryFile)) {
283
397
  rmSync(entryFile, { force: true });
@@ -289,5 +403,6 @@ export async function bundleVendor(projectDir = ".", options = {}) {
289
403
  bundler: bundlerInfo.name,
290
404
  dest,
291
405
  minify: Boolean(minify),
406
+ nodePolyfills: Boolean(polyfillPlugin),
292
407
  };
293
408
  }