@nasti-toolchain/nasti 1.3.1 → 1.3.3

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/dist/index.js CHANGED
@@ -180,7 +180,6 @@ __export(middleware_exports, {
180
180
  });
181
181
  import path8 from "path";
182
182
  import fs7 from "fs";
183
- import { createRequire as createRequire2 } from "module";
184
183
  function transformMiddleware(ctx) {
185
184
  ctx.envDefine = buildEnvDefine(
186
185
  loadEnv(ctx.config.mode, ctx.config.root, ctx.config.envPrefix),
@@ -256,6 +255,13 @@ async function transformRequest(url, ctx) {
256
255
  if (!filePath || !fs7.existsSync(filePath)) return null;
257
256
  const mod = await moduleGraph.ensureEntryFromUrl(url);
258
257
  moduleGraph.registerModule(mod, filePath);
258
+ const cleanReqUrl = url.split("?")[0];
259
+ if (cleanReqUrl.startsWith("/@modules/")) {
260
+ const code2 = await bundlePackageAsEsm(filePath);
261
+ const transformResult2 = { code: code2 };
262
+ mod.transformResult = transformResult2;
263
+ return transformResult2;
264
+ }
259
265
  let code = fs7.readFileSync(filePath, "utf-8");
260
266
  const pluginResult = await pluginContainer.transform(code, filePath);
261
267
  if (pluginResult) {
@@ -280,6 +286,67 @@ async function transformRequest(url, ctx) {
280
286
  mod.transformResult = transformResult;
281
287
  return transformResult;
282
288
  }
289
+ async function bundlePackageAsEsm(entryFile) {
290
+ if (!esmBundleCache.has(entryFile)) {
291
+ esmBundleCache.set(entryFile, doBundlePackage(entryFile));
292
+ }
293
+ return esmBundleCache.get(entryFile);
294
+ }
295
+ async function doBundlePackage(entryFile) {
296
+ const { rolldown: rolldown2 } = await import("rolldown");
297
+ const bundle = await rolldown2({
298
+ input: entryFile,
299
+ // 仅将其他 npm 包外部化;相对路径(包内部文件)全部内联打包
300
+ external: (id) => {
301
+ if (id.startsWith(".") || id.startsWith("/") || /^[A-Za-z]:\\/.test(id)) return false;
302
+ return true;
303
+ },
304
+ define: {
305
+ // CJS 包(如 react)通过 process.env.NODE_ENV 判断环境,需在打包时替换
306
+ "process.env.NODE_ENV": '"development"'
307
+ }
308
+ });
309
+ const result = await bundle.generate({ format: "esm", exports: "named" });
310
+ await bundle.close();
311
+ let code = result.output[0].code;
312
+ code = code.replace(/process\.env\.NODE_ENV/g, '"development"');
313
+ code = code.replace(
314
+ /^(import\b[^;'"]*?\bfrom\s+)(['"])([^'"./][^'"]*)(\2)/gm,
315
+ (_, prefix, q, spec) => `${prefix}${q}/@modules/${spec}${q}`
316
+ ).replace(
317
+ /^(export\b[^;'"]*?\bfrom\s+)(['"])([^'"./][^'"]*)(\2)/gm,
318
+ (_, prefix, q, spec) => `${prefix}${q}/@modules/${spec}${q}`
319
+ ).replace(
320
+ /^(import\s+)(['"])([^'"./][^'"]*)(\2)/gm,
321
+ (_, prefix, q, spec) => `${prefix}${q}/@modules/${spec}${q}`
322
+ );
323
+ if (code.includes("__commonJSMin")) {
324
+ code = await injectCjsNamedExports(code, entryFile);
325
+ }
326
+ return code;
327
+ }
328
+ async function injectCjsNamedExports(code, entryFile) {
329
+ try {
330
+ const { createRequire: createRequire2 } = await import("module");
331
+ const req = createRequire2(entryFile);
332
+ const cjsExports = req(entryFile);
333
+ if (!cjsExports || typeof cjsExports !== "object" || Array.isArray(cjsExports)) return code;
334
+ const namedKeys = Object.keys(cjsExports).filter(
335
+ (k) => k !== "__esModule" && k !== "default" && VALID_IDENT.test(k)
336
+ );
337
+ if (namedKeys.length === 0) return code;
338
+ return code.replace(
339
+ /^export default (\w+\(\));?\s*$/m,
340
+ (_, call) => [
341
+ `const __cjsMod = ${call};`,
342
+ `export default __cjsMod;`,
343
+ ...namedKeys.map((k) => `export const ${k} = __cjsMod[${JSON.stringify(k)}];`)
344
+ ].join("\n")
345
+ );
346
+ } catch {
347
+ return code;
348
+ }
349
+ }
283
350
  function rewriteImports(code, _config) {
284
351
  return code.replace(
285
352
  /\bfrom\s+(['"])([^'"./][^'"]*)\1/g,
@@ -300,16 +367,92 @@ function rewriteImports(code, _config) {
300
367
  }
301
368
  );
302
369
  }
370
+ function resolveNodeModule(root, moduleName) {
371
+ let pkgName;
372
+ let subpath;
373
+ if (moduleName.startsWith("@")) {
374
+ const parts = moduleName.split("/");
375
+ pkgName = parts.slice(0, 2).join("/");
376
+ subpath = parts.slice(2).join("/");
377
+ } else {
378
+ const slash = moduleName.indexOf("/");
379
+ pkgName = slash === -1 ? moduleName : moduleName.slice(0, slash);
380
+ subpath = slash === -1 ? "" : moduleName.slice(slash + 1);
381
+ }
382
+ let pkgDir = null;
383
+ let dir = root;
384
+ for (; ; ) {
385
+ const candidate = path8.join(dir, "node_modules", pkgName);
386
+ if (fs7.existsSync(candidate)) {
387
+ pkgDir = candidate;
388
+ break;
389
+ }
390
+ const parent = path8.dirname(dir);
391
+ if (parent === dir) break;
392
+ dir = parent;
393
+ }
394
+ if (!pkgDir) return null;
395
+ const pkgJsonPath = path8.join(pkgDir, "package.json");
396
+ if (!fs7.existsSync(pkgJsonPath)) return null;
397
+ let pkg;
398
+ try {
399
+ pkg = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf-8"));
400
+ } catch {
401
+ return null;
402
+ }
403
+ if (pkg.exports) {
404
+ const exportKey = subpath ? `./${subpath}` : ".";
405
+ const resolved = resolvePackageExports(pkg.exports, exportKey, pkgDir);
406
+ if (resolved) return resolved;
407
+ }
408
+ if (subpath) {
409
+ const direct = path8.join(pkgDir, subpath);
410
+ if (fs7.existsSync(direct) && fs7.statSync(direct).isFile()) return direct;
411
+ for (const ext of RESOLVE_EXTENSIONS) {
412
+ if (fs7.existsSync(direct + ext)) return direct + ext;
413
+ }
414
+ return null;
415
+ }
416
+ for (const field of ["module", "jsnext:main", "jsnext", "main"]) {
417
+ if (typeof pkg[field] === "string") {
418
+ const entry = path8.join(pkgDir, pkg[field]);
419
+ if (fs7.existsSync(entry)) return entry;
420
+ }
421
+ }
422
+ return null;
423
+ }
424
+ function resolvePackageExports(exports, key, pkgDir) {
425
+ if (typeof exports === "string") {
426
+ return key === "." ? path8.join(pkgDir, exports) : null;
427
+ }
428
+ const entry = exports[key];
429
+ if (entry === void 0) return null;
430
+ return resolveExportValue(entry, pkgDir);
431
+ }
432
+ function resolveExportValue(value, pkgDir) {
433
+ if (typeof value === "string") return path8.join(pkgDir, value);
434
+ if (Array.isArray(value)) {
435
+ for (const item of value) {
436
+ const r = resolveExportValue(item, pkgDir);
437
+ if (r) return r;
438
+ }
439
+ return null;
440
+ }
441
+ if (value && typeof value === "object") {
442
+ for (const cond of ESM_CONDITIONS) {
443
+ if (cond in value) {
444
+ const r = resolveExportValue(value[cond], pkgDir);
445
+ if (r) return r;
446
+ }
447
+ }
448
+ }
449
+ return null;
450
+ }
303
451
  function resolveUrlToFile(url, root) {
304
452
  const cleanUrl = url.split("?")[0];
305
453
  if (cleanUrl.startsWith("/@modules/")) {
306
454
  const moduleName = cleanUrl.slice("/@modules/".length);
307
- try {
308
- const req = createRequire2(path8.resolve(root, "package.json"));
309
- return req.resolve(moduleName);
310
- } catch {
311
- return null;
312
- }
455
+ return resolveNodeModule(root, moduleName);
313
456
  }
314
457
  const filePath = path8.resolve(root, cleanUrl.replace(/^\//, ""));
315
458
  if (fs7.existsSync(filePath) && fs7.statSync(filePath).isFile()) {
@@ -430,14 +573,17 @@ if (!window.__nasti_hot_map) window.__nasti_hot_map = new Map();
430
573
  window.__NASTI_HMR__ = { createHotContext };
431
574
  `;
432
575
  }
433
- var RESOLVE_EXTENSIONS;
576
+ var esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
434
577
  var init_middleware = __esm({
435
578
  "src/server/middleware.ts"() {
436
579
  "use strict";
437
580
  init_transformer();
438
581
  init_html();
439
582
  init_env();
583
+ esmBundleCache = /* @__PURE__ */ new Map();
584
+ VALID_IDENT = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
440
585
  RESOLVE_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".mjs", ".json", ".vue"];
586
+ ESM_CONDITIONS = ["import", "browser", "module", "default"];
441
587
  }
442
588
  });
443
589
 
@@ -923,7 +1069,7 @@ import pc from "picocolors";
923
1069
  async function build(inlineConfig = {}) {
924
1070
  const config = await resolveConfig(inlineConfig, "build");
925
1071
  const startTime = performance.now();
926
- console.log(pc.cyan("\n\u{1F528} nasti build") + pc.dim(` v${"1.3.1"}`));
1072
+ console.log(pc.cyan("\n\u{1F528} nasti build") + pc.dim(` v${"1.3.3"}`));
927
1073
  console.log(pc.dim(` root: ${config.root}`));
928
1074
  console.log(pc.dim(` mode: ${config.mode}`));
929
1075
  const outDir = path7.resolve(config.root, config.build.outDir);
@@ -1329,7 +1475,7 @@ async function createServer(inlineConfig = {}) {
1329
1475
  const localUrl = `http://localhost:${actualPort}`;
1330
1476
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
1331
1477
  console.log();
1332
- console.log(pc2.cyan(" nasti dev server") + pc2.dim(` v${"1.3.1"}`));
1478
+ console.log(pc2.cyan(" nasti dev server") + pc2.dim(` v${"1.3.3"}`));
1333
1479
  console.log();
1334
1480
  console.log(` ${pc2.green(">")} Local: ${pc2.cyan(localUrl)}`);
1335
1481
  if (networkUrl) {