@nasti-toolchain/nasti 2.5.0 → 2.5.2

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.
Files changed (60) hide show
  1. package/README.md +34 -2
  2. package/dist/build-CENae4VM.js +748 -0
  3. package/dist/build-CENae4VM.js.map +1 -0
  4. package/dist/build-vjh6h7PB.cjs +786 -0
  5. package/dist/build-vjh6h7PB.cjs.map +1 -0
  6. package/dist/cli.cjs +166 -7608
  7. package/dist/cli.cjs.map +1 -1
  8. package/dist/cli.d.cts +1 -2
  9. package/dist/cli.d.ts +1 -2
  10. package/dist/cli.js +166 -7606
  11. package/dist/cli.js.map +1 -1
  12. package/dist/client/hmr.cjs +0 -19
  13. package/dist/client/hmr.d.cts +14 -12
  14. package/dist/client/hmr.d.cts.map +1 -0
  15. package/dist/client/hmr.d.ts +14 -12
  16. package/dist/client/hmr.d.ts.map +1 -0
  17. package/dist/client/hmr.js +1 -1
  18. package/dist/dev-engine-DJL9sfv5.cjs +473 -0
  19. package/dist/dev-engine-DJL9sfv5.cjs.map +1 -0
  20. package/dist/dev-engine-DapuTPIz.js +469 -0
  21. package/dist/dev-engine-DapuTPIz.js.map +1 -0
  22. package/dist/electron-Bj8H-BJ6.js +278 -0
  23. package/dist/electron-Bj8H-BJ6.js.map +1 -0
  24. package/dist/electron-D0PSXz-a.cjs +316 -0
  25. package/dist/electron-D0PSXz-a.cjs.map +1 -0
  26. package/dist/electron-dev-BzI2IFnR.cjs +272 -0
  27. package/dist/electron-dev-BzI2IFnR.cjs.map +1 -0
  28. package/dist/electron-dev-CM15gsFp.js +251 -0
  29. package/dist/electron-dev-CM15gsFp.js.map +1 -0
  30. package/dist/env-GY7K1zPK.js +833 -0
  31. package/dist/env-GY7K1zPK.js.map +1 -0
  32. package/dist/env-lOj3yw8v.cjs +924 -0
  33. package/dist/env-lOj3yw8v.cjs.map +1 -0
  34. package/dist/environment-B2jCrhY2.js +1361 -0
  35. package/dist/environment-B2jCrhY2.js.map +1 -0
  36. package/dist/environment-CjmvoHIG.cjs +1443 -0
  37. package/dist/environment-CjmvoHIG.cjs.map +1 -0
  38. package/dist/index.cjs +453 -7976
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +872 -817
  41. package/dist/index.d.cts.map +1 -0
  42. package/dist/index.d.ts +872 -817
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +418 -7939
  45. package/dist/index.js.map +1 -1
  46. package/dist/logger-BVZwdqqT.js +116 -0
  47. package/dist/logger-BVZwdqqT.js.map +1 -0
  48. package/dist/logger-M7AuVVTV.cjs +171 -0
  49. package/dist/logger-M7AuVVTV.cjs.map +1 -0
  50. package/dist/runnable-environment-BjoOvdDa.js +1345 -0
  51. package/dist/runnable-environment-BjoOvdDa.js.map +1 -0
  52. package/dist/runnable-environment-ByA3DHQ6.cjs +1351 -0
  53. package/dist/runnable-environment-ByA3DHQ6.cjs.map +1 -0
  54. package/dist/server-Bqgl25z0.js +1871 -0
  55. package/dist/server-Bqgl25z0.js.map +1 -0
  56. package/dist/server-BynlMdFc.cjs +1895 -0
  57. package/dist/server-BynlMdFc.cjs.map +1 -0
  58. package/package.json +20 -10
  59. package/dist/client/hmr.cjs.map +0 -1
  60. package/dist/client/hmr.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-BynlMdFc.cjs","names":["WsServer","ws","path","fs","path","fileURLToPath","createRequire","fs","buildEnvDefine","loadEnv","ssrDefineOverrides","readHtmlFile","processHtml","pc","removeTimestampQuery","replaceEnvInCode","transformReactCode","shouldTransform","transformCode","pathToFileURL","isAssetFile","path","fs","pc","resolveConfig","resolvePluginList","http","getPluginApi","NastiEnvironment","createWsHotChannel","buildEnvDefine","loadEnv","ssrDefineOverrides","runTransformRequest","path","watch","pc","os"],"sources":["../src/server/ws.ts","../src/server/fs-allow.ts","../src/server/middleware.ts","../src/server/hmr.ts","../src/server/index.ts"],"sourcesContent":["// WebSocket 服务封装 - HMR 通信\nimport { WebSocketServer as WsServer, type WebSocket } from 'ws'\nimport type { WebSocketServer as IWebSocketServer, HmrPayload } from '../types.js'\n\nexport function createWebSocketServer(server: any): IWebSocketServer {\n const wss = new WsServer({ noServer: true })\n const clients = new Set<WebSocket>()\n\n // 处理 HTTP server 的 upgrade 请求\n server.on('upgrade', (req: any, socket: any, head: any) => {\n if (req.headers['sec-websocket-protocol'] === 'nasti-hmr') {\n wss.handleUpgrade(req, socket, head, (ws) => {\n wss.emit('connection', ws, req)\n })\n }\n })\n\n wss.on('connection', (ws) => {\n clients.add(ws)\n ws.send(JSON.stringify({ type: 'connected' }))\n\n ws.on('close', () => {\n clients.delete(ws)\n })\n\n ws.on('error', (err) => {\n console.error('[nasti] WebSocket error:', err)\n clients.delete(ws)\n })\n })\n\n return {\n send(payload: HmrPayload) {\n const data = JSON.stringify(payload)\n for (const client of clients) {\n if (client.readyState === 1) { // WebSocket.OPEN\n client.send(data)\n }\n }\n },\n close() {\n clients.clear()\n wss.close()\n },\n }\n}\n","// Filesystem allowlist helpers for the unbundled dev server.\n//\n// pnpm (and yarn/npm) workspaces link packages into node_modules as symlinks\n// whose realpath sits *outside* the app root (e.g. apps/web → packages/ui).\n// Several paths need to treat those linked roots as first-class:\n// - `/@modules/...?id=` security checks (otherwise transitive workspace\n// deps 404 after realpath leaves node_modules)\n// - chokidar watch targets (otherwise edits in packages/* never HMR)\nimport fs from 'node:fs'\nimport path from 'node:path'\n\n/** True when `abs` is a real file/dir strictly inside `root` (not root itself). */\nexport function isUnderRoot(abs: string, root: string): boolean {\n const rel = path.relative(root, abs)\n return !!rel && !rel.startsWith('..') && !path.isAbsolute(rel)\n}\n\nconst NM = `${path.sep}node_modules${path.sep}`\n\n/**\n * Walk `node_modules` from `projectRoot` (and nested package roots) following\n * symlinks. Return real paths of packages that live *outside* the project root\n * and outside any `node_modules` tree — i.e. workspace / `file:` linked\n * packages. Regular pnpm store entries (under `.pnpm/.../node_modules/`) are\n * skipped: they are not user-editable watch targets and already pass the\n * `node_modules` segment check for `?id=`.\n */\nexport function discoverLinkedPackageRoots(\n projectRoot: string,\n maxDepth = 4,\n): string[] {\n const results: string[] = []\n const seenReal = new Set<string>()\n const queued = new Set<string>([projectRoot])\n const queue: string[] = [projectRoot]\n\n for (let depth = 0; depth < maxDepth && queue.length > 0; depth++) {\n const levelCount = queue.length\n for (let i = 0; i < levelCount; i++) {\n const dir = queue.shift()!\n const nm = path.join(dir, 'node_modules')\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(nm, { withFileTypes: true })\n } catch {\n continue\n }\n\n for (const ent of entries) {\n // Skip pnpm / yarn internals and bins — walking `.pnpm` would explode\n // into the whole store without finding additional workspace roots.\n if (ent.name.startsWith('.') || ent.name === 'node_modules') continue\n\n const pkgNames = ent.name.startsWith('@')\n ? listScopedPackages(nm, ent.name)\n : [ent.name]\n\n for (const pkgName of pkgNames) {\n const pkgPath = path.join(nm, pkgName)\n let real: string\n try {\n real = fs.realpathSync(pkgPath)\n } catch {\n continue\n }\n if (seenReal.has(real)) continue\n seenReal.add(real)\n\n // Always enqueue so transitive workspace deps (A → B, app only\n // depends on A) are discovered via A's own node_modules.\n if (!queued.has(real)) {\n queued.add(real)\n queue.push(real)\n }\n\n if (\n real !== projectRoot &&\n !isUnderRoot(real, projectRoot) &&\n !real.includes(NM)\n ) {\n results.push(real)\n }\n }\n }\n }\n }\n\n return results\n}\n\nfunction listScopedPackages(nm: string, scope: string): string[] {\n try {\n return fs\n .readdirSync(path.join(nm, scope))\n .filter((name) => !name.startsWith('.'))\n .map((name) => path.join(scope, name))\n } catch {\n return []\n }\n}\n\nconst linkedRootsCache = new Map<string, { roots: string[]; mtimeMs: number }>()\n\n/** Cached discoverLinkedPackageRoots; invalidated when root/node_modules mtime changes. */\nexport function getLinkedPackageRoots(projectRoot: string): string[] {\n let mtimeMs = 0\n try {\n mtimeMs = fs.statSync(path.join(projectRoot, 'node_modules')).mtimeMs\n } catch {\n mtimeMs = 0\n }\n const cached = linkedRootsCache.get(projectRoot)\n if (cached && cached.mtimeMs === mtimeMs) {\n return cached.roots\n }\n const roots = discoverLinkedPackageRoots(projectRoot)\n linkedRootsCache.set(projectRoot, { roots, mtimeMs })\n return roots\n}\n\n/**\n * Clear the linked-roots cache. Call from the file watcher when any\n * `node_modules` tree changes (including nested ones under linked packages).\n */\nexport function clearLinkedPackageRootsCache(): void {\n linkedRootsCache.clear()\n}\n\n/**\n * Whether a realpath'd absolute file may be served via `/@modules/...?id=`.\n *\n * Allowed:\n * 1. under the project root (includes the app's own `node_modules`)\n * 2. under a `node_modules` directory on the walk up from the project root\n * (monorepo-hoisted stores such as `<repo>/node_modules/.pnpm/...`)\n * 3. under a workspace / file: package linked from the project's\n * node_modules tree (realpath leaves node_modules)\n *\n * A forged path that merely contains a `node_modules` segment under an\n * unrelated directory (e.g. `/tmp/other/node_modules/x`) is rejected.\n */\nexport function isAllowedDevModulePath(realId: string, projectRoot: string): boolean {\n if (realId === projectRoot || isUnderRoot(realId, projectRoot)) return true\n for (const pkgRoot of getLinkedPackageRoots(projectRoot)) {\n if (realId === pkgRoot || realId.startsWith(pkgRoot + path.sep)) return true\n }\n // Monorepo hoist: allow `<ancestor>/node_modules/...` while walking up from root.\n let dir = projectRoot\n for (;;) {\n const nm = path.join(dir, 'node_modules')\n if (realId === nm || realId.startsWith(nm + path.sep)) return true\n const parent = path.dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return false\n}\n\n/**\n * Walk up from `file` looking for the nearest directory with a package.json\n * that has a `name` field (a package root).\n */\nexport function findNearestPackageRoot(file: string): string | null {\n let dir = path.dirname(file)\n for (;;) {\n const pkgJson = path.join(dir, 'package.json')\n if (fs.existsSync(pkgJson)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgJson, 'utf-8'))\n if (typeof pkg?.name === 'string' && pkg.name) return dir\n } catch {\n /* keep walking */\n }\n }\n const parent = path.dirname(dir)\n if (parent === dir) return null\n dir = parent\n }\n}\n","// HTTP 中间件 - 请求拦截与按需转译\nimport path from 'node:path'\nimport fs from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport pc from 'picocolors'\nimport type { EnvironmentInstance, ResolvedConfig } from '../types.js'\nimport { PluginContainer } from '../core/plugin-container.js'\nimport { ModuleGraph } from '../core/module-graph.js'\nimport {\n transformCode,\n transformReactCode,\n shouldTransform,\n getModuleType,\n} from '../core/transformer.js'\nimport { readHtmlFile, processHtml } from '../plugins/html.js'\nimport {\n loadEnv,\n buildEnvDefine,\n replaceEnvInCode,\n ssrDefineOverrides,\n} from '../core/env.js'\nimport { removeTimestampQuery } from '../core/url.js'\nimport { isAssetFile } from '../plugins/assets.js'\nimport { isAllowedDevModulePath, isUnderRoot, getLinkedPackageRoots } from './fs-allow.js'\n\nconst __dirname_esm = path.dirname(fileURLToPath(import.meta.url))\nconst __require = createRequire(import.meta.url)\n\n/**\n * 将 react-refresh 的 CJS 运行时包装成浏览器可用的 ESM。\n * 原 CJS 通过 `exports.xxx = fn` 写入导出;我们用假的 module/exports/process\n * 对象跑一遍,再显式 re-export 出来。\n *\n * 读一次缓存一次:dev server 生命周期内不会变。\n */\nlet __refreshRuntimeCache: string | null = null\nexport function getReactRefreshRuntimeEsm(includeBoundaryHelpers = false): string {\n if (__refreshRuntimeCache) {\n return includeBoundaryHelpers\n ? __refreshRuntimeCache + REACT_REFRESH_BOUNDARY_HELPERS\n : __refreshRuntimeCache\n }\n // react-refresh 的 package.json `exports` 没有暴露 ./cjs/*,Node 24 严格执行\n // exports 后 `require.resolve('react-refresh/cjs/...')` 会抛 ERR_PACKAGE_PATH_NOT_EXPORTED。\n // 改为先 resolve 受支持的 ./package.json,再手动拼 cjs 子路径,绕开 exports 校验。\n let cjsPath: string\n try {\n const pkgPath = __require.resolve('react-refresh/package.json')\n cjsPath = path.join(path.dirname(pkgPath), 'cjs', 'react-refresh-runtime.development.js')\n } catch (err) {\n // 兜底:从 dist 向上找\n cjsPath = path.resolve(__dirname_esm, '../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js')\n if (!fs.existsSync(cjsPath)) {\n const origMsg = err instanceof Error ? err.message : String(err)\n throw new Error(\n `[nasti] Missing dependency \"react-refresh\". Install it with: npm install react-refresh\\nOriginal resolve error: ${origMsg}`,\n )\n }\n }\n const cjsSource = fs.readFileSync(cjsPath, 'utf-8')\n // 这些命名对应 react-refresh-runtime 的公共导出,与\n // node -e \"Object.keys(require('react-refresh/runtime'))\" 对齐。\n __refreshRuntimeCache = `// Wrapped react-refresh runtime -> ESM\nconst exports = {};\nconst module = { exports };\nconst process = { env: { NODE_ENV: 'development' } };\n${cjsSource}\nconst __rt = module.exports;\nexport const injectIntoGlobalHook = __rt.injectIntoGlobalHook;\nexport const register = __rt.register;\nexport const createSignatureFunctionForTransform = __rt.createSignatureFunctionForTransform;\nexport const performReactRefresh = __rt.performReactRefresh;\nexport const isLikelyComponentType = __rt.isLikelyComponentType;\nexport const hasUnrecoverableErrors = __rt.hasUnrecoverableErrors;\nexport const setSignature = __rt.setSignature;\nexport const getFamilyByID = __rt.getFamilyByID;\nexport const getFamilyByType = __rt.getFamilyByType;\nexport const findAffectedHostInstances = __rt.findAffectedHostInstances;\nexport const collectCustomHooksForSignature = __rt.collectCustomHooksForSignature;\nexport default __rt;\n`\n return includeBoundaryHelpers\n ? __refreshRuntimeCache + REACT_REFRESH_BOUNDARY_HELPERS\n : __refreshRuntimeCache\n}\n\n/** @vitejs/plugin-react 同类的 Refresh boundary 校验,避免非组件导出静默保持旧值。 */\nconst REACT_REFRESH_BOUNDARY_HELPERS = `\nfunction __nastiIsPlainObject(obj) {\n return Object.prototype.toString.call(obj) === '[object Object]' &&\n (obj.constructor === Object || obj.constructor === undefined);\n}\nfunction __nastiIsCompoundComponent(type) {\n if (!__nastiIsPlainObject(type)) return false;\n for (const key in type) {\n if (!isLikelyComponentType(type[key])) return false;\n }\n return true;\n}\nexport function registerExportsForReactRefresh(filename, moduleExports) {\n for (const key in moduleExports) {\n if (key === '__esModule') continue;\n const value = moduleExports[key];\n if (isLikelyComponentType(value)) {\n register(value, filename + ' export ' + key);\n } else if (__nastiIsCompoundComponent(value)) {\n for (const subKey in value) {\n register(value[subKey], filename + ' export ' + key + '-' + subKey);\n }\n }\n }\n}\nlet __nastiRefreshTimer;\nfunction __nastiEnqueueRefresh() {\n clearTimeout(__nastiRefreshTimer);\n __nastiRefreshTimer = setTimeout(() => performReactRefresh(), 16);\n}\nfunction __nastiCheckExports(ignored, exports, predicate) {\n for (const key in exports) {\n if (ignored.includes(key)) continue;\n if (!predicate(key, exports[key])) return key;\n }\n return true;\n}\nexport function validateRefreshBoundaryAndEnqueueUpdate(id, prevExports, nextExports) {\n const ignored = window.__getReactRefreshIgnoredExports?.({ id }) ?? [];\n if (__nastiCheckExports(ignored, prevExports, (key) => key in nextExports) !== true) {\n return 'Could not Fast Refresh (export removed)';\n }\n if (__nastiCheckExports(ignored, nextExports, (key) => key in prevExports) !== true) {\n return 'Could not Fast Refresh (new export)';\n }\n let hasExports = false;\n const compatible = __nastiCheckExports(ignored, nextExports, (key, value) => {\n hasExports = true;\n return isLikelyComponentType(value) ||\n __nastiIsCompoundComponent(value) ||\n prevExports[key] === value;\n });\n if (!hasExports) {\n return 'Could not Fast Refresh (no exports)';\n }\n if (compatible === true) {\n __nastiEnqueueRefresh();\n return;\n }\n return 'Could not Fast Refresh (\"' + compatible + '\" export is incompatible)';\n}\nexport const __hmr_import = (module) => import(module);\n`\n\n/**\n * React Fast Refresh 全局钩子安装脚本。\n * 必须在用户代码之前执行,由 html.ts 以 head-prepend 的方式注入到 index.html。\n */\nexport const REACT_REFRESH_GLOBAL_PREAMBLE = `\nimport RefreshRuntime from \"/@react-refresh\";\nRefreshRuntime.injectIntoGlobalHook(window);\nwindow.$RefreshReg$ = () => {};\nwindow.$RefreshSig$ = () => (type) => type;\nwindow.__vite_plugin_react_preamble_installed__ = true;\n`.trim()\n\n/**\n * 单模块的 Fast Refresh 包装。\n *\n * 包装前先把 transformed 代码里的 `import.meta.hot` 替换为本地 `__nasti_hot__`\n * 变量 —— 规避 `import.meta` 属性赋值在某些引擎下不可写的问题,并统一 JSX/非 JSX\n * 路径的 hot 来源。\n */\nfunction buildReactRefreshWrapper(moduleUrl: string, transformedCode: string): string {\n const urlLit = JSON.stringify(moduleUrl)\n const userCode = transformedCode.replace(/\\bimport\\.meta\\.hot\\b/g, '__nasti_hot__')\n return `import * as RefreshRuntime from \"/@react-refresh\";\nimport { createHotContext as __nasti_createHotContext__ } from \"/@nasti/client\";\nconst __nasti_hot__ = __nasti_createHotContext__(${urlLit});\n\nif (!window.__vite_plugin_react_preamble_installed__) {\n throw new Error(\"[nasti] React Fast Refresh preamble missing. Make sure nasti:html is wired with framework: 'react'.\");\n}\n\nconst prevRefreshReg = window.$RefreshReg$;\nconst prevRefreshSig = window.$RefreshSig$;\nwindow.$RefreshReg$ = (type, id) => {\n RefreshRuntime.register(type, ${urlLit} + \" \" + id);\n};\nwindow.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;\n\n${userCode}\n\nwindow.$RefreshReg$ = prevRefreshReg;\nwindow.$RefreshSig$ = prevRefreshSig;\n\nif (__nasti_hot__) {\n let __nasti_current_exports__;\n __nasti_hot__.accept((nextExports) => {\n if (!nextExports) return;\n if (!__nasti_current_exports__) {\n __nasti_hot__.invalidate('Could not Fast Refresh (previous exports unavailable)');\n return;\n }\n const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(\n ${urlLit},\n __nasti_current_exports__,\n nextExports,\n );\n if (invalidateMessage) __nasti_hot__.invalidate(invalidateMessage);\n });\n RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {\n __nasti_current_exports__ = currentExports;\n RefreshRuntime.registerExportsForReactRefresh(${urlLit}, currentExports);\n });\n}\n`\n}\n\n/**\n * 非 JSX 模块里用户显式写了 import.meta.hot —— 注入一段 hot context 头部并替换属性访问为本地变量。\n */\nfunction injectImportMetaHot(code: string, moduleUrl: string): string {\n const hotRE = /\\bimport\\.meta\\.hot\\b/g\n const matches = [...maskStringsAndComments(code).matchAll(hotRE)]\n if (matches.length === 0) return code\n\n for (const match of matches.reverse()) {\n const start = match.index\n code = code.slice(0, start) + '__nasti_hot__' + code.slice(start + match[0].length)\n }\n const urlLit = JSON.stringify(moduleUrl)\n const header = `import { createHotContext as __nasti_createHotContext__ } from \"/@nasti/client\";\nconst __nasti_hot__ = __nasti_createHotContext__(${urlLit});\n`\n return header + code\n}\n\nexport interface TransformMiddlewareContext {\n config: ResolvedConfig\n pluginContainer: PluginContainer\n moduleGraph: ModuleGraph\n environment?: EnvironmentInstance\n envDefine?: Record<string, string>\n onPrune?: (paths: string[]) => void\n}\n\n/** 主转译中间件 - 处理模块请求 */\nexport function transformMiddleware(ctx: TransformMiddlewareContext) {\n // 预加载环境变量,避免每次请求都重新读取 .env 文件\n ctx.envDefine = buildEnvDefine(\n loadEnv(ctx.config.mode, ctx.config.root, ctx.config.envPrefix),\n ctx.config.mode,\n ssrDefineOverrides(ctx.environment?.consumer ?? 'client'),\n )\n return async (req: IncomingMessage, res: ServerResponse, next: () => void) => {\n const url = req.url ?? '/'\n\n // 设置 CORS 响应头\n if (ctx.config.server.cors) {\n const origin = req.headers.origin ?? '*'\n res.setHeader('Access-Control-Allow-Origin', origin)\n res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type')\n if (req.method === 'OPTIONS') {\n res.statusCode = 204\n res.end()\n return\n }\n }\n\n // 跳过非 GET 请求\n if (req.method !== 'GET') return next()\n\n // 处理 HMR 客户端请求\n if (url === '/@nasti/client') {\n res.setHeader('Content-Type', 'application/javascript')\n res.end(getHmrClientCode())\n return\n }\n\n // 处理 HTML 请求\n if (url === '/' || url.endsWith('.html')) {\n const html = await readHtmlFile(\n ctx.config.root,\n ctx.config.environments.client?.html,\n )\n if (html) {\n let processedHtml = html\n\n // 执行 transformIndexHtml 钩子\n for (const plugin of ctx.config.plugins) {\n if (plugin.transformIndexHtml) {\n const result = await plugin.transformIndexHtml(processedHtml)\n if (typeof result === 'string') {\n processedHtml = result\n } else if (result && 'html' in result) {\n processedHtml = processHtml(result.html, result.tags)\n } else if (Array.isArray(result)) {\n processedHtml = processHtml(processedHtml, result)\n }\n }\n }\n\n res.setHeader('Content-Type', 'text/html')\n res.end(processedHtml)\n return\n }\n }\n\n // 处理模块请求(.ts, .tsx, .jsx, .vue, .css 等)\n if (isModuleRequest(url, req.headers['sec-fetch-dest'])) {\n try {\n const result = await transformRequest(url, ctx)\n if (result) {\n const contentType = url.endsWith('.css')\n ? 'application/javascript' // CSS 已转为 JS 模块\n : 'application/javascript'\n res.setHeader('Content-Type', contentType)\n res.setHeader('Cache-Control', 'no-cache')\n res.end(typeof result === 'string' ? result : result.code)\n return\n }\n } catch (err: any) {\n ctx.config.logger.error(\n pc.red(`Transform error: ${url}\\n`) + (err.stack ?? err.message),\n { timestamp: true, error: err },\n )\n res.statusCode = 500\n res.end(`Transform error: ${err.message}`)\n return\n }\n }\n\n next()\n }\n}\n\n/** 转译单个模块 */\nexport async function transformRequest(\n url: string,\n ctx: TransformMiddlewareContext,\n): Promise<{ code: string; map?: unknown } | null> {\n const { config, pluginContainer, moduleGraph } = ctx\n\n // HMR 的时间戳只用于绕过浏览器缓存,不能创建新的模块图节点或 hot context。\n url = removeTimestampQuery(url)\n const cleanReqUrl = url.split('?')[0]\n\n // 检查缓存\n const cached = moduleGraph.getModuleByUrl(url)\n if (cached?.transformResult) {\n return cached.transformResult as { code: string; map?: unknown }\n }\n\n // React Refresh 真实运行时(来自 react-refresh/cjs 包装为 ESM)\n if (cleanReqUrl === '/@react-refresh') {\n return { code: getReactRefreshRuntimeEsm(true) }\n }\n\n // `/@modules/<spec>?id=<abs>`:打包阶段已(相对 importer 真实目录)解析好的依赖文件。\n // 直接按该绝对路径打成 ESM,跳过 `resolveNodeModule(root, ...)` —— pnpm 严格布局下\n // 传递依赖不在顶层 node_modules,从 root 解析必然 404。`id` 由 externalSpecToModuleUrl /\n // subpath shim 用 encodeURIComponent 写入,URLSearchParams.get 自动解码(含 pnpm 路径里的 `+`)。\n if (cleanReqUrl.startsWith('/@modules/') && url.includes('?')) {\n const idParam = new URLSearchParams(url.slice(url.indexOf('?') + 1)).get('id')\n // 安全校验:`?id=` 本应只由我们自己写入(externalSpecToModuleUrl / subpath shim\n // 解析到的依赖真实文件),但浏览器或恶意页面可向 dev server 伪造任意绝对路径。\n // 解析真实路径后必须 (a) 是普通文件、(b) 落在 node_modules / 项目根 / 经\n // node_modules symlink 可达的 workspace·file: 包内,否则拒绝 —— 防止借此把\n // /etc/passwd、~/.ssh/* 等任意磁盘文件打成 ESM 读出去。\n let realId: string | null = null\n let realIdValid = false\n try {\n if (idParam) {\n realId = fs.realpathSync(idParam)\n // statSync 可能在 realpathSync 之后、检查之前因文件被删 / 权限变更而抛错(TOCTOU)。\n // 与上面的 realpathSync 一样按「校验失败」处理:落到下面的解析分支,而非把\n // 文件系统竞态变成 500(HTTP 路径)或向 server.transformRequest 调用方抛异常。\n realIdValid =\n fs.statSync(realId).isFile() && isAllowedDevModulePath(realId, config.root)\n }\n } catch {\n realId = null\n realIdValid = false\n }\n if (realId && realIdValid) {\n const mod = await moduleGraph.ensureEntryFromUrl(url)\n moduleGraph.registerModule(mod, realId)\n const code = await bundlePackageAsEsm(realId, config.root)\n const transformResult = { code }\n mod.transformResult = transformResult\n return transformResult\n }\n }\n\n // 插件提供的虚拟模块。\n //\n // Vite 风格的插件(如 chen-the-dawnstreak 的 file-based routing、virtual SVG sprite 等)\n // 用 `resolveId` 声称某个 bare specifier(例如 `virtual:chen-routes`),再用 `load` 提供模块源码。\n // `rewriteImports` 已经把 bare specifier 改写成 `/@modules/<spec>`,所以这里是它们落到 dev server 上的入口。\n //\n // 之前 dev server 仅做 `resolveUrlToFile` 的磁盘查找 → 直接 404。这里在落盘查找之前先问插件,\n // 如果有人接管这个 spec **并且** 解析后的 id 不是真实文件(`\\0`-前缀或不存在),就走插件\n // 的 load → transform 管道;real file 路径则交给原来的 `bundlePackageAsEsm` 分支处理。\n //\n // 没有任何插件认领的 spec 仍然回落到 `resolveNodeModule`,npm 包加载行为不变。\n if (cleanReqUrl.startsWith('/@modules/')) {\n const spec = cleanReqUrl.slice('/@modules/'.length)\n const virtual = await loadVirtualModule(spec, ctx)\n if (virtual) {\n const mod = await moduleGraph.ensureEntryFromUrl(url)\n moduleGraph.setModuleId(mod, virtual.id)\n mod.transformResult = virtual.result\n return virtual.result\n }\n }\n\n // 带「语义 query」的模块请求(如 Vue style 子块\n // `/abs/App.vue?vue&type=style&index=0&lang.css`):先问插件的 load → transform\n // 管道,**不要求磁盘上存在对应文件**(虚拟子模块)。默认的\"读盘 + 剥 query\"\n // 路径会把子模块错当成父模块整体重新编译(1.x 的 Vue dev 样式因此从未生效)。\n // `?t=`(HMR 时间戳)除外。\n const rawQuery = url.includes('?') ? url.slice(url.indexOf('?') + 1) : ''\n if (rawQuery && !/^t=\\d+$/.test(rawQuery)) {\n const mod = await moduleGraph.ensureEntryFromUrl(url)\n const transformVersion = mod.invalidationVersion\n const loaded = await pluginContainer.load(url)\n if (loaded != null) {\n let code = typeof loaded === 'string' ? loaded : loaded.code\n let map = typeof loaded === 'string' ? undefined : loaded.map\n const transformed = await pluginContainer.transform(code, url)\n if (transformed != null) {\n code = typeof transformed === 'string' ? transformed : transformed.code\n if (typeof transformed !== 'string' && transformed.map != null) {\n map = transformed.map\n }\n }\n // file 关联磁盘上的父文件:父文件变更时子模块一并失效\n const parentFile = resolveUrlToFile(cleanReqUrl, config.root) ?? cleanReqUrl\n moduleGraph.registerModule(mod, parentFile)\n const hotInfo = rewriteHotAcceptDeps(code, config, parentFile)\n code = injectImportMetaHot(hotInfo.code, url)\n code = replaceEnvInCode(code, ctx.envDefine ?? buildEnvDefine(\n loadEnv(config.mode, config.root, config.envPrefix),\n config.mode,\n ssrDefineOverrides(ctx.environment?.consumer ?? 'client'),\n ))\n const importedUrls = new Set<string>()\n code = rewriteImports(code, config, parentFile, importedUrls, moduleGraph)\n const pruned = await moduleGraph.updateModuleInfo(\n mod,\n importedUrls,\n hotInfo.acceptedUrls,\n hotInfo.isSelfAccepting,\n transformVersion,\n )\n const transformResult = { code, map }\n if (pruned) {\n if (pruned.size > 0) ctx.onPrune?.([...pruned].map((item) => item.url))\n mod.transformResult = transformResult\n }\n return transformResult\n }\n }\n\n // 解析文件路径\n const filePath = resolveUrlToFile(url, config.root)\n if (!filePath || !fs.existsSync(filePath)) return null\n\n // 创建/获取模块节点\n const mod = await moduleGraph.ensureEntryFromUrl(url)\n moduleGraph.registerModule(mod, filePath)\n const transformVersion = mod.invalidationVersion\n\n // node_modules 模块:用 rolldown 打成浏览器可用的 ESM\n // 解决 CJS 包(如 react)无法在浏览器中作为 ESM 使用的问题\n if (cleanReqUrl.startsWith('/@modules/')) {\n const code = await bundlePackageAsEsm(filePath, config.root)\n const transformResult = { code }\n mod.transformResult = transformResult\n return transformResult\n }\n\n // 先允许 assets 等专用 loader 把真实文件转换为 JS;无插件接管再读源码。\n const loaded = await pluginContainer.load(filePath)\n let code =\n loaded == null\n ? fs.readFileSync(filePath, 'utf-8')\n : typeof loaded === 'string'\n ? loaded\n : loaded.code\n let map: unknown = loaded && typeof loaded !== 'string' ? loaded.map : undefined\n\n // 通过插件管道 transform\n const pluginResult = await pluginContainer.transform(code, filePath)\n if (pluginResult) {\n code = typeof pluginResult === 'string' ? pluginResult : pluginResult.code\n if (typeof pluginResult !== 'string') map = pluginResult.map\n }\n\n // Fast Refresh / HMR 键必须在同一文件的多次 import(?t=xxx 变化)间稳定\n const stableUrl = cleanReqUrl\n\n // OXC 转译 (TS/JSX/TSX)。React 走独立管线,以便 Compiler 与 Refresh\n // 共享同一次 AST 转换;Vue/旧插件继续保持原来的后置转换顺序。\n let wrappedWithRefresh = false\n if (config.framework === 'react') {\n const refreshEnabled =\n (ctx.environment?.consumer ?? 'client') === 'client' &&\n config.server.hmr !== false\n const useRefresh = refreshEnabled && (\n !!config.react.compiler || /\\.[jt]sx$/.test(filePath)\n )\n const result = await transformReactCode(filePath, code, {\n react: config.react,\n consumer: ctx.environment?.consumer ?? 'client',\n development: true,\n reactRefresh: useRefresh,\n sourcemap: true,\n target: ctx.environment?.options.build.target ?? config.build.target,\n onWarning: (message) => config.logger.warn(`[nasti:react] ${message}`),\n })\n if (result) {\n code = result.code\n if (result.map) map = JSON.parse(result.map)\n if (useRefresh) {\n // 把模块包装起来:安装 $RefreshReg$/$RefreshSig$、建 hot context、尾部触发 performReactRefresh\n code = buildReactRefreshWrapper(stableUrl, code)\n wrappedWithRefresh = true\n }\n }\n } else if (shouldTransform(filePath)) {\n const result = transformCode(filePath, code, {\n sourcemap: true,\n jsxRuntime: 'automatic',\n jsxImportSource: 'vue',\n target: ctx.environment?.options.build.target ?? config.build.target,\n })\n code = result.code\n if (result.map) map = JSON.parse(result.map)\n }\n\n // 服务端与客户端必须使用同一组规范化 accept URL;否则消息里的 acceptedPath\n // 无法命中浏览器中注册的依赖回调。\n const hotInfo = rewriteHotAcceptDeps(code, config, filePath)\n code = hotInfo.code\n\n // 非 Fast-Refresh 模块里用户自己写了 import.meta.hot 的,注入 hot context\n if (!wrappedWithRefresh) {\n code = injectImportMetaHot(code, stableUrl)\n }\n\n // 替换 import.meta.env.* 为实际值\n const envDefine = ctx.envDefine ?? buildEnvDefine(\n loadEnv(config.mode, config.root, config.envPrefix),\n config.mode,\n ssrDefineOverrides(ctx.environment?.consumer ?? 'client'),\n )\n code = replaceEnvInCode(code, envDefine)\n\n // 重写 import 规范并同步模块图。变更后重新转换 importer 时,会给失效依赖追加\n // 时间戳,使浏览器真正重新执行依赖,而不是复用旧的 ESM Module Record。\n const importedUrls = new Set<string>()\n code = rewriteImports(code, config, filePath, importedUrls, moduleGraph)\n const pruned = await moduleGraph.updateModuleInfo(\n mod,\n importedUrls,\n hotInfo.acceptedUrls,\n wrappedWithRefresh || hotInfo.isSelfAccepting,\n transformVersion,\n )\n\n const transformResult = { code, map }\n if (pruned) {\n if (pruned.size > 0) ctx.onPrune?.([...pruned].map((item) => item.url))\n mod.transformResult = transformResult\n }\n return transformResult\n}\n\n/**\n * Run the plugin `resolveId` → `load` → `transform` pipeline for a bare specifier\n * that arrived as `/@modules/<spec>`, and return the prepared JS module if (and\n * only if) the result is a virtual module — i.e. its resolved id either uses the\n * Vite-convention `\\0` null-byte prefix or does not exist on disk.\n *\n * Real-file resolutions (e.g. an alias plugin remapping a bare specifier onto a\n * source file under the project) are intentionally skipped here so they fall\n * through to the normal `resolveUrlToFile` / `bundlePackageAsEsm` paths; this\n * keeps the npm-package loader and the React Refresh wrapper in charge of those.\n */\nasync function loadVirtualModule(\n spec: string,\n ctx: TransformMiddlewareContext,\n): Promise<{ id: string; result: { code: string } } | null> {\n const { config, pluginContainer } = ctx\n const resolved = await pluginContainer.resolveId(spec)\n if (resolved == null) return null\n const resolvedId = typeof resolved === 'string' ? resolved : resolved.id\n const looksVirtual = resolvedId.startsWith('\\0') || !fs.existsSync(resolvedId)\n if (!looksVirtual) return null\n\n const loadResult = await pluginContainer.load(resolvedId)\n if (loadResult == null) return null\n let code = typeof loadResult === 'string' ? loadResult : loadResult.code\n\n // Let other plugins transform the virtual source (e.g. macros, define-replace).\n const transformed = await pluginContainer.transform(code, resolvedId)\n if (transformed != null) {\n code = typeof transformed === 'string' ? transformed : transformed.code\n }\n\n // Replace `import.meta.env.*` and rewrite the inner import specifiers so the\n // browser can fetch them. Anchor at a synthetic file under the project root\n // so `./x` style imports inside generated code resolve from root (the same\n // contract Vite offers virtual modules whose ids don't map to a real dir).\n code = replaceEnvInCode(code, ctx.envDefine ?? buildEnvDefine(\n loadEnv(config.mode, config.root, config.envPrefix),\n config.mode,\n ssrDefineOverrides(ctx.environment?.consumer ?? 'client'),\n ))\n const anchor = path.join(config.root, '__nasti_virtual__.ts')\n code = rewriteImports(code, config, anchor)\n\n return { id: resolvedId, result: { code } }\n}\n\n/** 用 rolldown 将 node_modules 包打包为浏览器可用的 ESM(含 CJS→ESM 转换) */\n// Promise 缓存:同一入口文件只打包一次,防止并发重复打包\nconst esmBundleCache = new Map<string, Promise<string>>()\n\nasync function bundlePackageAsEsm(entryFile: string, root: string): Promise<string> {\n if (!esmBundleCache.has(entryFile)) {\n esmBundleCache.set(entryFile, doBundlePackage(entryFile, root))\n }\n return esmBundleCache.get(entryFile)!\n}\n\nasync function doBundlePackage(entryFile: string, root: string): Promise<string> {\n // 子路径入口(如 `react-aria-components/Select`)尝试生成 re-export shim,\n // 指向同包主入口。否则每个子路径会被 rolldown 各自打成独立 bundle,\n // 把同一份 `private/*.cjs` 内联多份 → 多个 `createContext(null)` 实例 →\n // React Aria 之类对 context identity 敏感的库会出现「provider 与 consumer\n // 看到的不是同一个 context」、`useContext` 返回 null 的运行期崩溃。\n // 详见: https://github.com/zixiao-labs/Nasti/pull/16\n const shim = await tryGenerateSubpathShim(entryFile, root)\n if (shim != null) return shim\n\n const { rolldown } = await import('rolldown')\n\n const bundle = await rolldown({\n input: entryFile,\n // 仅将其他 npm 包外部化;相对路径(包内部文件)全部内联打包\n external: (id: string) => {\n if (id.startsWith('.') || id.startsWith('/') || /^[A-Za-z]:\\\\/.test(id)) return false\n return true\n },\n })\n\n const result = await bundle.generate({ format: 'esm', exports: 'named' })\n await bundle.close()\n\n let code = result.output[0].code\n\n // 替换 process.env.NODE_ENV(rolldown 的 define 选项在此版本无效)\n code = code.replace(/process\\.env\\.NODE_ENV/g, '\"development\"')\n\n // 将外部化的 bare specifier 改写为 /@modules/ 路径供浏览器加载。\n // 解析相对「本包自身的真实目录」进行(externalSpecToModuleUrl),以兼容 pnpm\n // 严格布局下未被提升到顶层 node_modules 的传递依赖。\n // ⚠️ 必须用 ^ + m 锚定行首,只匹配真正的 import/export 声明,\n // 避免误匹配字符串内出现的 from \"...\" 导致 SyntaxError\n const externalBaseDir = path.dirname(entryFile)\n code = code\n .replace(/^(import\\b[^;'\"]*?\\bfrom\\s+)(['\"])([^'\"./][^'\"]*)(\\2)/gm,\n (_, prefix, q, spec) => `${prefix}${q}${externalSpecToModuleUrl(spec, externalBaseDir, root)}${q}`)\n .replace(/^(export\\b[^;'\"]*?\\bfrom\\s+)(['\"])([^'\"./][^'\"]*)(\\2)/gm,\n (_, prefix, q, spec) => `${prefix}${q}${externalSpecToModuleUrl(spec, externalBaseDir, root)}${q}`)\n .replace(/^(import\\s+)(['\"])([^'\"./][^'\"]*)(\\2)/gm,\n (_, prefix, q, spec) => `${prefix}${q}${externalSpecToModuleUrl(spec, externalBaseDir, root)}${q}`)\n\n // CJS 外部 require 改写:\n // rolldown 将 CJS 的 require(\"pkg\") 转为 __require(\"pkg\"),在浏览器中抛异常。\n // 收集所有 __require(\"pkg\"),替换为顶层 ESM import 的变量引用。\n code = rewriteExternalRequires(code, externalBaseDir, root)\n\n // CJS 包的具名导出补全 + ESM-interop default 解包:\n // rolldown 将 CJS 包包装为 __commonJSMin,只输出 `export default require_xxx()`,\n // 该调用返回的是整个 CJS exports 对象。这会引发两类问题:\n // 1. 具名导入失败:`import { parse } from '/@modules/cookie'` 没有静态命名导出。\n // 2. default 错误:当 CJS 模块自标 `__esModule: true` 且有 `default`\n // (tsc/babel 编译 ESM→CJS 的典型产物,如 `@gravity-ui/icons/Sun`),\n // `import X from '...'` 会拿到整个 namespace 对象而不是真正的 default 值,\n // 在 React 中表现为 \"Element type is invalid... got: object\"。\n // 通过 createRequire 在 Node.js 侧加载 CJS 模块、读取 exports,在 bundle\n // 末尾补具名 export,并按 Node import() interop 语义解包 default。\n if (code.includes('__commonJSMin')) {\n code = await injectCjsNamedExports(code, entryFile)\n }\n\n return code\n}\n\n/**\n * 当入口是 npm 包的「子路径」(即 `pkg/sub` 形式,对应 `node_modules/pkg/`\n * 内部的某个非主入口文件)时,尝试改用一个薄薄的 re-export shim 替代独立 bundle,\n * shim 通过 `/@modules/<pkgName>` 复用主入口 bundle 的导出。\n *\n * 这样做是为了避免「同一份代码被打到多个 bundle 里」造成的运行时 bug:\n * 例如 `react-aria-components/Select` 与 `react-aria-components` 主入口都内部\n * 依赖 `private/Select.*`,而 rolldown 会把这份相对依赖内联到各自的 bundle 中。\n * 结果是浏览器侧出现两个独立的 `SelectContext = createContext(null)` 实例 ——\n * `<Select>` 写入的 Provider 与下方 `<SelectValue>` 读到的 Consumer 不再指向\n * 同一个 context,`useContext` 返回 null 直接崩。React Aria 的 Tabs / Collection\n * / DialogTrigger 等都属于这一类对 context identity 敏感的设计。\n *\n * 安全前提:shim 仅在主入口 **完整覆盖** 子路径所有具名导出、且各导出值\n * 与主入口下的对应值是 **同一引用**(identity 相等)时生成;否则回退到普通\n * bundling,避免错误改写有副作用的子路径(如真正分裂的入口、wrapped exports)。\n *\n * 仅 dev server 使用:build 模式走单一 rolldown 整图打包,本身不会重复内联。\n */\nasync function tryGenerateSubpathShim(entryFile: string, root: string): Promise<string | null> {\n // 1. 必须位于 node_modules 内\n const NM = `${path.sep}node_modules${path.sep}`\n if (!entryFile.includes(NM)) return null\n\n // 2. 自下而上找第一份带 `name` 的 package.json,确认所属包根目录\n let pkgDir: string | null = null\n let pkgName: string | null = null\n let dir = path.dirname(entryFile)\n while (true) {\n const pkgJsonPath = path.join(dir, 'package.json')\n if (fs.existsSync(pkgJsonPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'))\n if (typeof pkg?.name === 'string' && pkg.name) {\n pkgDir = dir\n pkgName = pkg.name\n break\n }\n } catch {\n // 解析失败:继续向上找,但通常意味着这不是合法包\n }\n }\n const parent = path.dirname(dir)\n if (parent === dir) return null\n dir = parent\n // 一旦走出 node_modules 就放弃(用户源码不应进入此分支)\n if (!dir.includes(NM)) return null\n }\n if (!pkgDir || !pkgName) return null\n\n // 3. 选择与入口 **同扩展名** 的主入口路径。这一步至关重要:\n // 主入口的 `.cjs` 与子路径的 `.js`(ESM)在 Node 中会走不同的加载器,\n // 各自独立产生模块实例 —— 在 step 5 的 identity 校验里永远不等。\n // 而 dev server 上游 (`resolveUrlToFile`) 优先选取 `.js`/`.mjs` 而非 `.cjs`,\n // 因此我们必须按入口实际格式去拿匹配的主入口,避免跨格式比较。\n const entryExt = path.extname(entryFile)\n const mainEntry = pickMainEntryByExtension(pkgDir, entryExt)\n if (!mainEntry) return null\n if (path.resolve(mainEntry) === path.resolve(entryFile)) return null\n\n // 4. 用 `import()` 加载两侧(兼容 CJS / ESM;Node 会按文件扩展名自动选用\n // 正确的加载器,并以 file URL 共享模块缓存 —— 内部对相对依赖的 `require`\n // 会命中同一份 module instance)\n let mainNs: Record<string, unknown>\n let subNs: Record<string, unknown>\n try {\n mainNs = await import(pathToFileURL(mainEntry).href)\n subNs = await import(pathToFileURL(entryFile).href)\n } catch {\n return null\n }\n if (!mainNs || typeof mainNs !== 'object') return null\n if (!subNs || typeof subNs !== 'object') return null\n\n const subKeys = Object.keys(subNs).filter(\n (k) => k !== '__esModule' && k !== 'default' && VALID_IDENT.test(k),\n )\n if (subKeys.length === 0) return null\n\n // 5. 所有具名导出都必须存在于主入口、且引用相等\n for (const k of subKeys) {\n if (!(k in mainNs)) return null\n if (mainNs[k] !== subNs[k]) return null\n }\n\n // 子路径的 default 也必须由主入口承载且引用相等,否则下方的\n // `export default __pkg[\"default\"]` 会暴露错误(甚至 undefined)的 default。\n if ('default' in subNs) {\n if (!('default' in mainNs)) return null\n if (mainNs['default'] !== subNs['default']) return null\n }\n\n // 6. 生成 ESM shim:浏览器从 `/@modules/<pkgName>` 取到主 bundle 的命名空间,\n // 再按子路径所声明的导出名重新对外暴露。\n // 主入口 URL 必须与「其他模块对该包主入口的裸 import」命中同一个浏览器模块实例\n // —— 这正是 shim 去重 context(避免出现两份 `createContext`)的前提,见 PR #16。\n // rewriteImports 把用户源码里的裸 import 改写成裸 `/@modules/<pkgName>`,所以当该包\n // 主入口能从项目根解析、且解析到的就是当前这份包目录(同一版本实例)时,shim 也必须\n // 用裸 URL —— 浏览器按 URL 字符串去重,带 `?id=` 会被当成另一个模块而重复实例化。\n // 否则(pnpm 下未提升到顶层的传递依赖,或根部命中的是另一个版本)才回落到 `?id=`\n // 携带绝对路径,既避免 dev server 从 root 解析 404,也不会串到错误版本。\n const rootMain = resolveNodeModule(root, pkgName)\n const mainEntryUrl =\n rootMain && rootMain.startsWith(pkgDir + path.sep)\n ? `/@modules/${pkgName}`\n : `/@modules/${pkgName}?id=${encodeURIComponent(mainEntry)}`\n const lines: string[] = [\n `// Nasti subpath shim → ${pkgName} (avoid duplicate bundling)`,\n `import * as __pkg from \"${mainEntryUrl}\";`,\n ]\n for (const k of subKeys) {\n lines.push(`export const ${k} = __pkg[${JSON.stringify(k)}];`)\n }\n if ('default' in subNs) {\n lines.push(`export default (\"default\" in __pkg ? __pkg[\"default\"] : __pkg);`)\n }\n return lines.join('\\n') + '\\n'\n}\n\n/**\n * 解析包主入口绝对路径,**优先匹配指定扩展名**,再回退到任意可用主入口。\n * 主入口候选来自 `exports[\\\".\\\"]`(按 import / module / default / require / node 顺序展开嵌套条件)\n * 以及顶层 `module` / `main` 字段。\n */\nfunction pickMainEntryByExtension(pkgDir: string, preferredExt: string): string | null {\n const pkgJsonPath = path.join(pkgDir, 'package.json')\n let pkg: Record<string, any>\n try {\n pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'))\n } catch {\n return null\n }\n\n const candidates: string[] = []\n const collectFromExportObject = (obj: any) => {\n if (!obj || typeof obj !== 'object') return\n for (const cond of ['import', 'module', 'default', 'require', 'node']) {\n const v = obj[cond]\n if (typeof v === 'string') candidates.push(v)\n else if (v && typeof v === 'object') collectFromExportObject(v)\n }\n }\n const dot = pkg?.exports?.['.']\n if (typeof dot === 'string') candidates.push(dot)\n else if (dot && typeof dot === 'object') collectFromExportObject(dot)\n if (typeof pkg.module === 'string') candidates.push(pkg.module)\n if (typeof pkg.main === 'string') candidates.push(pkg.main)\n\n // 同扩展名优先\n for (const cand of candidates) {\n if (path.extname(cand) === preferredExt) {\n const full = path.resolve(pkgDir, cand)\n if (fs.existsSync(full)) return full\n }\n }\n // 任意可用候选\n for (const cand of candidates) {\n const full = path.resolve(pkgDir, cand)\n if (fs.existsSync(full)) return full\n }\n return null\n}\n\n/** 将 rolldown 生成的 __require(\"pkg\") 调用转换为顶层 ESM import\n * 使用 namespace import + default 回退,兼容 CJS 和 ESM 模块:\n * - CJS 包有 default export(__cjsMod)→ 取 .default\n * - ESM 包只有 named exports → 取 namespace 本身 */\nfunction rewriteExternalRequires(code: string, baseDir: string, root: string): string {\n const pkgs = new Set<string>()\n const re = /__require\\([\"']([^\"']+)[\"']\\)/g\n let m\n while ((m = re.exec(code)) !== null) {\n pkgs.add(m[1])\n }\n if (pkgs.size === 0) return code\n\n let result = code\n const imports: string[] = []\n for (const pkg of pkgs) {\n const safe = pkg.replace(/[^a-zA-Z0-9_$]/g, '_')\n imports.push(`import * as __ns_${safe} from \"${externalSpecToModuleUrl(pkg, baseDir, root)}\";`)\n imports.push(`var __req_${safe} = \"default\" in __ns_${safe} ? __ns_${safe}[\"default\"] : __ns_${safe};`)\n result = result.replaceAll(`__require(\"${pkg}\")`, `__req_${safe}`)\n result = result.replaceAll(`__require('${pkg}')`, `__req_${safe}`)\n }\n\n return imports.join('\\n') + '\\n' + result\n}\n\nconst VALID_IDENT = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/\n\nasync function injectCjsNamedExports(code: string, entryFile: string): Promise<string> {\n try {\n const { createRequire } = await import('module')\n const req = createRequire(entryFile)\n const cjsExports = req(entryFile)\n if (!cjsExports || (typeof cjsExports !== 'object' && typeof cjsExports !== 'function') || Array.isArray(cjsExports)) return code\n\n const namedKeys = Object.keys(cjsExports).filter(\n (k) => k !== '__esModule' && k !== 'default' && VALID_IDENT.test(k),\n )\n\n // ESM-interop unwrap: when the CJS module marks itself as `__esModule` and\n // exposes a `default` (typical for tsc/babel-compiled ESM emitted as CJS),\n // rolldown's `export default require_xxx()` would expose the entire CJS\n // namespace object instead of the inner `.default` — so `import X from \"pkg/sub\"`\n // hands the consumer `{ __esModule: true, default: X }` rather than `X`,\n // which breaks `<X />` in React with \"Element type is invalid ... got: object\".\n // Mirror Node's `import()` interop and unwrap to `__cjsMod.default`.\n const hasEsmInterop = cjsExports.__esModule === true && 'default' in cjsExports\n\n if (!hasEsmInterop && namedKeys.length === 0) return code\n\n // 把末尾的 \"export default require_xxx();\" 改写为带具名 export 的形式\n return code.replace(\n /^export default (\\w+\\(\\));?\\s*$/m,\n (_, call) => [\n `const __cjsMod = ${call};`,\n hasEsmInterop ? `export default __cjsMod.default;` : `export default __cjsMod;`,\n ...namedKeys.map((k) => `export const ${k} = __cjsMod[${JSON.stringify(k)}];`),\n ].join('\\n'),\n )\n } catch {\n return code\n }\n}\n\n/**\n * 重写 import/export 语句的模块规范:\n * - alias(如 `@/lib/api`)→ 解析后的项目内绝对 URL(带扩展名)\n * - 相对路径(`./x`、`../x`)→ 同样解析后回写为绝对 URL\n * - 项目内绝对路径(`/src/x`)→ 补扩展名\n * - 其余 bare specifier → `/@modules/<spec>`\n *\n * 浏览器加载无扩展名 URL(如 `/src/i18n`)时,里面的相对路径 `./locales/en`\n * 会按字面拼接得到 `/src/locales/en`,不会自动补 `.ts` 也不知道导入文件原先在\n * `/src/i18n/`。直接按 alias / fs 解析、回写绝对 URL,浏览器就能命中正确文件。\n */\nfunction rewriteImports(\n code: string,\n config: ResolvedConfig,\n filePath: string,\n importedUrls?: Set<string>,\n moduleGraph?: ModuleGraph,\n): string {\n const resolveSpec = createModuleSpecifierResolver(config, filePath)\n const transformSpec = (spec: string): string => {\n const resolved = removeTimestampQuery(resolveSpec(spec))\n importedUrls?.add(resolved)\n const timestamp = moduleGraph?.getModuleByUrl(resolved)?.lastHMRTimestamp ?? 0\n return timestamp > 0 ? appendTimestampQuery(resolved, timestamp) : resolved\n }\n\n return code\n // import ... from '...' / export ... from '...'\n .replace(\n /\\bfrom\\s+(['\"])([^'\"]+)\\1/g,\n (_m, q: string, s: string) => `from ${q}${transformSpec(s)}${q}`,\n )\n // 副作用 import: import '...'\n .replace(\n /\\bimport\\s+(['\"])([^'\"]+)\\1/g,\n (_m, q: string, s: string) => `import ${q}${transformSpec(s)}${q}`,\n )\n // 动态 import('...')\n .replace(\n /\\bimport\\s*\\(\\s*(['\"])([^'\"]+)\\1\\s*\\)/g,\n (_m, q: string, s: string) => `import(${q}${transformSpec(s)}${q})`,\n )\n}\n\nfunction createModuleSpecifierResolver(\n config: ResolvedConfig,\n filePath: string,\n): (specifier: string) => string {\n const root = config.root\n const fileDir = path.dirname(filePath)\n const aliasEntries = Object.entries(config.resolve.alias).sort(\n ([a], [b]) => b.length - a.length,\n )\n const toServableUrl = (abs: string): string | null => {\n if (isUnderRoot(abs, root)) {\n return '/' + path.relative(root, abs).replace(/\\\\/g, '/')\n }\n // Workspace / file: packages live outside root after realpath. Serve via\n // `/@fs/<abs>` (Vite-compatible) when the path is under a linked package.\n // Always use `/@fs/` so Windows drive paths become `/@fs/C:/...`, not `/@fsC:/...`.\n for (const pkgRoot of getLinkedPackageRoots(root)) {\n if (abs === pkgRoot || abs.startsWith(pkgRoot + path.sep)) {\n const normalized = abs.replace(/\\\\/g, '/')\n return '/@fs/' + (normalized.startsWith('/') ? normalized.slice(1) : normalized)\n }\n }\n return null\n }\n\n return (specifier: string): string => {\n // 解析时剥离 ?query / #hash(如 svg?url、json?import),回写时再附加到结果 URL\n const suffixMatch = specifier.match(/[?#].*$/)\n const suffix = suffixMatch ? suffixMatch[0] : ''\n const baseSpec = suffix ? specifier.slice(0, -suffix.length) : specifier\n\n // 1) alias —— 必须排在 bare 分支前,否则 `@/x` 会被当成 npm 包发到 /@modules/\n for (const [key, value] of aliasEntries) {\n if (baseSpec === key || baseSpec.startsWith(key + '/')) {\n const aliasBase = resolveAliasTarget(value, root)\n const sub = baseSpec.slice(key.length).replace(/^\\//, '')\n const target = sub ? path.join(aliasBase, sub) : aliasBase\n const resolved = tryResolveDiskPath(target)\n const url = resolved ? toServableUrl(resolved) : null\n return url ? url + suffix : specifier\n }\n }\n\n // 2) 相对路径\n if (baseSpec.startsWith('./') || baseSpec.startsWith('../')) {\n const resolved = tryResolveDiskPath(path.resolve(fileDir, baseSpec))\n const url = resolved ? toServableUrl(resolved) : null\n return url ? url + suffix : specifier\n }\n\n // 3) 项目内绝对路径\n if (baseSpec.startsWith('/') && !baseSpec.startsWith('/@')) {\n const resolved = tryResolveDiskPath(path.join(root, baseSpec.replace(/^\\//, '')))\n const url = resolved ? toServableUrl(resolved) : null\n return url ? url + suffix : specifier\n }\n\n // 4) 已改写的内部 URL 原样保留;其余 bare specifier 交给包中间件。\n if (baseSpec.startsWith('/')) return specifier\n return `/@modules/${specifier}`\n }\n}\n\ninterface HotAcceptAnalysis {\n code: string\n acceptedUrls: Set<string>\n isSelfAccepting: boolean\n}\n\n/**\n * 解析并规范化 import.meta.hot.accept() 的第一参数。\n * HMR API 只允许字符串字面量或字面量数组,因此无需引入完整 AST。\n */\nfunction rewriteHotAcceptDeps(\n code: string,\n config: ResolvedConfig,\n filePath: string,\n): HotAcceptAnalysis {\n const acceptedUrls = new Set<string>()\n const edits: Array<{ start: number; end: number; value: string }> = []\n const resolveSpec = createModuleSpecifierResolver(config, filePath)\n const acceptRE = /(?:\\bimport\\.meta\\.hot|\\b__nasti_hot__)(?:(?:\\?\\.)|\\.)accept\\s*\\(/g\n const searchableCode = maskStringsAndComments(code)\n let isSelfAccepting = false\n let match: RegExpExecArray | null\n\n while ((match = acceptRE.exec(searchableCode))) {\n let cursor = match.index + match[0].length\n const skipTrivia = (): void => {\n while (cursor < code.length) {\n if (/\\s/.test(code[cursor])) {\n cursor++\n continue\n }\n if (code[cursor] === '/' && code[cursor + 1] === '/') {\n cursor += 2\n while (cursor < code.length && code[cursor] !== '\\n') cursor++\n continue\n }\n if (code[cursor] === '/' && code[cursor + 1] === '*') {\n cursor += 2\n while (cursor < code.length && !(code[cursor] === '*' && code[cursor + 1] === '/')) cursor++\n cursor += 2\n continue\n }\n break\n }\n }\n skipTrivia()\n const first = code[cursor]\n\n if (!first || first === ')' || (first !== '[' && first !== \"'\" && first !== '\"' && first !== '`')) {\n isSelfAccepting = true\n continue\n }\n\n const readLiteral = (): void => {\n const quote = code[cursor]\n if (quote !== \"'\" && quote !== '\"' && quote !== '`') return\n const start = cursor\n cursor++\n let raw = ''\n while (cursor < code.length) {\n const char = code[cursor]\n if (char === '\\\\') {\n raw += code[cursor + 1] ?? ''\n cursor += 2\n continue\n }\n if (char === quote) {\n cursor++\n const resolved = removeTimestampQuery(resolveSpec(raw))\n acceptedUrls.add(resolved)\n edits.push({ start, end: cursor, value: JSON.stringify(resolved) })\n return\n }\n if (quote === '`' && char === '$' && code[cursor + 1] === '{') return\n raw += char\n cursor++\n }\n }\n\n if (first === '[') {\n cursor++\n while (cursor < code.length) {\n skipTrivia()\n if (code[cursor] === ',') {\n cursor++\n skipTrivia()\n }\n if (code[cursor] === ']') break\n const before = cursor\n readLiteral()\n if (cursor === before) break\n }\n } else {\n readLiteral()\n }\n }\n\n for (const edit of edits.sort((a, b) => b.start - a.start)) {\n code = code.slice(0, edit.start) + edit.value + code.slice(edit.end)\n }\n return { code, acceptedUrls, isSelfAccepting }\n}\n\n/** 用等长空格遮蔽字符串、模板字面量和注释,避免把文档文本误识别为 HMR 调用。 */\nfunction maskStringsAndComments(code: string): string {\n // split('') 保持 UTF-16 索引与 RegExp match.index 对齐(展开运算会合并代理对)。\n const masked = code.split('')\n let state:\n | 'code'\n | 'single'\n | 'double'\n | 'template'\n | 'regex'\n | 'regex-class'\n | 'line-comment'\n | 'block-comment' = 'code'\n\n const isRegexStart = (index: number): boolean => {\n let previous = index - 1\n while (previous >= 0 && /\\s/.test(code[previous])) previous--\n return previous < 0 || '=(:,!&|?{};[]+-*%^~<>'.includes(code[previous])\n }\n\n for (let i = 0; i < code.length; i++) {\n const char = code[i]\n const next = code[i + 1]\n if (state === 'code') {\n if (char === \"'\") state = 'single'\n else if (char === '\"') state = 'double'\n else if (char === '`') state = 'template'\n else if (char === '/' && next === '/') state = 'line-comment'\n else if (char === '/' && next === '*') state = 'block-comment'\n else if (char === '/' && isRegexStart(i)) state = 'regex'\n else continue\n masked[i] = ' '\n continue\n }\n\n if (state === 'line-comment') {\n if (char === '\\n') {\n state = 'code'\n } else {\n masked[i] = ' '\n }\n continue\n }\n if (state === 'block-comment') {\n masked[i] = char === '\\n' ? '\\n' : ' '\n if (char === '*' && next === '/') {\n masked[i + 1] = ' '\n i++\n state = 'code'\n }\n continue\n }\n if (state === 'regex' || state === 'regex-class') {\n masked[i] = char === '\\n' ? '\\n' : ' '\n if (char === '\\\\') {\n if (i + 1 < code.length) masked[++i] = ' '\n } else if (state === 'regex' && char === '[') {\n state = 'regex-class'\n } else if (state === 'regex-class' && char === ']') {\n state = 'regex'\n } else if (state === 'regex' && char === '/') {\n state = 'code'\n }\n continue\n }\n\n masked[i] = char === '\\n' ? '\\n' : ' '\n if (char === '\\\\') {\n if (i + 1 < code.length) masked[++i] = ' '\n continue\n }\n if (\n (state === 'single' && char === \"'\") ||\n (state === 'double' && char === '\"') ||\n (state === 'template' && char === '`')\n ) {\n state = 'code'\n }\n }\n return masked.join('')\n}\n\n/**\n * 把 alias 值统一成磁盘绝对路径。\n * - `/Users/.../src` 这类绝对路径直接用\n * - `/src` 这类用户写的「项目根相对」路径按 `<root>/src` 处理\n * - 其余字符串相对 root 解析\n */\nfunction resolveAliasTarget(value: string, root: string): string {\n if (path.isAbsolute(value) && fs.existsSync(value)) return value\n if (value.startsWith('/')) return path.join(root, value.slice(1))\n return path.resolve(root, value)\n}\n\n/** 把磁盘上的目标路径补全为存在的文件(扩展名 / index 兜底)。 */\nfunction tryResolveDiskPath(target: string): string | null {\n if (fs.existsSync(target) && fs.statSync(target).isFile()) return target\n for (const ext of RESOLVE_EXTENSIONS) {\n const withExt = target + ext\n if (fs.existsSync(withExt) && fs.statSync(withExt).isFile()) return withExt\n }\n if (fs.existsSync(target) && fs.statSync(target).isDirectory()) {\n for (const ext of RESOLVE_EXTENSIONS) {\n const idx = path.join(target, 'index' + ext)\n if (fs.existsSync(idx) && fs.statSync(idx).isFile()) return idx\n }\n }\n return null\n}\n\nfunction appendTimestampQuery(url: string, timestamp: number): string {\n const hashIndex = url.indexOf('#')\n const hash = hashIndex >= 0 ? url.slice(hashIndex) : ''\n const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url\n return `${withoutHash}${withoutHash.includes('?') ? '&' : '?'}t=${timestamp}${hash}`\n}\n\nconst RESOLVE_EXTENSIONS = ['.tsx', '.ts', '.jsx', '.js', '.mjs', '.json', '.vue']\nconst ESM_CONDITIONS = ['import', 'browser', 'module', 'default']\n\n/** 从 /@modules/pkgName/... URL 中提取包名(支持 scoped 包) */\nfunction modulesUrlToPkgName(url: string): string {\n const modulePath = url.slice('/@modules/'.length).split('?')[0]\n if (modulePath.startsWith('@')) {\n return modulePath.split('/').slice(0, 2).join('/')\n }\n return modulePath.split('/')[0]\n}\n\n/** 从 root 开始向上查找包目录 */\nfunction findPkgDir(root: string, pkgName: string): string | null {\n let dir = root\n for (;;) {\n const candidate = path.join(dir, 'node_modules', pkgName)\n if (fs.existsSync(candidate)) return candidate\n const parent = path.dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n\n/**\n * 将 node_modules 文件中的相对导入改写为 /@modules/pkgName/subpath 形式。\n * 浏览器加载 /@modules/pkgName 时,相对路径 ./foo.js 会被解析为 /@modules/foo.js\n * 而非正确的 /@modules/pkgName/dist/foo.js,因此必须在服务端将其改写为绝对路径。\n */\nfunction rewriteNodeModuleRelativeImports(\n code: string,\n pkgName: string,\n filePath: string,\n pkgDir: string,\n): string {\n const fileDir = path.dirname(filePath)\n const rewrite = (spec: string): string => {\n const abs = path.resolve(fileDir, spec)\n const rel = path.relative(pkgDir, abs).replace(/\\\\/g, '/')\n return `/@modules/${pkgName}/${rel}`\n }\n return code\n .replace(/\\bfrom\\s+(['\"])(\\.\\.?\\/[^'\"]*)\\1/g, (_, q, spec) => `from ${q}${rewrite(spec)}${q}`)\n .replace(/\\bimport\\s+(['\"])(\\.\\.?\\/[^'\"]*)\\1/g, (_, q, spec) => `import ${q}${rewrite(spec)}${q}`)\n .replace(/\\bimport\\s*\\(\\s*(['\"])(\\.\\.?\\/[^'\"]*)\\1\\s*\\)/g, (_, q, spec) => `import(${q}${rewrite(spec)}${q})`)\n}\n\n/**\n * 把 bundle 中被 external 化的 bare specifier 解析为浏览器可加载的 URL。\n *\n * 关键:相对「正在打包的包自身的真实目录」解析(而非项目根)。pnpm 严格布局下,\n * 传递依赖不会被提升到顶层 node_modules(只有直接依赖以 symlink 形式出现在那里),\n * 真实文件在 `.pnpm/<pkg>@<ver>/node_modules/` 内,其依赖是同目录下的兄弟包。\n * 从项目根向上走只能找到直接依赖 → 传递依赖(如 react-router 的 @tanstack/router-core)\n * 必然 404。改为从 importer 包的真实目录向上走即可命中。\n *\n * URL 去重(关键,关系到 React 等对实例唯一性敏感的库能否工作):用户源码里的裸 import\n * 被 rewriteImports 改写成裸 `/@modules/<spec>`,并由 dev server 从项目根解析。若从 importer\n * 真实目录解析与从项目根解析命中**同一真实文件**(npm/yarn 扁平布局,或依赖已被提升到顶层\n * node_modules),就必须同样发裸 URL —— 浏览器按 URL 字符串去重,带 `?id=` 会被当成另一个\n * 模块重复实例化。否则 app 的 `/@modules/react` 与 react-dom 外部化得到的\n * `/@modules/react?id=...` 会变成两份 React → 二者 dispatcher 不互通 → useEffect 读到 null →\n * \"Invalid hook call. Hooks can only be called inside of the body of a function component\"。\n *\n * 仅当项目根解析不到、或解析到的是**不同文件**(pnpm 未提升的传递依赖、多版本并存)时,\n * 才把 importer 相对解析到的绝对路径编码进 `?id=`,dev server 据此直接打包该文件,无需再次\n * 从 root 解析(见 transformRequest 中的 `/@modules/...?id=` 分支)。\n */\nfunction externalSpecToModuleUrl(spec: string, baseDir: string, root: string): string {\n const resolved = resolveNodeModule(baseDir, spec)\n if (!resolved) return `/@modules/${spec}`\n const rootResolved = resolveNodeModule(root, spec)\n if (rootResolved && rootResolved === resolved) return `/@modules/${spec}`\n return `/@modules/${spec}?id=${encodeURIComponent(resolved)}`\n}\n\n/**\n * ESM-aware node_modules 解析:支持 package.json exports 字段的 import/browser/module/default 条件,\n * 兼容 ESM-only 包(如只有 \"import\" 条件而无 \"require\" 的包)。\n * createRequire 使用 CJS 解析逻辑,遇到 ESM-only exports 会抛异常,因此不能用于此场景。\n *\n * **返回真实路径**(解析 symlink):pnpm 把直接依赖以 symlink 放在顶层 node_modules,\n * 真实文件在 `.pnpm/.../node_modules/` 下。后续打包阶段用 `dirname(entryFile)` 向上找\n * 传递依赖,只有从真实路径出发才能命中那些未被提升的兄弟包。\n */\nfunction resolveNodeModule(baseDir: string, moduleName: string): string | null {\n const resolved = resolveNodeModuleEntry(baseDir, moduleName)\n if (!resolved) return null\n try {\n return fs.realpathSync(resolved)\n } catch {\n return resolved\n }\n}\n\nfunction resolveNodeModuleEntry(root: string, moduleName: string): string | null {\n // 解析包名和子路径(处理 scoped 包如 @scope/pkg/sub)\n let pkgName: string\n let subpath: string\n if (moduleName.startsWith('@')) {\n const parts = moduleName.split('/')\n pkgName = parts.slice(0, 2).join('/')\n subpath = parts.slice(2).join('/')\n } else {\n const slash = moduleName.indexOf('/')\n pkgName = slash === -1 ? moduleName : moduleName.slice(0, slash)\n subpath = slash === -1 ? '' : moduleName.slice(slash + 1)\n }\n\n // 向上查找 node_modules\n let pkgDir: string | null = null\n let dir = root\n for (;;) {\n const candidate = path.join(dir, 'node_modules', pkgName)\n if (fs.existsSync(candidate)) { pkgDir = candidate; break }\n const parent = path.dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n if (!pkgDir) return null\n\n const pkgJsonPath = path.join(pkgDir, 'package.json')\n if (!fs.existsSync(pkgJsonPath)) return null\n let pkg: Record<string, any>\n try { pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) } catch { return null }\n\n // 优先使用 exports 字段(ESM-aware 条件解析)\n if (pkg.exports) {\n const exportKey = subpath ? `./${subpath}` : '.'\n const resolved = resolvePackageExports(pkg.exports, exportKey, pkgDir)\n if (resolved) return resolved\n }\n\n // 子路径直接文件\n if (subpath) {\n // 收集候选目录:包根目录 + module/main 字段所在的目录\n // 如 dom-helpers 的 module: 'esm/index.js',子路径 addClass 应查找 esm/addClass.js\n const subDirs = ['']\n for (const field of ['module', 'main']) {\n if (typeof pkg[field] === 'string') {\n const dir = path.dirname(pkg[field])\n if (dir && dir !== '.' && !subDirs.includes(dir)) subDirs.push(dir)\n }\n }\n for (const dir of subDirs) {\n const direct = path.join(pkgDir, dir, subpath)\n if (fs.existsSync(direct) && fs.statSync(direct).isFile()) return direct\n for (const ext of RESOLVE_EXTENSIONS) {\n if (fs.existsSync(direct + ext)) return direct + ext\n }\n }\n return null\n }\n\n // 主入口回退:module > main\n for (const field of ['module', 'jsnext:main', 'jsnext', 'main']) {\n if (typeof pkg[field] === 'string') {\n const entry = path.join(pkgDir, pkg[field])\n if (fs.existsSync(entry)) return entry\n }\n }\n\n // 最终回退:index.js\n const indexFallback = path.join(pkgDir, 'index.js')\n if (fs.existsSync(indexFallback)) return indexFallback\n\n return null\n}\n\nfunction resolvePackageExports(exports: any, key: string, pkgDir: string): string | null {\n if (typeof exports === 'string') {\n return key === '.' ? path.join(pkgDir, exports) : null\n }\n const entry = exports[key]\n if (entry === undefined) {\n // 顶层条件对象(如 `{\"import\": \"./x.mjs\", \"require\": \"./x.cjs\"}`)是 \".\" 入口的\n // 语法糖:当对象没有任何以 \".\" 开头的子路径键时,整个对象就是 \".\" 的条件映射,\n // 交给 resolveExportValue 走 ESM_CONDITIONS 解析,而不是误判为「无此导出」返回 null\n // (否则只能回落到 module/main,exports-only 的双格式包会解析失败)。\n if (\n key === '.' &&\n typeof exports === 'object' &&\n !Object.keys(exports).some((k) => k.startsWith('.'))\n ) {\n return resolveExportValue(exports, pkgDir)\n }\n return null\n }\n return resolveExportValue(entry, pkgDir)\n}\n\nfunction resolveExportValue(value: any, pkgDir: string): string | null {\n if (typeof value === 'string') return path.join(pkgDir, value)\n if (Array.isArray(value)) {\n for (const item of value) {\n const r = resolveExportValue(item, pkgDir)\n if (r) return r\n }\n return null\n }\n if (value && typeof value === 'object') {\n for (const cond of ESM_CONDITIONS) {\n if (cond in value) {\n const r = resolveExportValue(value[cond], pkgDir)\n if (r) return r\n }\n }\n }\n return null\n}\n\nfunction resolveUrlToFile(url: string, root: string): string | null {\n // 去除 query / hash,避免污染文件系统路径解析\n const cleanUrl = url.split(/[?#]/)[0]\n\n // /@modules/ 前缀 → node_modules 预构建\n if (cleanUrl.startsWith('/@modules/')) {\n const moduleName = cleanUrl.slice('/@modules/'.length)\n return resolveNodeModule(root, moduleName)\n }\n\n // /@fs/<abs>:workspace / file: 包在 root 外的源文件(Vite 兼容)\n if (cleanUrl.startsWith('/@fs/')) {\n let abs = cleanUrl.slice('/@fs/'.length)\n // URL 里是 POSIX 分隔符;Windows 盘符为 `C:/...`,Unix 需补回前导 `/`\n if (process.platform === 'win32') {\n abs = abs.replace(/\\//g, path.sep)\n } else if (!abs.startsWith('/')) {\n abs = '/' + abs\n }\n try {\n const real = fs.realpathSync(abs)\n if (fs.statSync(real).isFile() && isAllowedDevModulePath(real, root)) return real\n } catch {\n return null\n }\n return null\n }\n\n // 普通路径\n const filePath = path.resolve(root, cleanUrl.replace(/^\\//, ''))\n\n // 精确路径存在\n if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {\n return filePath\n }\n\n // 扩展名补全(处理无扩展名导入,如 ./App → ./App.tsx)\n for (const ext of RESOLVE_EXTENSIONS) {\n const withExt = filePath + ext\n if (fs.existsSync(withExt)) return withExt\n }\n\n // 目录 index 文件(如 ./utils → ./utils/index.ts)\n for (const ext of RESOLVE_EXTENSIONS) {\n const indexFile = path.join(filePath, 'index' + ext)\n if (fs.existsSync(indexFile)) return indexFile\n }\n\n return null\n}\n\nfunction isModuleRequest(\n url: string,\n destination?: string | string[],\n): boolean {\n const cleanUrl = url.split(/[?#]/)[0]\n if (/\\.(ts|tsx|jsx|js|mjs|vue|css|json)$/.test(cleanUrl)) return true\n if (cleanUrl.startsWith('/@modules/')) return true\n if (cleanUrl.startsWith('/@fs/')) return true\n if (isAssetFile(cleanUrl)) {\n const qIdx = url.indexOf('?')\n const hIdx = url.indexOf('#')\n const queryEnd = hIdx === -1 ? url.length : hIdx\n const query = qIdx === -1 || qIdx > queryEnd ? '' : url.slice(qIdx + 1, queryEnd)\n const isExplicitAssetModule = /(?:^|&)(?:url|raw)(?:&|$)/.test(query)\n return isExplicitAssetModule || destination === 'script'\n }\n // 无扩展名路径可能是省略扩展名的模块导入(如 /src/App)\n if (!path.extname(cleanUrl)) return true\n return false\n}\n\nfunction getHmrClientCode(): string {\n return `\n// Nasti HMR Client\nconst socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';\nconst socket = new WebSocket(socketProtocol + '://' + location.host, 'nasti-hmr');\nconst hotModulesMap = new Map();\nconst disposeMap = new Map();\nconst pruneMap = new Map();\nconst dataMap = new Map();\nconst customListenersMap = new Map();\nlet updateQueue = [];\nlet pendingUpdateQueue = false;\n\nsocket.addEventListener('message', async ({ data }) => {\n const payload = JSON.parse(data);\n // 默认浏览器 client 只消费自己的 HMR 消息;native/worker 环境通过各自的\n // HotChannel 或 app-level HMR 协调器处理同一 transport 上的命名消息。\n if (payload.environment && payload.environment !== 'client') return;\n switch (payload.type) {\n case 'connected':\n console.debug('[nasti] connected.');\n clearErrorOverlay();\n break;\n case 'update':\n try {\n // CSS 在 unbundled 模式下也是会注入 <style> 的 JS 模块,和普通 JS\n // 一样重新 import 才能执行 dispose/accept 并保持页面状态。\n await Promise.all(payload.updates.map(queueUpdate));\n clearErrorOverlay();\n console.debug('[nasti] HMR update complete.');\n } catch (err) {\n console.error('[nasti] HMR update failed:', err);\n showErrorOverlay(err);\n }\n break;\n case 'full-reload':\n console.log('[nasti] full reload');\n location.reload();\n break;\n case 'prune':\n await Promise.all(payload.paths.map(async (path) => {\n const data = dataMap.get(path);\n const dispose = disposeMap.get(path);\n const prune = pruneMap.get(path);\n if (dispose) await dispose(data);\n if (prune) await prune(data);\n hotModulesMap.delete(path);\n disposeMap.delete(path);\n pruneMap.delete(path);\n dataMap.delete(path);\n clearCustomListeners(path);\n }));\n break;\n case 'custom': {\n const listenersByOwner = customListenersMap.get(payload.event);\n if (!listenersByOwner) break;\n const results = await Promise.allSettled(\n [...listenersByOwner.values()]\n .flatMap((listeners) => [...listeners])\n .map((listener) => Promise.resolve().then(() => listener(payload.data)))\n );\n for (const result of results) {\n if (result.status === 'rejected') {\n console.error('[nasti] custom HMR event listener failed:', result.reason);\n }\n }\n break;\n }\n case 'error':\n console.error('[nasti] error:', payload.err.message);\n showErrorOverlay(payload.err);\n break;\n }\n});\n\n// 服务重启后旧模块图已失效,重连时整页刷新是必要兜底;正常 update 不再刷新。\nlet reconnectTimer = 0;\nsocket.addEventListener('close', () => {\n clearTimeout(reconnectTimer);\n reconnectTimer = setTimeout(() => location.reload(), 1000);\n});\n\n/**\n * 同一批更新先全部拉取,再按服务端消息顺序执行 accept 回调,避免 HTTP 往返速度\n * 改变模块应用顺序。这与 Vite HMRClient 的 fetch/apply 两阶段一致。\n */\nasync function queueUpdate(update) {\n updateQueue.push(fetchUpdate(update));\n if (pendingUpdateQueue) return;\n\n pendingUpdateQueue = true;\n await Promise.resolve();\n pendingUpdateQueue = false;\n const loading = updateQueue;\n updateQueue = [];\n const applyUpdates = await Promise.all(loading);\n for (const apply of applyUpdates) {\n if (apply) apply();\n }\n}\n\nasync function fetchUpdate(update) {\n const mod = hotModulesMap.get(update.path);\n // 尚未在当前页面加载的动态模块不需要更新。\n if (!mod) return;\n\n // 必须在重新 import 前确定旧回调;新模块执行 createHotContext 时会清空并注册新回调。\n const qualifiedCallbacks = mod.callbacks.filter(({ deps }) =>\n deps.includes(update.acceptedPath)\n );\n const isSelfUpdate = update.path === update.acceptedPath;\n if (!isSelfUpdate && qualifiedCallbacks.length === 0) return;\n\n const dispose = disposeMap.get(update.acceptedPath);\n if (dispose) await dispose(dataMap.get(update.acceptedPath));\n const newMod = await import(appendTimestampQuery(update.acceptedPath, update.timestamp));\n\n return () => {\n for (const { deps, fn } of qualifiedCallbacks) {\n fn(deps.map((dep) => dep === update.acceptedPath ? newMod : undefined));\n }\n const detail = isSelfUpdate\n ? update.path\n : update.acceptedPath + ' via ' + update.path;\n console.debug('[nasti] hot updated:', detail);\n };\n}\n\nfunction appendTimestampQuery(url, timestamp) {\n const hashIndex = url.indexOf('#');\n const hash = hashIndex >= 0 ? url.slice(hashIndex) : '';\n const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;\n return withoutHash + (withoutHash.includes('?') ? '&' : '?') + 't=' + timestamp + hash;\n}\n\nfunction clearErrorOverlay() {\n const el = document.getElementById('nasti-error-overlay');\n if (el) el.remove();\n}\n\nfunction showErrorOverlay(err) {\n clearErrorOverlay();\n const overlay = document.createElement('div');\n overlay.id = 'nasti-error-overlay';\n overlay.style.cssText = 'position:fixed;inset:0;z-index:99999;background:rgba(0,0,0,0.85);color:#fff;font-family:monospace;padding:2rem;overflow:auto;';\n const title = document.createElement('h2');\n title.style.color = '#ff5555';\n title.textContent = 'Build Error';\n const pre = document.createElement('pre');\n pre.textContent = err.message + '\\\\n' + (err.stack || '');\n const btn = document.createElement('button');\n btn.style.cssText = 'margin-top:1rem;padding:0.5rem 1rem;cursor:pointer';\n btn.textContent = 'Close';\n btn.onclick = () => overlay.remove();\n overlay.appendChild(title);\n overlay.appendChild(pre);\n overlay.appendChild(btn);\n document.body.appendChild(overlay);\n}\n\nexport function createHotContext(ownerPath) {\n if (!dataMap.has(ownerPath)) dataMap.set(ownerPath, {});\n\n // 模块重新执行时丢弃旧 accept 回调,但保留同一个 hot.data 对象。\n const existing = hotModulesMap.get(ownerPath);\n if (existing) existing.callbacks = [];\n clearCustomListeners(ownerPath);\n\n const acceptDeps = (deps, callback = () => {}) => {\n const mod = hotModulesMap.get(ownerPath) || { id: ownerPath, callbacks: [] };\n mod.callbacks.push({ deps, fn: callback });\n hotModulesMap.set(ownerPath, mod);\n };\n\n return {\n accept(deps, callback) {\n if (typeof deps === 'function' || deps === undefined) {\n acceptDeps([ownerPath], ([mod]) => deps?.(mod));\n } else if (typeof deps === 'string') {\n acceptDeps([deps], ([mod]) => callback?.(mod));\n } else if (Array.isArray(deps)) {\n acceptDeps(deps, callback);\n } else {\n throw new Error('invalid hot.accept() usage');\n }\n },\n prune(callback) {\n pruneMap.set(ownerPath, callback);\n },\n dispose(callback) {\n disposeMap.set(ownerPath, callback);\n },\n on(event, callback) {\n let listenersByOwner = customListenersMap.get(event);\n if (!listenersByOwner) {\n listenersByOwner = new Map();\n customListenersMap.set(event, listenersByOwner);\n }\n let listeners = listenersByOwner.get(ownerPath);\n if (!listeners) {\n listeners = new Set();\n listenersByOwner.set(ownerPath, listeners);\n }\n listeners.add(callback);\n },\n off(event, callback) {\n const listenersByOwner = customListenersMap.get(event);\n const listeners = listenersByOwner?.get(ownerPath);\n listeners?.delete(callback);\n if (listeners?.size === 0) listenersByOwner.delete(ownerPath);\n if (listenersByOwner?.size === 0) customListenersMap.delete(event);\n },\n invalidate() {\n location.reload();\n },\n data: dataMap.get(ownerPath),\n };\n}\n\nfunction clearCustomListeners(ownerPath) {\n for (const [event, listenersByOwner] of customListenersMap) {\n listenersByOwner.delete(ownerPath);\n if (listenersByOwner.size === 0) customListenersMap.delete(event);\n }\n}\n`\n}\n","// HMR 逻辑 - 文件变更 → 模块失效 → 通知客户端\nimport path from 'node:path'\nimport fs from 'node:fs'\nimport pc from 'picocolors'\nimport type {\n DevServer,\n EnvironmentHotUpdateResult,\n ModuleNode,\n HmrUpdate,\n HmrContext,\n} from '../types.js'\nimport { ModuleGraph } from '../core/module-graph.js'\nimport { findNearestPackageRoot, getLinkedPackageRoots } from './fs-allow.js'\n\nexport async function handleFileChange(\n file: string,\n server: DevServer,\n environmentName = 'client',\n timestamp = Date.now(),\n): Promise<EnvironmentHotUpdateResult | null> {\n const { config } = server\n const environment = server.environments[environmentName]\n if (!environment) {\n throw new Error(`[nasti] unknown dev environment \"${environmentName}\"`)\n }\n const moduleGraph = environment.moduleGraph\n const logger = config.logger\n const relativePath = '/' + path.relative(config.root, file)\n const shortFile = path.relative(config.root, file)\n\n // 找到受影响的模块。watcher 路径与 registerModule 路径在 macOS(/var →\n // /private/var)或 pnpm workspace realpath 后可能不一致,先精确匹配再试\n // realpath。workspace 包经 /@modules 预打包时只登记入口,包内其它文件变更\n // 再回退到同一 package root 下已登记的模块。\n let mods = moduleGraph.getModulesByFile(file)\n if (!mods || mods.size === 0) {\n try {\n const real = fs.realpathSync(file)\n if (real !== file) mods = moduleGraph.getModulesByFile(real)\n if (mods && mods.size > 0) file = real\n } catch {\n /* deleted / dangling */\n }\n }\n if (!mods || mods.size === 0) {\n const packageRoot = findNearestPackageRoot(file)\n if (\n packageRoot &&\n getLinkedPackageRoots(config.root).some(\n (r) => packageRoot === r || packageRoot.startsWith(r + path.sep),\n )\n ) {\n const under = (moduleGraph as ModuleGraph).getModulesWithFileUnder(packageRoot)\n if (under.size > 0) mods = under\n }\n }\n if (!mods || mods.size === 0) {\n return null\n }\n\n const updates: HmrUpdate[] = []\n const graph = moduleGraph as ModuleGraph\n const invalidatedModules = new Set<ModuleNode>()\n const affectedSet = new Set<ModuleNode>()\n let fullReload = false\n\n for (const mod of mods) {\n // importer 也要失效,边界重新导入时才能把变更时间戳传播到依赖 URL。\n graph.invalidateModuleAndImporters(mod, timestamp, invalidatedModules)\n\n // 执行插件的 handleHotUpdate 钩子\n const ctx: HmrContext = {\n file,\n timestamp,\n modules: [mod],\n read: () => fs.readFileSync(file, 'utf-8'),\n server,\n environment,\n }\n\n let affectedModules: ModuleNode[] = [mod]\n for (const plugin of environment.plugins) {\n if (plugin.handleHotUpdate) {\n const result = await plugin.handleHotUpdate(ctx)\n if (result) {\n affectedModules = result\n }\n }\n }\n\n // 检查 HMR 边界\n for (const affected of affectedModules) {\n affectedSet.add(affected)\n graph.invalidateModuleAndImporters(affected, timestamp, invalidatedModules)\n const boundaries = graph.getHmrBoundaries(affected)\n if (boundaries.length === 0) {\n fullReload = true\n continue\n }\n\n for (const { boundary, acceptedVia } of boundaries) {\n const update: HmrUpdate = {\n type: boundary.type === 'css' ? 'css-update' : 'js-update',\n path: boundary.url,\n acceptedPath: acceptedVia.url,\n timestamp,\n }\n if (!updates.some((existing) =>\n existing.type === update.type &&\n existing.path === update.path &&\n existing.acceptedPath === update.acceptedPath\n )) {\n updates.push(update)\n }\n }\n }\n }\n\n const transformed = await Promise.all(\n [...affectedSet].map(async (module) => ({\n module,\n result: await environment.transformRequest(module.url),\n })),\n )\n\n const logPrefix = environmentName === 'client' ? '' : `[${environmentName}] `\n if (fullReload) {\n logger.info(pc.green(`${logPrefix}reload `) + pc.dim(shortFile), { timestamp: true })\n environment.hot.send({ type: 'full-reload', path: relativePath })\n } else if (updates.length > 0) {\n logger.info(\n updates\n .map((u) => pc.green(`${logPrefix}hmr update `) + pc.dim(u.path))\n .join('\\n'),\n { timestamp: true },\n )\n environment.hot.send({ type: 'update', updates })\n }\n\n return {\n environment,\n modules: [...affectedSet],\n updates,\n transformed,\n fullReload,\n }\n}\n","// Dev Server 主逻辑\nimport http from 'node:http'\nimport path from 'node:path'\nimport os from 'node:os'\nimport connect from 'connect'\nimport sirv from 'sirv'\nimport { watch } from 'chokidar'\nimport pc from 'picocolors'\nimport type {\n EnvironmentServeResult,\n NastiConfig,\n ResolvedConfig,\n DevServer,\n} from '../types.js'\nimport { resolveConfig } from '../config/index.js'\nimport { NastiEnvironment } from '../core/environment.js'\nimport { createWsHotChannel } from '../core/hot-channel.js'\nimport { printServerUrls } from '../core/logger.js'\nimport { createWebSocketServer } from './ws.js'\nimport {\n transformMiddleware,\n transformRequest as runTransformRequest,\n type TransformMiddlewareContext,\n} from './middleware.js'\nimport { handleFileChange } from './hmr.js'\nimport { resolvePluginList } from '../plugins/builtins.js'\nimport { getPluginApi } from '../core/plugin-api.js'\nimport { buildEnvDefine, loadEnv, ssrDefineOverrides } from '../core/env.js'\nimport { clearLinkedPackageRootsCache, getLinkedPackageRoots, isUnderRoot } from './fs-allow.js'\n\nexport async function createServer(inlineConfig: NastiConfig = {}): Promise<DevServer> {\n const startTime = performance.now()\n const config = await resolveConfig(inlineConfig, 'serve')\n const logger = config.logger\n\n // 组装内置插件 + 用户插件(per-env 统一拼装函数)\n const allPlugins = resolvePluginList(config, config.plugins, {\n environmentName: 'client',\n })\n const configWithPlugins: ResolvedConfig = { ...config, plugins: allPlugins }\n\n // HTTP 服务\n const app = connect()\n const httpServer = http.createServer(app)\n const ws = createWebSocketServer(httpServer)\n\n // ── Environment API:client 环境承载 dev 运行时(per-env 容器/图/热通道)──\n // ssr 等其余环境:server consumer 的插件列表带 consumer 标记(css 无 DOM stub),\n // 容器在首次使用(ssrLoadModule)时初始化 —— 生命周期钩子默认 client 单次触发。\n const pluginApi = getPluginApi(config)\n const clientEnv = new NastiEnvironment('client', config, {\n hot: createWsHotChannel(ws, 'client'),\n mode: 'dev',\n plugins: allPlugins,\n pluginApi,\n })\n await clientEnv.init()\n const environments: Record<string, NastiEnvironment> = { client: clientEnv }\n for (const name of Object.keys(config.environments)) {\n if (name === 'client') continue\n const consumer = config.environments[name].consumer\n const envPlugins = resolvePluginList(config, config.plugins, {\n consumer,\n environmentName: name,\n })\n environments[name] = new NastiEnvironment(name, config, {\n hot:\n consumer === 'client'\n ? createWsHotChannel(ws, name)\n : undefined,\n mode: 'dev',\n plugins: envPlugins,\n pluginApi,\n })\n }\n for (const [name, environment] of Object.entries(environments)) {\n if (\n name === 'client' ||\n environment.consumer === 'client' ||\n environment.options.driver\n ) {\n await environment.init()\n }\n }\n\n const transformContexts = new Map<string, TransformMiddlewareContext>()\n for (const environment of Object.values(environments)) {\n if (environment.consumer !== 'client' || environment.driver) continue\n const environmentConfig: ResolvedConfig = {\n ...configWithPlugins,\n resolve: environment.options.resolve,\n build: environment.options.build,\n plugins: environment.plugins,\n }\n const context: TransformMiddlewareContext = {\n config: environmentConfig,\n pluginContainer: environment.pluginContainer!,\n moduleGraph: environment.moduleGraph,\n environment,\n envDefine: buildEnvDefine(\n loadEnv(environmentConfig.mode, environmentConfig.root, environmentConfig.envPrefix),\n environmentConfig.mode,\n ssrDefineOverrides(environment.consumer),\n ),\n onPrune: (paths) => environment.hot.send({ type: 'prune', paths }),\n }\n transformContexts.set(environment.name, context)\n environment.configureDevPipeline((url) => runTransformRequest(url, context))\n }\n\n // SSR module runner(懒初始化:仅在 ssrLoadModule 首次调用时建容器/runner)\n let ssrRunner: import('./runnable-environment.js').NastiModuleRunner | null = null\n async function getSsrRunner() {\n if (ssrRunner) return ssrRunner\n const ssrEnv = environments.ssr\n if (!ssrEnv) {\n throw new Error('[nasti] no \"ssr\" environment configured (config.environments.ssr)')\n }\n await ssrEnv.init()\n const { createModuleRunner } = await import('./runnable-environment.js')\n ssrRunner = createModuleRunner(ssrEnv)\n return ssrRunner\n }\n\n const moduleGraph = clientEnv.moduleGraph\n\n // ── 完整打包模式(opt-in,experimental.bundledDev / --bundle)──────────\n // DevEngine 整体打包 client 环境,产物从内存服务;中间件注册在\n // transformMiddleware 之前(接管 '/'、/assets/*、懒编译端点)。\n // unbundled 管线保持默认 —— 不开启时下面这段完全不执行。\n let bundledServer: import('./bundled/dev-engine.js').BundledDevServer | null = null\n if (config.experimental.bundledDev) {\n const { createBundledDevServer } = await import('./bundled/dev-engine.js')\n bundledServer = await createBundledDevServer({\n config: configWithPlugins,\n clientEnv,\n httpServer,\n })\n app.use(bundledServer.middleware)\n }\n\n // 文件监听\n // chokidar v4 不再把 `ignored` 字符串当作 glob 处理,而是按字面值精确匹配\n // (见 chokidar/esm/index.js 的 createPattern),原先的 `**/node_modules/**`\n // 等模式根本不会命中任何路径,导致 watcher 递归进入 node_modules 并对每个\n // 子目录调用 fs.watch,在 macOS 上很快耗尽 fd 触发 EMFILE。改用函数 matcher\n // 显式判定相对段。\n //\n // pnpm/yarn/npm workspaces:直接依赖以 symlink 出现在 node_modules,realpath\n // 落在 apps/web 之外的 packages/*。只 watch config.root 时这些包的改动永远\n // 进不了 HMR —— 把 discover 到的 linked package roots 一并纳入。\n const ignoredSegments = new Set(['node_modules', '.git', '.nasti'])\n const outDirAbs = path.resolve(config.root, config.build.outDir)\n // Skip linked roots that are config.root itself or an ancestor of it — watching\n // those would duplicate (and amplify) the config.root watch tree.\n const linkedPackageRoots = getLinkedPackageRoots(config.root).filter(\n (r) => r !== config.root && !isUnderRoot(config.root, r),\n )\n const watchTargets = [config.root, ...linkedPackageRoots]\n const watcher = watch(watchTargets, {\n ignored: (filePath: string) => {\n if (filePath === outDirAbs || filePath.startsWith(outDirAbs + path.sep)) return true\n for (const watchRoot of watchTargets) {\n if (filePath === watchRoot) return false\n const rel = path.relative(watchRoot, filePath)\n if (!rel || rel.startsWith('..') || path.isAbsolute(rel)) continue\n for (const seg of rel.split(path.sep)) {\n if (ignoredSegments.has(seg)) return true\n }\n return false\n }\n return false\n },\n ignoreInitial: true,\n })\n\n // Wait until the initial scan finishes so getWatched() / unwatch() are usable\n // immediately after createServer resolves (avoids races under parallel tests).\n await new Promise<void>((resolve, reject) => {\n const onReady = () => {\n watcher.off('error', onError)\n resolve()\n }\n const onError = (err: unknown) => {\n watcher.off('ready', onReady)\n reject(err)\n }\n watcher.once('ready', onReady)\n watcher.once('error', onError)\n })\n\n // 先声明 server 变量,再赋值\n let server: DevServer\n const environmentServices: Record<string, EnvironmentServeResult> = {}\n let environmentDriversStarted = false\n let devPipelinesStarted = false\n\n const startDevPipelines = async () => {\n if (devPipelinesStarted) return\n devPipelinesStarted = true\n for (const environment of Object.values(environments)) {\n if (!transformContexts.has(environment.name)) continue\n await environment.pluginContainer!.buildStart()\n }\n }\n\n const logCloseError = (target: string, error: unknown) => {\n const normalized = error instanceof Error ? error : new Error(String(error))\n logger.error(`[nasti] failed to close ${target}`, { error: normalized })\n }\n\n const startEnvironmentDrivers = async () => {\n if (environmentDriversStarted) return\n environmentDriversStarted = true\n const started: Array<{\n name: string\n environment: NastiEnvironment\n service: EnvironmentServeResult\n }> = []\n const attempted: NastiEnvironment[] = []\n try {\n for (const [name, environment] of Object.entries(environments)) {\n if (!environment.driver?.serve) continue\n attempted.push(environment)\n const result = await environment.driver.serve({\n ...environment.getDriverContext(),\n server,\n })\n started.push({ name, environment, service: result ?? {} })\n }\n for (const { name, service } of started) {\n environmentServices[name] = service\n if (service.middleware) app.use(service.middleware)\n }\n } catch (error) {\n environmentDriversStarted = false\n for (const { name } of started) {\n delete environmentServices[name]\n }\n for (const environment of attempted.reverse()) {\n try {\n await environment.driver?.close?.(environment.getDriverContext())\n } catch (closeError) {\n logCloseError(`environment driver \"${environment.driver!.name}\"`, closeError)\n }\n }\n throw error\n }\n }\n\n const notifyEnvironmentDrivers = (\n file: string,\n event: 'add' | 'change' | 'unlink',\n ) => {\n for (const environment of Object.values(environments)) {\n if (!environment.driver?.watchChange) continue\n void Promise.resolve(\n environment.driver.watchChange(file, event, environment.getDriverContext()),\n )\n .catch((error) => {\n logger.error(\n `[nasti] environment driver \"${environment.driver!.name}\" watchChange failed`,\n { error },\n )\n })\n }\n }\n\n const updateClientEnvironments = async (file: string) => {\n const timestamp = Date.now()\n const results: Record<string, NonNullable<Awaited<ReturnType<typeof handleFileChange>>>> = {}\n for (const environment of Object.values(environments)) {\n if (environment.consumer !== 'client' || environment.driver) continue\n try {\n const result = await handleFileChange(file, server, environment.name, timestamp)\n if (result) results[environment.name] = result\n } catch (error) {\n const normalized = error instanceof Error ? error : new Error(String(error))\n logger.error(\n `[nasti] HMR failed for environment \"${environment.name}\": ${normalized.message}`,\n { error: normalized },\n )\n try {\n environment.hot.send({\n type: 'error',\n err: { message: normalized.message, stack: normalized.stack },\n })\n } catch (channelError) {\n const channelFailure =\n channelError instanceof Error\n ? channelError\n : new Error(String(channelError))\n logger.error(\n `[nasti] failed to deliver HMR error to environment \"${environment.name}\"`,\n { error: channelFailure },\n )\n }\n }\n }\n if (Object.keys(results).length === 0) return\n const context = {\n file,\n timestamp,\n environments: Object.freeze({ ...results }),\n server,\n }\n for (const plugin of config.plugins) {\n await plugin.handleHotUpdateApp?.(context)\n }\n }\n\n const queueClientEnvironmentUpdate = (file: string) => {\n void updateClientEnvironments(file).catch((error) => {\n const normalized = error instanceof Error ? error : new Error(String(error))\n logger.error(`[nasti] multi-environment HMR failed: ${normalized.message}`, {\n error: normalized,\n })\n })\n }\n\n watcher.on('change', (file: string) => {\n if (file.includes(`${path.sep}node_modules${path.sep}`) || file.endsWith(`${path.sep}node_modules`)) {\n clearLinkedPackageRootsCache()\n }\n ssrRunner?.invalidateFile(file)\n queueClientEnvironmentUpdate(file)\n notifyEnvironmentDrivers(file, 'change')\n })\n\n watcher.on('add', (file: string) => {\n if (file.includes(`${path.sep}node_modules${path.sep}`) || file.endsWith(`${path.sep}node_modules`)) {\n clearLinkedPackageRootsCache()\n }\n ssrRunner?.invalidateFile(file)\n queueClientEnvironmentUpdate(file)\n notifyEnvironmentDrivers(file, 'add')\n })\n\n watcher.on('unlink', (file: string) => {\n if (file.includes(`${path.sep}node_modules${path.sep}`) || file.endsWith(`${path.sep}node_modules`)) {\n clearLinkedPackageRootsCache()\n }\n ssrRunner?.invalidateFile(file)\n notifyEnvironmentDrivers(file, 'unlink')\n })\n\n server = {\n config: configWithPlugins,\n middlewares: app,\n moduleGraph: moduleGraph as any,\n watcher,\n ws,\n environments,\n environmentServices,\n\n async listen(port?: number) {\n const finalPort = port ?? config.server.port\n const host = config.server.host === true ? '0.0.0.0' : (config.server.host as string)\n\n await startDevPipelines()\n await startEnvironmentDrivers()\n\n return new Promise((resolve, reject) => {\n let currentPort = finalPort\n\n const onListening = () => {\n const actualPort = (httpServer.address() as any)?.port ?? currentPort\n config.server.port = actualPort\n const localUrl = `http://localhost:${actualPort}/`\n const networkUrl = host === '0.0.0.0' ? `http://${getNetworkAddress()}:${actualPort}/` : null\n const driverLocalUrls = Object.values(environmentServices)\n .flatMap((service) => service.localUrls ?? [])\n const driverNetworkUrls = Object.values(environmentServices)\n .flatMap((service) => service.networkUrls ?? [])\n\n logger.clearScreen('info')\n const readyIn = Math.ceil(performance.now() - startTime)\n logger.info(\n `\\n ${pc.cyan(pc.bold('NASTI'))} ${pc.cyan(`v${__NASTI_VERSION__}`)} ${pc.dim('ready in')} ${pc.bold(readyIn)} ${pc.dim('ms')}\\n`,\n )\n printServerUrls(\n {\n local: [localUrl, ...driverLocalUrls],\n network: [...(networkUrl ? [networkUrl] : []), ...driverNetworkUrls],\n },\n logger.info,\n )\n logger.info('')\n\n resolve(server)\n }\n\n httpServer.on('listening', onListening)\n httpServer.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n currentPort++\n logger.info(pc.yellow(`Port ${currentPort - 1} is in use, trying ${currentPort}...`))\n httpServer.listen(currentPort, host)\n } else {\n reject(err)\n }\n })\n\n httpServer.listen(currentPort, host)\n })\n },\n\n async transformRequest(url: string) {\n return clientEnv.transformRequest(url)\n },\n\n async transformEnvironmentRequest(environmentName: string, url: string) {\n const environment = environments[environmentName]\n if (!environment) {\n throw new Error(`[nasti] unknown dev environment \"${environmentName}\"`)\n }\n return environment.transformRequest(url)\n },\n\n async ssrLoadModule(url: string) {\n const runner = await getSsrRunner()\n return runner.import(url)\n },\n\n async close() {\n if (devPipelinesStarted) {\n for (const environment of Object.values(environments).reverse()) {\n if (!transformContexts.has(environment.name)) continue\n await environment.pluginContainer!.buildEnd()\n }\n }\n await bundledServer?.close()\n let environmentCloseFailed = false\n let firstEnvironmentCloseError: unknown\n for (const environment of Object.values(environments).reverse()) {\n try {\n await environment.close()\n } catch (error) {\n if (!environmentCloseFailed) {\n environmentCloseFailed = true\n firstEnvironmentCloseError = error\n }\n logCloseError(`environment \"${environment.name}\"`, error)\n }\n }\n await watcher.close()\n ws.close()\n httpServer.close()\n if (environmentCloseFailed) {\n throw firstEnvironmentCloseError\n }\n },\n }\n\n try {\n await startEnvironmentDrivers()\n } catch (error) {\n if (bundledServer) {\n try {\n await bundledServer.close()\n } catch (closeError) {\n logCloseError('bundled dev server after driver startup failure', closeError)\n }\n }\n try {\n await watcher.close()\n } catch (closeError) {\n logCloseError('file watcher after driver startup failure', closeError)\n }\n try {\n ws.close()\n } catch (closeError) {\n logCloseError('WebSocket server after driver startup failure', closeError)\n }\n try {\n httpServer.close()\n } catch (closeError) {\n logCloseError('HTTP server after driver startup failure', closeError)\n }\n throw error\n }\n\n // 外部环境驱动中间件优先于 Nasti 的转换和静态文件服务。\n app.use(transformMiddleware(transformContexts.get('client')!))\n\n const publicDir = path.resolve(config.root, 'public')\n app.use(sirv(publicDir, { dev: true, etag: true }))\n app.use(sirv(config.root, { dev: true, etag: true }))\n\n // 执行插件的 configureServer 钩子(此时 server 已完全初始化,\n // 插件可安全访问 server.middlewares / server.watcher 等)\n const postMiddlewares: Array<() => void> = []\n for (const plugin of allPlugins) {\n if (plugin.configureServer) {\n const result = await plugin.configureServer(server)\n if (typeof result === 'function') {\n postMiddlewares.push(result)\n }\n }\n }\n // 插件返回的函数会在内置中间件之后执行\n for (const run of postMiddlewares) run()\n\n return server\n}\n\nfunction getNetworkAddress(): string {\n const interfaces = os.networkInterfaces()\n for (const name of Object.keys(interfaces)) {\n for (const iface of interfaces[name] ?? []) {\n if (iface.family === 'IPv4' && !iface.internal) {\n return iface.address\n }\n }\n }\n return 'localhost'\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nasti-toolchain/nasti",
3
- "version": "2.5.0",
3
+ "version": "2.5.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -22,9 +22,17 @@
22
22
  "license": "MIT",
23
23
  "author": "amiya167",
24
24
  "type": "module",
25
+ "packageManager": "pnpm@11.22.0",
25
26
  "engines": {
26
27
  "node": "^20.19.0 || >=22.12.0"
27
28
  },
29
+ "devEngines": {
30
+ "runtime": {
31
+ "name": "node",
32
+ "version": "^22.18.0 || >=24.11.0",
33
+ "onFail": "warn"
34
+ }
35
+ },
28
36
  "exports": {
29
37
  ".": {
30
38
  "import": "./dist/index.js",
@@ -46,20 +54,22 @@
46
54
  "client"
47
55
  ],
48
56
  "scripts": {
49
- "build": "tsup",
50
- "dev": "tsup --watch",
51
- "test": "npm run build && node --test \"test/*.test.mjs\""
57
+ "build": "tsdown",
58
+ "dev": "tsdown --watch",
59
+ "test": "pnpm build && pnpm test:run",
60
+ "test:run": "node --test"
52
61
  },
53
62
  "dependencies": {
54
63
  "cac": "^6.7.14",
55
64
  "chokidar": "^4.0.0",
56
65
  "connect": "^3.7.0",
57
66
  "dotenv": "^16.4.0",
58
- "oxc-parser": "^0.142.0",
59
- "oxc-transform": "^0.142.0",
67
+ "import-meta-resolve": "^4.2.0",
68
+ "oxc-parser": "^0.147.0",
69
+ "oxc-transform": "^0.147.0",
60
70
  "picocolors": "^1.1.0",
61
71
  "react-refresh": "^0.14.2",
62
- "rolldown": "1.2.1",
72
+ "rolldown": "1.2.6",
63
73
  "sirv": "^3.0.0",
64
74
  "source-map-js": "^1.2.1",
65
75
  "ws": "^8.18.0"
@@ -70,8 +80,8 @@
70
80
  "@types/connect": "^3.4.0",
71
81
  "@types/node": "^22.0.0",
72
82
  "@types/ws": "^8.5.0",
73
- "oxc-transform-react": "^0.142.0",
74
- "tsup": "^8.0.0",
83
+ "oxc-transform-react": "^0.147.0",
84
+ "tsdown": "^0.22.14",
75
85
  "typescript": "^5.7.0",
76
86
  "vue": "^3.6.0-rc.2"
77
87
  },
@@ -80,7 +90,7 @@
80
90
  "lightningcss": "^1.32.0"
81
91
  },
82
92
  "peerDependencies": {
83
- "oxc-transform-react": "^0.142.0",
93
+ "oxc-transform-react": "^0.147.0",
84
94
  "react-server-dom-webpack": "^19.0.0"
85
95
  },
86
96
  "peerDependenciesMeta": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../client/hmr.ts"],"sourcesContent":["// Nasti HMR 浏览器客户端\n// 此文件会被内联到 Dev Server 中间件返回给浏览器\n\nexport interface HotModule {\n accept(cb?: (mod: any) => void): void\n accept(dep: string, cb: (mod: any) => void): void\n accept(deps: string[], cb: (mods: any[]) => void): void\n dispose(cb: (data: Record<string, any>) => void | Promise<void>): void\n prune(cb: (data: Record<string, any>) => void | Promise<void>): void\n invalidate(message?: string): void\n data: Record<string, any>\n}\n\ndeclare global {\n interface ImportMeta {\n hot?: HotModule\n }\n}\n\nexport {}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}