@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.
- package/README.md +34 -2
- package/dist/build-CENae4VM.js +748 -0
- package/dist/build-CENae4VM.js.map +1 -0
- package/dist/build-vjh6h7PB.cjs +786 -0
- package/dist/build-vjh6h7PB.cjs.map +1 -0
- package/dist/cli.cjs +166 -7608
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +1 -2
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +166 -7606
- package/dist/cli.js.map +1 -1
- package/dist/client/hmr.cjs +0 -19
- package/dist/client/hmr.d.cts +14 -12
- package/dist/client/hmr.d.cts.map +1 -0
- package/dist/client/hmr.d.ts +14 -12
- package/dist/client/hmr.d.ts.map +1 -0
- package/dist/client/hmr.js +1 -1
- package/dist/dev-engine-DJL9sfv5.cjs +473 -0
- package/dist/dev-engine-DJL9sfv5.cjs.map +1 -0
- package/dist/dev-engine-DapuTPIz.js +469 -0
- package/dist/dev-engine-DapuTPIz.js.map +1 -0
- package/dist/electron-Bj8H-BJ6.js +278 -0
- package/dist/electron-Bj8H-BJ6.js.map +1 -0
- package/dist/electron-D0PSXz-a.cjs +316 -0
- package/dist/electron-D0PSXz-a.cjs.map +1 -0
- package/dist/electron-dev-BzI2IFnR.cjs +272 -0
- package/dist/electron-dev-BzI2IFnR.cjs.map +1 -0
- package/dist/electron-dev-CM15gsFp.js +251 -0
- package/dist/electron-dev-CM15gsFp.js.map +1 -0
- package/dist/env-GY7K1zPK.js +833 -0
- package/dist/env-GY7K1zPK.js.map +1 -0
- package/dist/env-lOj3yw8v.cjs +924 -0
- package/dist/env-lOj3yw8v.cjs.map +1 -0
- package/dist/environment-B2jCrhY2.js +1361 -0
- package/dist/environment-B2jCrhY2.js.map +1 -0
- package/dist/environment-CjmvoHIG.cjs +1443 -0
- package/dist/environment-CjmvoHIG.cjs.map +1 -0
- package/dist/index.cjs +453 -7976
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +872 -817
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +872 -817
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +418 -7939
- package/dist/index.js.map +1 -1
- package/dist/logger-BVZwdqqT.js +116 -0
- package/dist/logger-BVZwdqqT.js.map +1 -0
- package/dist/logger-M7AuVVTV.cjs +171 -0
- package/dist/logger-M7AuVVTV.cjs.map +1 -0
- package/dist/runnable-environment-BjoOvdDa.js +1345 -0
- package/dist/runnable-environment-BjoOvdDa.js.map +1 -0
- package/dist/runnable-environment-ByA3DHQ6.cjs +1351 -0
- package/dist/runnable-environment-ByA3DHQ6.cjs.map +1 -0
- package/dist/server-Bqgl25z0.js +1871 -0
- package/dist/server-Bqgl25z0.js.map +1 -0
- package/dist/server-BynlMdFc.cjs +1895 -0
- package/dist/server-BynlMdFc.cjs.map +1 -0
- package/package.json +20 -10
- package/dist/client/hmr.cjs.map +0 -1
- package/dist/client/hmr.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment-CjmvoHIG.cjs","names":["pc","debug","createRequire","path","pathToFileURL","SourceMapGenerator","path","path","fs","crypto","debug","SourceNode","SourceMapConsumer","transformCode","SourceMapGenerator","crypto","path","fs","resolvePlugin","orderPlugins","getPluginApi"],"sources":["../src/core/debug.ts","../src/core/css-engine.ts","../src/plugins/tailwind.ts","../src/plugins/css.ts","../src/plugins/css-post.ts","../src/plugins/assets.ts","../src/plugins/vue.ts","../src/plugins/html.ts","../src/plugins/builtins.ts","../src/core/plugin-container.ts","../src/core/url.ts","../src/core/module-graph.ts","../src/core/hot-channel.ts","../src/core/environment.ts"],"sourcesContent":["// Debug - DEBUG 环境变量驱动的命名空间调试输出(仿 Vite createDebugger)\n// 用法:DEBUG=nasti:* nasti dev;NASTI_DEBUG_FILTER=foo 进一步按内容过滤\nimport pc from 'picocolors'\n\nexport type NastiDebugScope = `nasti:${string}`\n\ninterface DebuggerOptions {\n /** 仅当 DEBUG 精确包含该命名空间(而非 nasti:* 通配)时才启用 */\n onlyWhenFocused?: boolean | string\n}\n\nconst DEBUG = process.env.DEBUG\n// 同时认 vite:* —— 方便移植 Vite 插件/工作流时直接复用已有的 DEBUG 习惯\nconst filter = process.env.NASTI_DEBUG_FILTER || process.env.VITE_DEBUG_FILTER\n\nexport function createDebugger(\n namespace: NastiDebugScope,\n options: DebuggerOptions = {},\n): ((...args: unknown[]) => void) | undefined {\n if (!DEBUG) return undefined\n\n const patterns = DEBUG.split(',').map((p) => p.trim())\n const enabled = patterns.some((p) => {\n if (p === '*' || p === 'nasti:*' || p === 'vite:*') return true\n // 把 vite:xxx 映射到 nasti:xxx,兼容移植的调试习惯\n const normalized = p.startsWith('vite:') ? `nasti:${p.slice(5)}` : p\n return normalized === namespace\n })\n if (!enabled) return undefined\n\n if (options.onlyWhenFocused) {\n const focus =\n typeof options.onlyWhenFocused === 'string'\n ? options.onlyWhenFocused\n : namespace\n if (!patterns.includes(focus)) return undefined\n }\n\n let lastTime = performance.now()\n return (...args: unknown[]) => {\n const now = performance.now()\n const elapsed = now - lastTime\n lastTime = now\n const msg = args\n .map((a) => {\n if (typeof a === 'string') return a\n // JSON.stringify 在循环引用 / BigInt 上会抛 —— 调试输出绝不能反过来\n // 中断主流程,故 try/catch 回退到 String()\n try {\n return JSON.stringify(a)\n } catch {\n return String(a)\n }\n })\n .join(' ')\n if (filter && !msg.includes(filter)) return\n console.debug(\n `${pc.magenta(namespace)} ${msg} ${pc.dim(`+${Math.round(elapsed)}ms`)}`,\n )\n }\n}\n","// CSS 引擎 - build 期 per-chunk CSS 抽取的共享状态与工具\n//\n// 架构(NASTI_2.0_PLAN.md §2.2):\n// compile 阶段(plugins/css.ts) :Tailwind 编译 + url() 重写,把 CSS 字符串\n// 按规范化模块 id 注册进 styles Map,向\n// bundler 返回空 JS stub(moduleType:'js',\n// Rolldown 1.x 移除了原生 CSS 打包,见 #4271)\n// css-post 阶段(plugins/css-post.ts):renderChunk 按 chunk.moduleIds 聚合\n// CSS、压缩、emitFile 产出带 hash 的 .css\n//\n// 压缩器是 Lightning CSS(守卫导入,可选依赖)—— 这是相对 Vite 默认\n// (PostCSS 转换器 + Lightning 压缩器)的有意分歧:纯 Rust、依赖更小。\n// 不可用时回退到保守的正则压缩。\nimport type {\n EnvironmentCssMetadata,\n EnvironmentCssModule,\n ResolvedConfig,\n} from '../types.js'\nimport { createDebugger } from './debug.js'\n\nconst debug = createDebugger('nasti:css')\n\nexport interface CssEngine {\n /** 规范化模块 id → 编译后的 CSS 字符串 */\n styles: Map<string, string>\n /** 规范化模块 id → 原始与编译后 CSS,供工具链直接消费。 */\n modules: Map<string, EnvironmentCssModule>\n /** chunk fileName → CSS 模块与最终文件所有权。 */\n chunks: Map<string, { moduleIds: string[]; cssFileNames: string[] }>\n /** entry chunk 的 facadeModuleId → 抽出的 css 文件名(用于 HTML <link> 注入) */\n entryCss: Map<string, string[]>\n /** 全部已 emit 的 css 文件名(按 render 顺序) */\n allCss: string[]\n /** cssCodeSplit:false 时的跨 chunk 累积(按 renderChunk 顺序) */\n pendingSingle: string[]\n /** cssCodeSplit:false 时最终单文件名 */\n singleFileName: string | null\n}\n\nexport function createCssEngine(): CssEngine {\n return {\n styles: new Map(),\n modules: new Map(),\n chunks: new Map(),\n entryCss: new Map(),\n allCss: [],\n pendingSingle: [],\n singleFileName: null,\n }\n}\n\nexport function getCssMetadata(engine: CssEngine): EnvironmentCssMetadata {\n return {\n modules: Object.fromEntries(\n [...engine.modules].map(([id, module]) => [id, { ...module }]),\n ),\n chunks: Object.fromEntries(\n [...engine.chunks].map(([fileName, chunk]) => [\n fileName,\n {\n fileName,\n moduleIds: [...chunk.moduleIds],\n cssFileNames: [...chunk.cssFileNames],\n },\n ]),\n ),\n }\n}\n\n/**\n * 规范化模块 id:去掉 Rolldown 虚拟模块的 null-byte 前缀。\n * **保留 query** —— Vue style 子块(`App.vue?vue&type=style&...&lang.css`)与\n * 父模块 `App.vue` 是不同模块,剥 query 会让二者 key 撞车导致 CSS 重复输出。\n * chunk.moduleIds 里的 id 必须与 transform 期注册的 key 一致 —— 两侧都过这个函数。\n */\nexport function normalizeCssModuleId(id: string): string {\n return id.startsWith('\\0') ? id.slice(1) : id\n}\n\nlet lightningCss: typeof import('lightningcss') | null | undefined\n\n/**\n * 压缩 CSS:优先 Lightning CSS(守卫导入),不可用时回退正则压缩。\n * Tailwind v4 的输出已自行 flatten @import,这里不做 @import 解析。\n */\nexport async function minifyCss(css: string, config: ResolvedConfig): Promise<string> {\n if (lightningCss === undefined) {\n try {\n lightningCss = await import('lightningcss')\n } catch {\n lightningCss = null\n debug?.('lightningcss unavailable, falling back to regex minifier')\n }\n }\n if (lightningCss) {\n try {\n const result = lightningCss.transform({\n filename: 'bundle.css',\n code: Buffer.from(css),\n minify: true,\n // 不展开 @import(Tailwind 已 flatten;裸 @import 保留原样交给浏览器)\n errorRecovery: true,\n })\n for (const w of result.warnings ?? []) {\n config.logger.warnOnce(`[nasti:css] ${w.message}`)\n }\n return result.code.toString()\n } catch (err: any) {\n config.logger.warnOnce(\n `[nasti:css] Lightning CSS minify failed (${err.message}), emitting unminified CSS`,\n )\n return css\n }\n }\n return fallbackMinify(css)\n}\n\n/** 保守的正则压缩:去注释、压空白。不做任何结构性变换。 */\nfunction fallbackMinify(css: string): string {\n return css\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n // 仅折叠结构性标点周围的空白;不碰 + > ~ —— 它们在 calc()(`1 + 2`)\n // 与选择器组合符里语义敏感,去空格会产出非法 CSS\n .replace(/\\s*([{}:;,])\\s*/g, '$1')\n .replace(/;}/g, '}')\n .replace(/\\s+/g, ' ')\n .trim()\n}\n","// Tailwind v4 integration: when a stylesheet contains v4 directives\n// (`@import \"tailwindcss\"`, `@theme`, `@apply`, `@plugin`, `@source`,\n// `@utility`, `@variant`, `@custom-variant`, `@reference`, or `@tailwind`),\n// we hand the entire CSS to `@tailwindcss/node`'s `compile()` (which\n// internally resolves all `@import`s, including bare specifiers like\n// `@heroui/styles`) and then scan the project for candidate utilities via\n// `@tailwindcss/oxide`. Both packages are resolved from the project's own\n// `node_modules` — they are optional peer dependencies of Nasti.\nimport path from 'node:path'\nimport { createRequire } from 'node:module'\nimport { pathToFileURL } from 'node:url'\n\n// Matches the documented v4 at-rules. `@import \"tailwindcss...\"` is enough\n// to trigger the full pipeline; the other directives are recognized as a\n// safety net for stylesheets that bring their own preflight / utilities\n// scaffolding without going through the canonical entry.\nconst TAILWIND_DIRECTIVE_RE =\n /@(?:import\\s+[\"']tailwindcss(?:\\b|\\/)|tailwind\\b|theme\\b|apply\\b|plugin\\b|source\\b|utility\\b|variant\\b|custom-variant\\b|reference\\b)/\n\nexport function hasTailwindDirectives(css: string): boolean {\n // Strip comments to avoid false positives from commented-out directives\n const withoutBlockComments = css.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n const withoutLineComments = withoutBlockComments.replace(/\\/\\/.*$/gm, '')\n return TAILWIND_DIRECTIVE_RE.test(withoutLineComments)\n}\n\ntype SourceEntry = { base: string; pattern: string; negated: boolean }\n\ntype TailwindModules = {\n node: {\n compile(\n css: string,\n options: { base: string; from: string; onDependency: (p: string) => void },\n ): Promise<{ sources: SourceEntry[]; build(candidates: string[]): string }>\n }\n oxide: {\n Scanner: new (options: { sources?: SourceEntry[] }) => {\n scan(): string[]\n files: string[]\n }\n }\n}\n\nlet cached: TailwindModules | null = null\nlet cachedRoot: string | null = null\n\nasync function loadTailwind(projectRoot: string): Promise<TailwindModules> {\n if (cached && cachedRoot === projectRoot) return cached\n // createRequire anchored at a *file* under the project root, otherwise\n // Node interprets `projectRoot` as a parent directory and resolution\n // walks outside the project's node_modules.\n const req = createRequire(path.join(projectRoot, 'package.json'))\n let nodePath: string\n let oxidePath: string\n try {\n nodePath = req.resolve('@tailwindcss/node')\n oxidePath = req.resolve('@tailwindcss/oxide')\n } catch {\n throw new Error(\n '[nasti] CSS contains Tailwind v4 directives but `@tailwindcss/node` ' +\n 'and/or `@tailwindcss/oxide` are not installed in this project. ' +\n 'Install them with: npm i -D tailwindcss @tailwindcss/node @tailwindcss/oxide',\n )\n }\n const node = (await import(pathToFileURL(nodePath).href)) as TailwindModules['node']\n const oxide = (await import(pathToFileURL(oxidePath).href)) as TailwindModules['oxide']\n cached = { node, oxide }\n cachedRoot = projectRoot\n return cached\n}\n\nexport type TailwindCompileResult = {\n css: string\n dependencies: string[]\n}\n\nexport async function compileTailwind(\n css: string,\n fromFile: string,\n projectRoot: string,\n): Promise<TailwindCompileResult> {\n const { node, oxide } = await loadTailwind(projectRoot)\n\n const dependencies: string[] = []\n const compiler = await node.compile(css, {\n base: path.dirname(fromFile),\n from: fromFile,\n onDependency: (p: string) => dependencies.push(p),\n })\n\n // Tailwind reports the source roots it wants scanned for class candidates\n // (driven by the implicit project root for `@import \"tailwindcss\"` and by\n // any explicit `@source` directives). We forward them verbatim to the\n // oxide scanner.\n const scanner = new oxide.Scanner({ sources: compiler.sources })\n const candidates = scanner.scan()\n\n return {\n css: compiler.build(candidates),\n dependencies: [...dependencies, ...scanner.files],\n }\n}\n","// CSS 处理插件 - 处理 .css 导入\n//\n// dev:编译后注入可热更新的 <style>(行为与 1.x 完全一致)\n// build:compile 阶段 —— 编译 + url() 重写后把 CSS 注册进 CssEngine,\n// 向 Rolldown 返回空 JS stub(moduleType:'js',规避 rolldown#4271\n// 移除原生 CSS 打包后的报错;no-treeshake 保证模块留在 chunk.moduleIds\n// 里供 css-post 的 renderChunk 聚合)。真正的 .css 产物由\n// plugins/css-post.ts 在 renderChunk 期 per-chunk 抽取。\nimport path from 'node:path'\nimport { SourceMapGenerator } from 'source-map-js'\nimport type { NastiPlugin, ResolvedConfig } from '../types.js'\nimport type { CssEngine } from '../core/css-engine.js'\nimport { normalizeCssModuleId } from '../core/css-engine.js'\nimport { compileTailwind, hasTailwindDirectives } from './tailwind.js'\n\nexport function cssPlugin(\n config: ResolvedConfig,\n engine?: CssEngine,\n consumer: 'client' | 'server' = 'client',\n): NastiPlugin {\n return {\n name: 'nasti:css',\n\n resolveId(source) {\n if (source.endsWith('.css')) return null // 交给 resolve 插件处理\n return null\n },\n\n async transform(code, id) {\n // 匹配 .css 文件与 .css 结尾的虚拟模块(如 Vue style 子块\n // `App.vue?vue&type=style&index=0&lang.css`);?raw / ?url 交给 assets 插件\n const [file, query = ''] = id.split('?', 2)\n const isCssRequest = file.endsWith('.css') || /\\.css$/.test(id)\n if (!isCssRequest) return null\n if (query === 'raw' || query === 'url') return null\n\n // Tailwind v4: when the stylesheet uses any v4 directive, hand the\n // entire source to Tailwind. Tailwind's own compiler resolves all\n // `@import`s (including bare specifiers like `@heroui/styles`), runs\n // the oxide scanner to discover utility candidates, and emits a\n // fully-flattened stylesheet — which is exactly what the browser\n // needs when we inline the result into a `<style>` tag below.\n let cssSource = code\n if (hasTailwindDirectives(code)) {\n const compiled = await compileTailwind(code, id, config.root)\n cssSource = compiled.css\n }\n\n // 将 CSS 中的相对 url() 路径重写为绝对路径,确保打包后资源路径正确\n const rewritten = rewriteCssUrls(cssSource, file, config.root)\n const escaped = JSON.stringify(rewritten)\n const normalizedId = normalizeCssModuleId(id)\n const cssModule = { id: normalizedId, source: code, code: rewritten }\n const map = config.build.sourcemap\n ? createIdentitySourceMap(code, id)\n : undefined\n engine?.modules.set(normalizedId, cssModule)\n this.environment?.setCssModule?.(cssModule)\n\n // ?inline:只要编译后的字符串,不注入、不抽取(dev/build 行为一致)\n if (query === 'inline') {\n return { code: `export default ${escaped};\\n`, map, moduleType: 'js' }\n }\n\n // server consumer(SSR dev/build、Electron main/preload):无 DOM 环境,\n // 返回 CSS 字符串导出(SSR 可收集),真实 .css 产物由 client 环境负责\n if (consumer === 'server') {\n return { code: `export default ${escaped};\\n`, map, moduleType: 'js' }\n }\n\n if (config.command === 'serve') {\n if (config.build.css.inject === false) {\n return {\n code: `export default ${escaped};\\n`,\n map,\n moduleType: 'js',\n moduleSideEffects: 'no-treeshake',\n }\n }\n // Dev 模式: 注入可热更新的 <style> 标签\n return {\n code: `\nconst css = ${escaped};\nconst __nasti_css_id__ = ${JSON.stringify(id)};\nconst __nasti_existing__ = document.querySelector('style[data-nasti-css=' + JSON.stringify(__nasti_css_id__) + ']');\nif (__nasti_existing__) __nasti_existing__.remove();\nconst style = document.createElement('style');\nstyle.setAttribute('data-nasti-css', __nasti_css_id__);\nstyle.textContent = css;\ndocument.head.appendChild(style);\n\n// HMR(prune 在 bundled 模式的 rolldown hot context 上不存在,须守卫)\nif (import.meta.hot) {\n import.meta.hot.accept();\n if (import.meta.hot.prune) {\n import.meta.hot.prune(() => {\n style.remove();\n });\n }\n}\n\nexport default css;\n`,\n map,\n // bundled dev(DevEngine)下该模块会进 Rolldown:不标 js 会按 .css\n // 扩展名走 CSS 管线触发 #4271 报错;unbundled 中间件忽略此字段\n moduleType: 'js',\n }\n }\n\n // Build 模式:注册进 CssEngine,由 css-post 在 renderChunk 抽取为\n // 带 hash 的 .css 文件。返回空 stub —— CSS 文本不再进 JS bundle\n // (1.x 是运行时 <style>/<link> 注入 + export default css 字符串,\n // 体积双份;`import css from './x.css'` 现在得到 '',需要字符串请用\n // `?inline`,与 Vite 语义一致)。\n if (engine) {\n engine.styles.set(normalizedId, rewritten)\n return {\n code: `export default '';\\n`,\n map,\n moduleType: 'js',\n // 防止空 stub 被 tree-shake 出 chunk.moduleIds(css-post 靠它定位)\n moduleSideEffects: 'no-treeshake',\n }\n }\n\n // 无 engine(理论上只有未迁移的调用方):保留 1.x 运行时注入兜底\n const cssConfig = config.build.css || {}\n const nonce = cssConfig.nonce\n const nonceAttr = nonce ? `style.setAttribute('nonce', ${JSON.stringify(nonce)});` : ''\n return {\n code: `\nconst css = ${escaped};\nconst style = document.createElement('style');\nstyle.setAttribute('data-nasti-css', ${JSON.stringify(id)});\n${nonceAttr}\nstyle.textContent = css;\ndocument.head.appendChild(style);\n\nexport default css;\n`,\n map,\n moduleType: 'js',\n }\n },\n }\n}\n\nfunction createIdentitySourceMap(code: string, id: string) {\n const map = new SourceMapGenerator({ file: id })\n const lines = code.split('\\n')\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n for (let column = 0; column <= lines[lineIndex].length; column++) {\n map.addMapping({\n generated: { line: lineIndex + 1, column },\n original: { line: lineIndex + 1, column },\n source: id,\n })\n }\n }\n map.setSourceContent(id, code)\n return map.toJSON()\n}\n\n/** CSS URL 重写(将相对路径转为绝对路径) */\nexport function rewriteCssUrls(css: string, from: string, root: string): string {\n return css.replace(/url\\(\\s*['\"]?([^'\")\\s]+)['\"]?\\s*\\)/g, (match, url: string) => {\n // 跳过绝对路径、data URI、http(s) URL\n if (url.startsWith('/') || url.startsWith('data:') || url.startsWith('http')) {\n return match\n }\n const resolved = path.resolve(path.dirname(from), url)\n // path.relative 在 Windows 上产出反斜杠 —— URL 必须用 POSIX 分隔符\n const relative = '/' + path.relative(root, resolved).replace(/\\\\/g, '/')\n return `url(${relative})`\n })\n}\n","// CSS post 插件 - build 期 per-chunk CSS 抽取(NASTI_2.0_PLAN.md §2.2)\n//\n// renderChunk 在 Rolldown 真实插件上下文中运行(经 build/index.ts 转发表),\n// this.emitFile({type:'asset'}) 经 output.assetFileNames 产出带 hash 的 .css,\n// this.getFileName(ref) 立即可解析最终文件名(asset hash 由内容决定,与 chunk\n// hash 无关,因此 renderChunk 期即可取得)。\n//\n// - entry chunk:css 文件名记入 engine.entryCss,由 build/index.ts 注入静态\n// <link rel=\"stylesheet\"> 到 index.html\n// - 动态 chunk:在 chunk 代码\"尾部\"追加幂等的运行时 <link> 注入片段\n// (追加而非前置 —— 保持原代码行号,sourcemap 仍然对齐;FOUC 窗口已知,\n// Phase 3 的打包模式会换 DevEngine 路径)\n// - augmentChunkHash 把 chunk 关联的 CSS 内容折进 JS chunk hash(缓存正确性)\nimport type { RenderedChunk } from 'rolldown'\nimport type { NastiPlugin, ResolvedConfig } from '../types.js'\nimport { type CssEngine, normalizeCssModuleId, minifyCss } from '../core/css-engine.js'\n\n/** 按 chunk 模块执行顺序聚合该 chunk 的 CSS(id 两侧都已规范化) */\nfunction collectChunkCss(\n chunk: RenderedChunk,\n engine: CssEngine,\n): { css: string; moduleIds: string[] } {\n const ids = chunk.moduleIds ?? Object.keys(chunk.modules)\n let css = ''\n const moduleIds: string[] = []\n for (const id of ids) {\n const normalizedId = normalizeCssModuleId(id)\n const styles = engine.styles.get(normalizedId)\n if (styles) {\n css += styles + '\\n'\n moduleIds.push(normalizedId)\n }\n }\n return { css, moduleIds }\n}\n\nexport function cssPostPlugin(config: ResolvedConfig, engine: CssEngine): NastiPlugin {\n return {\n name: 'nasti:css-post',\n enforce: 'post',\n\n async renderChunk(code, chunk) {\n const { css, moduleIds } = collectChunkCss(chunk, engine)\n if (!css) return null\n const ownership = { moduleIds, cssFileNames: [] as string[] }\n engine.chunks.set(chunk.fileName, ownership)\n\n if (config.build.css.emit === false) return null\n\n // 单文件模式:跨 chunk 累积,generateBundle 一次性 emit\n if (!config.build.cssCodeSplit) {\n engine.pendingSingle.push(css)\n return null\n }\n\n const finalCss = config.build.cssMinify ? await minifyCss(css, config) : css\n const ref = this.emitFile({\n type: 'asset',\n name: `${chunk.name}.css`,\n source: finalCss,\n })\n const fileName = this.getFileName(ref)\n engine.allCss.push(fileName)\n ownership.cssFileNames.push(fileName)\n\n if (chunk.isEntry) {\n const key = chunk.facadeModuleId ?? chunk.name\n const existing = engine.entryCss.get(key) ?? []\n existing.push(fileName)\n engine.entryCss.set(key, existing)\n return null\n }\n\n // 动态 chunk:运行时注入 <link>(幂等,data-nasti-css 标记去重)\n if (config.build.css.inject === false) return null\n\n const href = JSON.stringify(config.base + fileName)\n const snippet =\n `\\n;(function(){try{var d=document,h=${href};` +\n `if(!d.querySelector('link[data-nasti-css=\"'+h+'\"]')){` +\n `var l=d.createElement('link');l.rel='stylesheet';l.href=h;` +\n `l.setAttribute('data-nasti-css',h);d.head.appendChild(l);}}catch(e){}})();`\n return { code: code + snippet, map: null }\n },\n\n augmentChunkHash(chunk) {\n // CSS 内容变 → JS chunk hash 变(动态 chunk 的注入 URL、缓存失效正确性)\n const { css } = collectChunkCss(chunk, engine)\n return css || undefined\n },\n\n async generateBundle() {\n if (config.build.cssCodeSplit || engine.pendingSingle.length === 0) return\n const merged = engine.pendingSingle.join('\\n')\n const finalCss = config.build.cssMinify ? await minifyCss(merged, config) : merged\n const ref = this.emitFile({ type: 'asset', name: 'style.css', source: finalCss })\n const fileName = this.getFileName(ref)\n engine.singleFileName = fileName\n engine.allCss.push(fileName)\n for (const ownership of engine.chunks.values()) {\n if (ownership.moduleIds.length > 0) ownership.cssFileNames.push(fileName)\n }\n },\n }\n}\n","// 静态资源处理插件 - 图片、字体等\nimport path from 'node:path'\nimport fs from 'node:fs'\nimport crypto from 'node:crypto'\nimport type { NastiPlugin, ResolvedConfig } from '../types.js'\n\nconst ASSET_EXTENSIONS = new Set([\n '.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico', '.webp', '.avif',\n '.mp4', '.webm', '.ogg', '.mp3', '.wav', '.flac', '.aac',\n '.woff', '.woff2', '.eot', '.ttf', '.otf',\n '.pdf', '.txt',\n])\n\nexport function assetsPlugin(config: ResolvedConfig): NastiPlugin {\n const emittedAssets = new Set<string>()\n\n return {\n name: 'nasti:assets',\n\n resolveId(source) {\n // 处理 ?url 和 ?raw 后缀\n if (source.endsWith('?url') || source.endsWith('?raw')) {\n return source\n }\n return null\n },\n\n load(id) {\n const ext = path.extname(id.replace(/\\?.*$/, ''))\n\n // ?raw 查询: 返回文件原始内容\n if (id.endsWith('?raw')) {\n const file = id.slice(0, -4)\n if (fs.existsSync(file)) {\n const content = fs.readFileSync(file, 'utf-8')\n return `export default ${JSON.stringify(content)}`\n }\n }\n\n // ?url 查询或静态资源扩展名: 返回 URL\n if (id.endsWith('?url') || ASSET_EXTENSIONS.has(ext)) {\n const file = id.replace(/\\?.*$/, '')\n if (!fs.existsSync(file)) return null\n\n if (config.command === 'serve') {\n // Dev 模式: 返回相对于 root 的路径\n const url = '/' + path.relative(config.root, file)\n return `export default ${JSON.stringify(url)}`\n }\n\n // Build 模式: 计算内容哈希用于文件名\n const content = fs.readFileSync(file)\n const hash = crypto.createHash('sha256').update(content).digest('hex').slice(0, 8)\n const basename = path.basename(file, ext)\n const hashedName = `${config.build.assetsDir}/${basename}.${hash}${ext}`\n const environment = this.environment\n if (!environment) {\n throw new Error('[nasti:assets] build environment is not initialized')\n }\n if (!emittedAssets.has(hashedName)) {\n this.emitFile({\n type: 'asset',\n fileName: hashedName,\n source: content,\n })\n emittedAssets.add(hashedName)\n }\n environment.setAssetModule(file, hashedName)\n return `export default ${JSON.stringify(config.base + hashedName)}`\n }\n\n return null\n },\n }\n}\n\nexport function isAssetFile(id: string): boolean {\n const ext = path.extname(id.replace(/\\?.*$/, ''))\n return ASSET_EXTENSIONS.has(ext)\n}\n","// 内置 Vue 插件 - SFC 编译 + Vue HMR(含 Vue 3.6 Vapor Mode 测试版)\nimport crypto from 'node:crypto'\nimport type {\n NastiPlugin,\n ResolvedConfig,\n VueEnvironmentOptions,\n VueSfcSourceTransform,\n VueSfcTransformContext,\n} from '../types.js'\nimport {\n SourceMapConsumer,\n SourceMapGenerator,\n SourceNode,\n type RawSourceMap,\n} from 'source-map-js'\nimport { transformCode } from '../core/transformer.js'\nimport { createDebugger } from '../core/debug.js'\n\nconst VUE_FILE_RE = /\\.vue$/\n// 同时接受 2.0 的 `&lang.css`(Vite 约定,id 以 .css 结尾可被 css 插件接管)\n// 与 1.x 的 `&lang=css`(向后兼容已缓存的 URL)\nconst VUE_QUERY_RE = /\\.vue\\?vue&type=(script|template|style)(&index=\\d+)?(&lang[.=]\\w+)?/\nconst debug = createDebugger('nasti:vue')\n\n/** Vapor Mode 测试版免责声明:终端与浏览器控制台共用同一文案 */\nexport const VAPOR_BETA_WARNING =\n 'Vapor Mode is a beta feature; Zixiao Labs and the Vue team do not provide guarantees against crashes in production environments, and it is not suitable for server-side rendering environments.'\n\ninterface VueCompilerSfc {\n parse: (source: string, options?: any) => any\n compileScript: (sfc: any, options: any) => any\n compileTemplate: (options: any) => any\n compileStyleAsync: (options: any) => Promise<any>\n version?: string\n}\n\nlet compiler: VueCompilerSfc | null = null\n\nasync function loadVueCompiler(): Promise<VueCompilerSfc | null> {\n if (compiler) return compiler\n try {\n compiler = await import('@vue/compiler-sfc')\n return compiler\n } catch {\n return null\n }\n}\n\nexport function vuePlugin(\n config: ResolvedConfig,\n environmentName = 'client',\n): NastiPlugin {\n const isDev = config.command === 'serve'\n const descriptorCache = new Map<\n string,\n { descriptor: any; sourceMap?: unknown }\n >()\n const vueOptions = config.environments[environmentName]?.vue ?? {}\n\n return {\n name: 'nasti:vue',\n enforce: 'pre',\n\n async resolveId(source) {\n // 处理 .vue 虚拟模块请求 (?vue&type=...)\n if (VUE_QUERY_RE.test(source)) {\n return source\n }\n return null\n },\n\n // 虚拟子模块必须有 load 钩子:build 下 Rolldown 否则会按字面路径读盘,\n // 抛 UNLOADABLE_DEPENDENCY(1.x Vue 生产构建因此直接失败)。\n // style 子块在这里编译成 CSS 字符串,交给 css 插件统一处理\n // (dev = <style> 注入 + HMR;build = CssEngine 抽取成 hashed .css)。\n async load(id) {\n const match = id.match(/(.+\\.vue)\\?vue&type=style(?:&index=(\\d+))?/)\n if (!match) return null\n\n const sfc = await loadVueCompiler()\n if (!sfc) return null\n\n const [, filePath, indexStr] = match\n let cached = descriptorCache.get(filePath)\n if (!cached) {\n // 直接请求子模块(如 dev 冷启动 / 缓存失效)时按需重新解析父 SFC\n try {\n const fs = await import('node:fs')\n const rawSource = fs.readFileSync(filePath, 'utf-8')\n const transformedSfc = await applySourceTransform(\n vueOptions.transformSfc,\n rawSource,\n { filename: filePath, environmentName, type: 'sfc' },\n )\n const parsed = sfc.parse(transformedSfc.code, {\n ...vueOptions.parse,\n filename: filePath,\n sourceMap: true,\n })\n if (parsed.errors.length) return null\n cached = {\n descriptor: parsed.descriptor,\n sourceMap: transformedSfc.map,\n }\n descriptorCache.set(filePath, cached)\n } catch {\n return null\n }\n }\n\n const { descriptor, sourceMap: sfcSourceMap } = cached\n const index = parseInt(indexStr ?? '0', 10)\n const style = descriptor.styles[index]\n if (!style) return null\n\n const scopeId = hashId(filePath)\n const transformedStyle = await applySourceTransform(\n vueOptions.transformStyle,\n style.content,\n { filename: filePath, environmentName, type: 'style', index },\n )\n const wantsStyleSourceMap =\n !!config.build.sourcemap ||\n transformedStyle.map != null ||\n sfcSourceMap != null\n const styleInputMap = wantsStyleSourceMap\n ? composeSourceMapChain(\n [transformedStyle.map, style.map, sfcSourceMap],\n { filename: filePath, environmentName, type: 'style', index },\n )\n : undefined\n const result = await sfc.compileStyleAsync({\n ...vueOptions.style,\n source: transformedStyle.code,\n filename: filePath,\n id: `data-v-${scopeId}`,\n scoped: style.scoped ?? false,\n inMap: styleInputMap,\n // <style lang=\"scss|less|stylus\"> 需经对应预处理器(缺省 undefined = 纯 CSS)\n preprocessLang: style.lang,\n })\n if (transformedStyle.map != null && result.map == null) {\n warnUnchainableMap(\n { filename: filePath, environmentName, type: 'style', index },\n 'compiler-sfc did not return a style map',\n )\n }\n return wantsStyleSourceMap\n ? { code: result.code as string, map: result.map }\n : result.code as string\n },\n\n async transform(code, id) {\n // 处理 .vue 文件\n if (!VUE_FILE_RE.test(id) && !VUE_QUERY_RE.test(id)) return null\n\n const sfc = await loadVueCompiler()\n if (!sfc) {\n console.warn('[nasti:vue] @vue/compiler-sfc not found. Install it: npm install @vue/compiler-sfc')\n return null\n }\n\n // 处理虚拟模块请求(子块)。style 子块的内容由上方 load 钩子产出 CSS,\n // 后续交给 css 插件(dev 注入 / build 抽取),这里不再拦截。\n if (VUE_QUERY_RE.test(id)) {\n return null\n }\n\n // 解析 SFC\n const transformedSfc = await applySourceTransform(\n vueOptions.transformSfc,\n code,\n { filename: id, environmentName, type: 'sfc' },\n )\n code = transformedSfc.code\n const { descriptor, errors } = sfc.parse(code, {\n ...vueOptions.parse,\n filename: id,\n sourceMap: true,\n })\n if (errors.length) {\n const firstError = errors[0]\n console.error(\n `[nasti:vue] Parse error in ${id}:`,\n typeof firstError === 'string' ? firstError : firstError.message,\n )\n return null\n }\n\n descriptorCache.set(id, {\n descriptor,\n sourceMap: transformedSfc.map,\n })\n const scopeId = hashId(id)\n const wantsSourceMap =\n !!config.build.sourcemap || transformedSfc.map != null\n const vapor = resolveVaporMode(descriptor, vueOptions, sfc, config)\n\n // 编译 script\n let scriptCode = ''\n let scriptMap: unknown\n let scriptBindings: Record<string, unknown> | undefined\n if (descriptor.script || descriptor.scriptSetup) {\n const inlineTemplate = vueOptions.script?.inlineTemplate !== false\n const compiled = sfc.compileScript(descriptor, {\n ...vueOptions.script,\n id: scopeId,\n isProd: !isDev,\n inlineTemplate,\n sourceMap: wantsSourceMap,\n // 让 compileScript 产出 `const __sfc__ = ...`(而非默认的 `export default {...}`)。\n // 否则下方追加的 `__sfc__.render` / `__sfc__.__scopeId` / HMR 记录会引用一个\n // 不存在的 `__sfc__`,并与 compileScript 自带的 `export default` 形成双重默认导出。\n genDefaultAs: '__sfc__',\n vapor,\n })\n scriptCode = compiled.content\n scriptBindings = compiled.bindings\n scriptMap = composeSourceMapChain(\n [compiled.map, transformedSfc.map],\n { filename: id, environmentName, type: 'sfc' },\n )\n if (transformedSfc.map != null && scriptMap == null) {\n warnUnchainableMap(\n { filename: id, environmentName, type: 'sfc' },\n 'compiler-sfc did not return a script map',\n )\n }\n }\n\n // 编译 template(如果没有 inline)\n let templateCode = ''\n let templateMap: unknown\n let templateMultiRoot: boolean | undefined\n const scriptSetupIsInline =\n !!descriptor.scriptSetup && vueOptions.script?.inlineTemplate !== false\n const isTemplateOnlyVapor =\n vapor && !descriptor.script && !descriptor.scriptSetup\n if (descriptor.template && !scriptSetupIsInline) {\n const transformedTemplate = await applySourceTransform(\n vueOptions.transformTemplate,\n descriptor.template.content,\n { filename: id, environmentName, type: 'template' },\n )\n const templateInputMap = composeSourceMapChain(\n [\n transformedTemplate.map,\n descriptor.template.map,\n transformedSfc.map,\n ],\n { filename: id, environmentName, type: 'template' },\n )\n const customCompilerOptions =\n vueOptions.template?.compilerOptions ?? {}\n const compiled = sfc.compileTemplate({\n ...vueOptions.template,\n source: transformedTemplate.code,\n filename: id,\n id: scopeId,\n inMap: templateInputMap,\n vapor,\n compilerOptions: {\n ...customCompilerOptions,\n // Vapor 在 bindingMetadata 缺失时需要空对象(与 Vite / compiler-sfc 一致)\n bindingMetadata:\n customCompilerOptions.bindingMetadata ??\n scriptBindings ??\n (vapor ? {} : undefined),\n scopeId: `data-v-${scopeId}`,\n },\n })\n templateCode = compiled.code\n templateMultiRoot = compiled.multiRoot\n if (\n wantsSourceMap ||\n transformedTemplate.map != null\n ) {\n templateMap = compiled.map\n }\n if (transformedTemplate.map != null && templateMap == null) {\n warnUnchainableMap(\n { filename: id, environmentName, type: 'template' },\n 'compiler-sfc did not return a template map',\n )\n }\n }\n\n // 组装输出。若 SFC 只有 <template> 而无任何 <script>,scriptCode 为空,\n // 兜底一个空组件对象,保证后续 `__sfc__.render` / `__scopeId` 赋值成立。\n // Vapor 纯 template SFC 必须带 `__vapor: true`,否则运行时按 VDOM 组件处理。\n const outputNode = new SourceNode()\n let hasMappedOutput = false\n const append = (fragment: string, map?: unknown) => {\n const normalizedMap = normalizeSourceMap(\n map,\n { filename: id, environmentName, type: 'sfc' },\n )\n if (!normalizedMap) {\n outputNode.add(fragment)\n return\n }\n try {\n // source-map-js accepts nested SourceNodes at runtime, but its bundled\n // declaration incorrectly narrows SourceNode#add to string only.\n outputNode.add(\n SourceNode.fromStringWithSourceMap(\n fragment,\n new SourceMapConsumer(normalizedMap),\n ) as unknown as string,\n )\n hasMappedOutput = true\n } catch (error) {\n warnUnchainableMap(\n { filename: id, environmentName, type: 'sfc' },\n `source-map assembly failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n outputNode.add(fragment)\n }\n }\n\n append(\n scriptCode ||\n (vapor ? 'const __sfc__ = { __vapor: true }' : 'const __sfc__ = {}'),\n scriptMap,\n )\n\n if (templateCode) {\n append('\\n')\n append(templateCode, templateMap)\n append('\\n')\n append('\\n__sfc__.render = render\\n')\n if (isTemplateOnlyVapor && templateMultiRoot !== undefined) {\n append(`\\n__sfc__.__multiRoot = ${JSON.stringify(templateMultiRoot)}\\n`)\n }\n }\n\n // style 导入(&lang.css 结尾 —— css 插件按 .css 后缀接管该虚拟模块)\n if (descriptor.styles.length > 0) {\n for (let i = 0; i < descriptor.styles.length; i++) {\n append(`\\nimport \"${id}?vue&type=style&index=${i}&lang.css\"\\n`)\n }\n }\n\n // Vapor 测试版免责声明:必须放在所有 import 之后,避免破坏 ESM 语法\n if (vapor) {\n append(\n `\\nif (!globalThis.__NASTI_VAPOR_BETA_WARNED__) {\\n` +\n ` globalThis.__NASTI_VAPOR_BETA_WARNED__ = true\\n` +\n ` console.warn(${JSON.stringify(VAPOR_BETA_WARNING)})\\n` +\n `}\\n`,\n )\n }\n\n // scoped 标记\n append(`\\n__sfc__.__scopeId = \"data-v-${scopeId}\"\\n`)\n\n // HMR\n if (isDev) {\n append(`\n__sfc__.__hmrId = ${JSON.stringify(scopeId)}\nif (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {\n __VUE_HMR_RUNTIME__.createRecord(__sfc__.__hmrId, __sfc__)\n}\nif (import.meta.hot) {\n import.meta.hot.accept((mod) => {\n if (!mod) return\n const { default: updated } = mod\n if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {\n __VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render)\n }\n })\n}\n`)\n }\n\n append('\\nexport default __sfc__\\n')\n const renderedOutput = outputNode.toStringWithSourceMap({ file: id })\n const output = renderedOutput.code\n const outputMap = hasMappedOutput\n ? renderedOutput.map.toJSON()\n : undefined\n if (transformedSfc.map != null && outputMap == null) {\n warnUnchainableMap(\n { filename: id, environmentName, type: 'sfc' },\n 'the compiled SFC output contained no chainable mappings',\n )\n }\n\n // compileScript 对 lang=\"ts\" 的 SFC 会在产物里保留 TS 注解 —— 不仅是用户脚本,\n // 连内联 render 也带(如 `(_ctx: any, _cache: any) =>`、`($event: any) => ...`)。\n // Nasti 的 oxc 转译按扩展名只处理 .ts/.tsx,不碰 .vue,所以这里显式把组装后的\n // 产物按 TS 走一遍 oxc 剥离类型,产出纯 JS —— dev(浏览器原生 ESM)与 build\n // (Rolldown 解析)都需要这一步,否则裸 TS 会直接触发解析错误。\n const lang = descriptor.scriptSetup?.lang ?? descriptor.script?.lang\n if (lang === 'ts') {\n const transpiled = transformCode(`${id}.ts`, output, {\n sourcemap: wantsSourceMap,\n target: config.build.target,\n })\n const transpiledMap = transpiled.map\n ? JSON.parse(transpiled.map)\n : undefined\n return {\n code: transpiled.code,\n map: composeSourceMapChain(\n [transpiledMap, outputMap],\n { filename: id, environmentName, type: 'sfc' },\n ),\n }\n }\n\n return { code: output, map: outputMap }\n },\n\n handleHotUpdate(ctx) {\n const { file, modules } = ctx\n if (VUE_FILE_RE.test(file)) {\n // Vue 文件更新: 标记为自接受\n for (const mod of modules) {\n mod.isSelfAccepting = true\n }\n // 清除缓存\n descriptorCache.delete(file)\n }\n return modules\n },\n }\n}\n\n/**\n * 解析当前 SFC 是否启用 Vapor Mode。\n * - 单文件 opt-in:`descriptor.vapor`(`<script setup vapor>` / `<template vapor>`)\n * - 环境级强制:`vue.features.vapor`(仅对可强制的 SFC 生效)\n * 首次启用时在终端打印测试版免责声明。\n */\nfunction resolveVaporMode(\n descriptor: any,\n vueOptions: VueEnvironmentOptions,\n sfc: VueCompilerSfc,\n config: ResolvedConfig,\n): boolean {\n const requested =\n !!descriptor.vapor ||\n (!!vueOptions.features?.vapor && canForceVaporMode(descriptor))\n if (!requested) return false\n\n if (!supportsVaporCompiler(sfc)) {\n config.logger.warnOnce(\n '[nasti:vue] Vapor Mode requires @vue/compiler-sfc >= 3.6. ' +\n 'Install it: npm install @vue/compiler-sfc@^3.6.0-0',\n )\n return false\n }\n\n config.logger.warnOnce(VAPOR_BETA_WARNING)\n return true\n}\n\n/**\n * `features.vapor` 可强制:纯 template SFC、`<script setup>` SFC。\n * 不可强制仅含普通 `<script>`(无 setup)的 `.vue`,因为 Vapor 不支持 Options API。\n */\nfunction canForceVaporMode(descriptor: any): boolean {\n if (typeof descriptor.filename === 'string' && descriptor.filename.endsWith('.vue')) {\n if (descriptor.script && !descriptor.scriptSetup) return false\n return !!(descriptor.scriptSetup || descriptor.template)\n }\n return true\n}\n\n/** `@vue/compiler-sfc` 主版本 ≥ 3.6 才具备 Vapor 编译器。 */\nfunction supportsVaporCompiler(sfc: VueCompilerSfc): boolean {\n const version = sfc.version\n if (!version) return false\n const [major, minor] = version.split('.').map((part) => Number.parseInt(part, 10))\n if (!Number.isFinite(major) || !Number.isFinite(minor)) return false\n return major > 3 || (major === 3 && minor >= 6)\n}\n\nasync function applySourceTransform(\n transform: VueSfcSourceTransform | undefined,\n source: string,\n context: VueSfcTransformContext,\n): Promise<{ code: string; map?: unknown }> {\n if (!transform) return { code: source }\n const result = await transform(source, context)\n return typeof result === 'string' ? { code: result } : result\n}\n\nfunction normalizeSourceMap(\n map: unknown,\n context: VueSfcTransformContext,\n): RawSourceMap | undefined {\n if (map == null) return undefined\n try {\n const value = typeof map === 'string' ? JSON.parse(map) : map\n if (\n value &&\n typeof value === 'object' &&\n Array.isArray((value as RawSourceMap).sources) &&\n Array.isArray((value as RawSourceMap).names) &&\n typeof (value as RawSourceMap).mappings === 'string'\n ) {\n return value as RawSourceMap\n }\n } catch {\n // Report through the debug channel below.\n }\n warnUnchainableMap(context, 'the provided map is not a valid source map')\n return undefined\n}\n\nfunction composeSourceMapChain(\n maps: unknown[],\n context: VueSfcTransformContext,\n): RawSourceMap | undefined {\n const pending = maps.filter((map) => map != null)\n if (pending.length === 0) return undefined\n let composed = normalizeSourceMap(pending.shift(), context)\n for (const map of pending) {\n const input = normalizeSourceMap(map, context)\n if (!input) continue\n if (!composed) {\n composed = input\n continue\n }\n try {\n const consumer = new SourceMapConsumer(composed)\n if (consumer.sources.length !== 1) {\n warnUnchainableMap(\n context,\n 'a generated map has multiple sources and cannot be chained safely',\n )\n continue\n }\n const generator = SourceMapGenerator.fromSourceMap(consumer)\n generator.applySourceMap(\n new SourceMapConsumer(input),\n consumer.sources[0],\n )\n composed = generator.toJSON()\n } catch (error) {\n warnUnchainableMap(\n context,\n `source-map composition failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n }\n }\n return composed\n}\n\nfunction warnUnchainableMap(\n context: VueSfcTransformContext,\n reason: string,\n): void {\n debug?.(\n `source map warning for ${context.filename} (${context.type}, ${context.environmentName}): ${reason}`,\n )\n}\n\nfunction hashId(filename: string): string {\n return crypto.createHash('sha256').update(filename).digest('hex').slice(0, 8)\n}\n","// HTML 入口处理插件 - index.html 处理与脚本注入\nimport path from 'node:path'\nimport fs from 'node:fs'\nimport type { NastiPlugin, ResolvedConfig, HtmlTagDescriptor } from '../types.js'\n\n/** 运行在用户脚本之前、安装 React Fast Refresh 全局钩子的 preamble。 */\nconst REACT_REFRESH_HTML_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\nexport function htmlPlugin(config: ResolvedConfig): NastiPlugin {\n return {\n name: 'nasti:html',\n enforce: 'post',\n\n transformIndexHtml(html) {\n const tags: HtmlTagDescriptor[] = []\n\n if (config.command === 'serve') {\n const isReactLike = config.framework === 'react'\n\n // 先装 Fast Refresh 钩子(必须在任何用户模块之前,因为 JSX 模块 wrapper\n // 会校验 window.__vite_plugin_react_preamble_installed__)\n if (isReactLike) {\n tags.push({\n tag: 'script',\n attrs: { type: 'module' },\n children: REACT_REFRESH_HTML_PREAMBLE,\n injectTo: 'head-prepend',\n })\n }\n\n // HMR 客户端(内置 createHotContext 命名导出,供模块 wrapper 调用)\n tags.push({\n tag: 'script',\n attrs: { type: 'module', src: '/@nasti/client' },\n injectTo: 'head-prepend',\n })\n }\n\n return { html, tags }\n },\n }\n}\n\n/** 处理 HTML,注入标签并重写 script src */\nexport function processHtml(\n html: string,\n tags: HtmlTagDescriptor[],\n): string {\n const headPrepend = tags.filter((t) => t.injectTo === 'head-prepend')\n const head = tags.filter((t) => t.injectTo === 'head' || !t.injectTo)\n const bodyPrepend = tags.filter((t) => t.injectTo === 'body-prepend')\n const body = tags.filter((t) => t.injectTo === 'body')\n\n if (headPrepend.length) {\n html = html.replace(/<head([^>]*)>/i, `<head$1>\\n${serializeTags(headPrepend)}`)\n }\n if (head.length) {\n html = html.replace(/<\\/head>/i, `${serializeTags(head)}\\n</head>`)\n }\n if (bodyPrepend.length) {\n html = html.replace(/<body([^>]*)>/i, `<body$1>\\n${serializeTags(bodyPrepend)}`)\n }\n if (body.length) {\n html = html.replace(/<\\/body>/i, `${serializeTags(body)}\\n</body>`)\n }\n\n return html\n}\n\nfunction serializeTags(tags: HtmlTagDescriptor[]): string {\n return tags.map(serializeTag).join('\\n')\n}\n\nfunction serializeTag(tag: HtmlTagDescriptor): string {\n const attrs = tag.attrs\n ? ' ' +\n Object.entries(tag.attrs)\n .map(([k, v]) => (v === true ? k : `${k}=\"${v}\"`))\n .join(' ')\n : ''\n const children =\n typeof tag.children === 'string'\n ? tag.children\n : tag.children\n ? serializeTags(tag.children)\n : ''\n\n const selfClosing = ['link', 'meta', 'br', 'hr', 'img', 'input'].includes(tag.tag)\n if (selfClosing && !children) {\n return ` <${tag.tag}${attrs} />`\n }\n return ` <${tag.tag}${attrs}>${children}</${tag.tag}>`\n}\n\n/** 读取 HTML 入口文件;htmlFile 可为相对 root 或绝对路径。 */\nexport async function readHtmlFile(\n root: string,\n htmlFile: string = 'index.html',\n): Promise<string | null> {\n const htmlPath = path.isAbsolute(htmlFile) ? htmlFile : path.resolve(root, htmlFile)\n if (!fs.existsSync(htmlPath)) return null\n return fs.readFileSync(htmlPath, 'utf-8')\n}\n","// 内置插件拼装 - server 与 build 共用的 per-env 函数(NASTI_2.0_PLAN.md §1.2)\n//\n// 1.x 在 server/index.ts 与 build/index.ts 各拼一份,容易漂移;统一后\n// 环境插件列表 = pre 内置 + 用户插件 + post 内置,再经 applyToEnvironment\n// 过滤(core/environment.ts 的 resolveEnvironmentPlugins)。\nimport type { NastiPlugin, ResolvedConfig } from '../types.js'\nimport type { CssEngine } from '../core/css-engine.js'\nimport { resolvePlugin } from './resolve.js'\nimport { cssPlugin } from './css.js'\nimport { cssPostPlugin } from './css-post.js'\nimport { assetsPlugin } from './assets.js'\nimport { vuePlugin } from './vue.js'\nimport { htmlPlugin } from './html.js'\n\nexport interface BuiltinPluginOptions {\n /** build 期 CSS 抽取引擎(serve 不传,dev 走 <style> 注入路径) */\n cssEngine?: CssEngine\n /** 当前环境名;内置插件据此读取 per-env resolve/build 配置。 */\n environmentName?: string\n /** 环境 consumer:server 时 css 插件返回无 DOM 的纯 stub(SSR/main/preload) */\n consumer?: 'client' | 'server'\n}\n\n/**\n * 拼装某一环境的完整插件列表(顺序与 1.x 完全一致):\n * [vue?] → resolve → css → assets → [html(serve)] → 用户插件 → [css-post(build)]\n */\nexport function resolvePluginList(\n config: ResolvedConfig,\n userPlugins: NastiPlugin[],\n opts: BuiltinPluginOptions = {},\n): NastiPlugin[] {\n const isServe = config.command === 'serve'\n let environmentOptions\n if (opts.environmentName) {\n environmentOptions = config.environments[opts.environmentName]\n if (!environmentOptions) {\n throw new Error(\n `[nasti] unknown environment \"${opts.environmentName}\" — declare it in config.environments`,\n )\n }\n }\n const pluginConfig = environmentOptions\n ? { ...config, resolve: environmentOptions.resolve, build: environmentOptions.build }\n : config\n const consumer = opts.consumer ?? environmentOptions?.consumer\n\n return [\n // vuePlugin 排最前(enforce: 'pre' 语义):.vue 先编译成 JS 再走后续管道\n ...(config.framework === 'vue'\n ? [vuePlugin(pluginConfig, opts.environmentName ?? 'client')]\n : []),\n resolvePlugin(pluginConfig),\n cssPlugin(pluginConfig, opts.cssEngine, consumer),\n assetsPlugin(pluginConfig),\n ...(isServe ? [htmlPlugin(pluginConfig)] : []),\n ...userPlugins,\n // cssPostPlugin 最后(enforce: 'post' 语义):renderChunk 聚合抽取\n ...(!isServe && opts.cssEngine ? [cssPostPlugin(pluginConfig, opts.cssEngine)] : []),\n ]\n}\n","// Vite 兼容插件容器\n// 管理插件生命周期,实现 resolveId → load → transform 管道\n\nimport type {\n NastiPlugin,\n ResolvedConfig,\n PluginContext,\n ResolveIdResult,\n LoadResult,\n TransformResult,\n ModuleInfo,\n EnvironmentInstance,\n} from '../types.js'\nimport { orderPlugins } from './plugin-api.js'\n\nexport class PluginContainer {\n private plugins: NastiPlugin[]\n private config: ResolvedConfig\n private ctx: PluginContext\n private emittedFiles: Map<string, { fileName: string; source: string | Uint8Array }> = new Map()\n /** Environment API:容器所属环境(未传时为 undefined,行为同 1.x client) */\n readonly environment?: EnvironmentInstance\n\n constructor(config: ResolvedConfig, environment?: EnvironmentInstance) {\n this.config = config\n this.environment = environment\n // 按 enforce 分组,处理 pre/post 显式依赖并执行稳定拓扑排序\n this.plugins = orderPlugins(config.plugins)\n this.ctx = this.createContext()\n }\n\n private createContext(): PluginContext {\n const container = this\n return {\n async resolve(source: string, importer?: string) {\n return container.resolveId(source, importer)\n },\n emitFile(file) {\n const fileName = file.fileName ?? file.name ?? `asset-${container.emittedFiles.size}`\n const id = `emitted:${fileName}`\n container.emittedFiles.set(id, {\n fileName,\n source: file.source ?? '',\n })\n return id\n },\n getModuleInfo(_id): ModuleInfo | null {\n return null\n },\n environment: container.environment,\n }\n }\n\n /** 返回所有通过 emitFile() 输出的文件 */\n getEmittedFiles(): Array<{ fileName: string; source: string | Uint8Array }> {\n return Array.from(this.emittedFiles.values())\n }\n\n async buildStart(): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.buildStart) {\n await plugin.buildStart.call(this.ctx)\n }\n }\n }\n\n async buildEnd(error?: Error): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.buildEnd) {\n await plugin.buildEnd.call(this.ctx, error)\n }\n }\n }\n\n async resolveId(\n source: string,\n importer?: string,\n options: { isEntry?: boolean } = {},\n ): Promise<ResolveIdResult> {\n // ssr 标志由环境 consumer 派生(1.x 写死 false;client 环境行为不变)\n const ssr = this.environment?.consumer === 'server'\n for (const plugin of this.plugins) {\n if (!plugin.resolveId) continue\n const result = await plugin.resolveId.call(\n this.ctx,\n source,\n importer ?? undefined,\n { isEntry: options.isEntry ?? false, ssr },\n )\n if (result != null) return result\n }\n return null\n }\n\n async load(id: string): Promise<LoadResult> {\n for (const plugin of this.plugins) {\n if (!plugin.load) continue\n const result = await plugin.load.call(this.ctx, id)\n if (result != null) return result\n }\n return null\n }\n\n async transform(code: string, id: string): Promise<TransformResult> {\n let currentCode = code\n let lastResult: Exclude<TransformResult, string | null | undefined> | undefined\n for (const plugin of this.plugins) {\n if (!plugin.transform) continue\n const result = await plugin.transform.call(this.ctx, currentCode, id)\n if (result == null) continue\n if (typeof result === 'string') {\n currentCode = result\n lastResult = undefined\n } else {\n currentCode = result.code\n lastResult = result\n }\n }\n return currentCode === code\n ? null\n : {\n ...lastResult,\n code: currentCode,\n }\n }\n\n /** 完整的模块处理管道: resolveId → load → transform */\n async processModule(\n source: string,\n importer?: string,\n ): Promise<{ id: string; code: string } | null> {\n // 1. resolveId\n const resolveResult = await this.resolveId(source, importer, {\n isEntry: !importer,\n })\n if (resolveResult == null) return null\n const id = typeof resolveResult === 'string' ? resolveResult : resolveResult.id\n\n // 2. load\n const loadResult = await this.load(id)\n if (loadResult == null) return null\n const loadedCode = typeof loadResult === 'string' ? loadResult : loadResult.code\n\n // 3. transform\n const transformResult = await this.transform(loadedCode, id)\n const finalCode = transformResult == null\n ? loadedCode\n : typeof transformResult === 'string'\n ? transformResult\n : transformResult.code\n\n return { id, code: finalCode }\n }\n\n getPlugins(): NastiPlugin[] {\n return this.plugins\n }\n}\n","/** 保留语义 query,仅移除浏览器为 HMR 缓存失效附加的 `t` 参数。 */\nexport function removeTimestampQuery(url: string): 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 const queryIndex = withoutHash.indexOf('?')\n if (queryIndex < 0) return url\n\n const pathname = withoutHash.slice(0, queryIndex)\n const query = withoutHash\n .slice(queryIndex + 1)\n .split('&')\n .filter((part) => !/^t=\\d+$/.test(part))\n .join('&')\n return pathname + (query ? `?${query}` : '') + hash\n}\n","// 模块依赖图 - 用于 HMR 追踪模块关系\n\nimport type { ModuleNode, TransformResult } from '../types.js'\nimport { removeTimestampQuery } from './url.js'\n\nexport class ModuleGraph {\n readonly environmentName: string\n private urlToModuleMap = new Map<string, ModuleNode>()\n private idToModuleMap = new Map<string, ModuleNode>()\n private fileToModulesMap = new Map<string, Set<ModuleNode>>()\n\n constructor(environmentName = 'client') {\n this.environmentName = environmentName\n }\n\n getModuleByUrl(url: string): ModuleNode | undefined {\n return this.urlToModuleMap.get(removeTimestampQuery(url))\n }\n\n getModuleById(id: string): ModuleNode | undefined {\n return this.idToModuleMap.get(id)\n }\n\n getModulesByFile(file: string): Set<ModuleNode> | undefined {\n return this.fileToModulesMap.get(file)\n }\n\n /**\n * Modules whose registered entry file lives under `dir` (inclusive).\n * Used when a non-entry source inside a prebundled workspace package changes:\n * only the package entry was registered, so getModulesByFile(changedFile)\n * misses — we invalidate every /@modules entry rooted in that package.\n */\n getModulesWithFileUnder(dir: string): Set<ModuleNode> {\n const result = new Set<ModuleNode>()\n // Normalize separators so Windows-stored paths still match.\n const normDir = dir.replace(/\\\\/g, '/')\n const normPrefix = normDir.endsWith('/') ? normDir : normDir + '/'\n for (const [file, mods] of this.fileToModulesMap) {\n const normFile = file.replace(/\\\\/g, '/')\n if (normFile === normDir || normFile.startsWith(normPrefix)) {\n for (const m of mods) result.add(m)\n }\n }\n return result\n }\n\n async ensureEntryFromUrl(url: string): Promise<ModuleNode> {\n const normalizedUrl = removeTimestampQuery(url)\n let mod = this.urlToModuleMap.get(normalizedUrl)\n if (mod) return mod\n\n mod = this.createModule(normalizedUrl)\n this.urlToModuleMap.set(normalizedUrl, mod)\n return mod\n }\n\n createModule(url: string, id?: string): ModuleNode {\n const mod: ModuleNode = {\n id: id ?? url,\n file: null,\n url,\n type: url.endsWith('.css') ? 'css' : 'js',\n importers: new Set(),\n importedModules: new Set(),\n acceptedHmrDeps: new Set(),\n transformResult: null,\n lastHMRTimestamp: 0,\n invalidationVersion: 0,\n isSelfAccepting: false,\n environment: this.environmentName,\n }\n this.idToModuleMap.set(mod.id, mod)\n return mod\n }\n\n /** 注册文件路径到模块的映射 */\n registerModule(mod: ModuleNode, file: string): void {\n mod.file = file\n let mods = this.fileToModulesMap.get(file)\n if (!mods) {\n mods = new Set()\n this.fileToModulesMap.set(file, mods)\n }\n mods.add(mod)\n }\n\n /**\n * Reindex a module under a plugin-provided canonical id (e.g. a `\\0virtual:foo`\n * id returned from `resolveId`). Plugins look up their own virtual modules via\n * `getModuleById(RESOLVED_ID)` to invalidate them on watcher events; without\n * this remap they'd never find the node because `ensureEntryFromUrl` keys by\n * the public URL only.\n */\n setModuleId(mod: ModuleNode, id: string): void {\n if (mod.id === id) return\n this.idToModuleMap.delete(mod.id)\n mod.id = id\n this.idToModuleMap.set(id, mod)\n }\n\n /** 更新模块依赖关系 */\n updateModuleImports(mod: ModuleNode, importedIds: Set<string>): void {\n // 清除旧的导入关系\n for (const imported of mod.importedModules) {\n imported.importers.delete(mod)\n }\n mod.importedModules.clear()\n\n // 建立新的导入关系\n for (const id of importedIds) {\n const importedMod = this.idToModuleMap.get(id)\n if (importedMod) {\n mod.importedModules.add(importedMod)\n importedMod.importers.add(mod)\n }\n }\n }\n\n /**\n * 用一次转换得到的信息原子更新 import 与 HMR accept 关系。\n * 依赖节点会在真正被浏览器请求前预先创建,这样入口模块先转换时也能建立完整图。\n */\n async updateModuleInfo(\n mod: ModuleNode,\n importedUrls: Set<string>,\n acceptedUrls: Set<string>,\n isSelfAccepting: boolean,\n expectedInvalidationVersion?: number,\n ): Promise<Set<ModuleNode> | null> {\n const importedModules = await Promise.all(\n [...importedUrls].map((url) => this.ensureEntryFromUrl(url)),\n )\n const acceptedModules = await Promise.all(\n [...acceptedUrls].map((url) => this.ensureEntryFromUrl(url)),\n )\n\n // 异步插件转换期间若又发生文件变更,旧结果不能覆盖新模块图或转换缓存。\n if (\n expectedInvalidationVersion !== undefined &&\n mod.invalidationVersion !== expectedInvalidationVersion\n ) {\n return null\n }\n\n const previousImports = new Set(mod.importedModules)\n for (const imported of previousImports) {\n imported.importers.delete(mod)\n }\n mod.importedModules.clear()\n mod.acceptedHmrDeps.clear()\n\n for (const imported of importedModules) {\n mod.importedModules.add(imported)\n imported.importers.add(mod)\n }\n for (const accepted of acceptedModules) {\n mod.acceptedHmrDeps.add(accepted)\n }\n mod.isSelfAccepting = isSelfAccepting\n\n const pruned = new Set<ModuleNode>()\n for (const imported of previousImports) {\n if (!mod.importedModules.has(imported) && imported.importers.size === 0) {\n pruned.add(imported)\n }\n }\n return pruned\n }\n\n /** 使模块的转换缓存失效 */\n invalidateModule(mod: ModuleNode, timestamp = Date.now()): void {\n mod.transformResult = null\n mod.lastHMRTimestamp = timestamp\n mod.invalidationVersion++\n }\n\n /**\n * 仅失效到 HMR 边界:显式接受依赖的模块本身不会重执行;自接受模块需要失效,\n * 但不再继续影响其 importer。这样既能传播依赖时间戳,也不会隐式重复副作用。\n */\n invalidateModuleAndImporters(\n mod: ModuleNode,\n timestamp = Date.now(),\n seen = new Set<ModuleNode>(),\n ): void {\n if (seen.has(mod)) return\n seen.add(mod)\n this.invalidateModule(mod, timestamp)\n for (const importer of mod.importers) {\n if (importer.acceptedHmrDeps.has(mod)) continue\n if (importer.isSelfAccepting) {\n this.invalidateModule(importer, timestamp)\n continue\n }\n this.invalidateModuleAndImporters(importer, timestamp, seen)\n }\n }\n\n /** 使所有模块缓存失效 */\n invalidateAll(): void {\n for (const mod of this.idToModuleMap.values()) {\n this.invalidateModule(mod)\n }\n }\n\n /** 获取 HMR 传播边界 - 从变更模块向上遍历找到接受更新的边界 */\n getHmrBoundaries(mod: ModuleNode): { boundary: ModuleNode; acceptedVia: ModuleNode }[] {\n const boundaries: { boundary: ModuleNode; acceptedVia: ModuleNode }[] = []\n const traversed = new Set<ModuleNode>()\n\n const addBoundary = (boundary: ModuleNode, acceptedVia: ModuleNode): void => {\n if (!boundaries.some((item) =>\n item.boundary === boundary && item.acceptedVia === acceptedVia\n )) {\n boundaries.push({ boundary, acceptedVia })\n }\n }\n\n const propagate = (node: ModuleNode): boolean => {\n if (traversed.has(node)) return true\n traversed.add(node)\n\n // 自接受边界重新导入自身,而不是触发它的下游依赖。\n if (node.isSelfAccepting) {\n addBoundary(node, node)\n return true\n }\n if (node.importers.size === 0) return false\n\n for (const importer of node.importers) {\n // 显式 accept 在进入 importer 前判断,所以被接受的分支不会污染 traversed;\n // 菱形图中的其他未接受分支仍会继续传播并正确发现死路。\n if (importer.acceptedHmrDeps.has(node)) {\n addBoundary(importer, node)\n continue\n }\n if (!propagate(importer)) return false\n }\n return true\n }\n\n return propagate(mod) ? boundaries : []\n }\n}\n","// HotChannel - per-environment 热更通道(Environment API)\n//\n// 接口契约定义在 types.ts(含 invoke:fetchModule/getBuiltins/_skipFsCheck)。\n// client-consumer 环境使用带环境名的共享 ws transport;非 client = noop。\n// SSR module runner 可经 setInvokeHandler 注册 RPC,不需要再改接口。\nimport type {\n HotChannel,\n HotChannelInvokeHandlers,\n HotChannelListener,\n HmrPayload,\n WebSocketServer,\n} from '../types.js'\n\n/** 非 client 环境的占位通道(SSR/edge 可由 runner/driver 接上真实 transport) */\nexport function createNoopHotChannel(): HotChannel {\n return {\n send() {},\n on() {},\n off() {},\n listen() {},\n close() {},\n setInvokeHandler() {},\n }\n}\n\n/**\n * client-consumer 环境的 ws 通道:包装 server/ws.ts 的 WebSocketServer。\n * 事件监听与 invoke 在现有 ws 协议上预留,payload 以 environment 字段分流。\n */\nexport function createWsHotChannel(\n ws: WebSocketServer,\n environmentName = 'client',\n): HotChannel {\n const listeners = new Map<string, Set<HotChannelListener>>()\n let invokeHandlers: HotChannelInvokeHandlers | undefined\n\n return {\n send(payload: HmrPayload) {\n ws.send({ ...payload, environment: payload.environment ?? environmentName })\n },\n on(event, listener) {\n let set = listeners.get(event)\n if (!set) listeners.set(event, (set = new Set()))\n set.add(listener)\n },\n off(event, listener) {\n listeners.get(event)?.delete(listener)\n },\n listen() {},\n // 多个 environment 共享底层 WebSocket server;它由 DevServer.close() 统一关闭。\n close() {},\n setInvokeHandler(handlers) {\n invokeHandlers = handlers\n void invokeHandlers\n },\n }\n}\n","// NastiEnvironment - Environment API 主干(NASTI_2.0_PLAN.md §1.2)\n//\n// Vite 8 的分层是 PartialEnvironment→BaseEnvironment→Dev/BuildEnvironment;\n// Nasti 当前单图单容器,收敛为一个精简类即可:每个环境自带 name/consumer/\n// 过滤后的插件列表/PluginContainer/ModuleGraph/HotChannel。\n//\n// SSR、完整打包模式、多端/Electron 全部表达为 environment —— 这是其余\n// 2.0 特性共同依赖的主干。每个 client-consumer 环境拥有独立的 dev\n// transform/module graph/HMR 管线;server consumer 可由 module runner 或\n// 外部 driver 接管。\nimport type {\n EnvironmentDriver,\n EnvironmentBuildMetadata,\n EnvironmentDriverContext,\n EnvironmentCssModule,\n EnvironmentInstance,\n HotChannel,\n NastiPlugin,\n PluginApi,\n ResolvedConfig,\n ResolvedEnvironmentOptions,\n} from '../types.js'\nimport { PluginContainer } from './plugin-container.js'\nimport { ModuleGraph } from './module-graph.js'\nimport { createNoopHotChannel } from './hot-channel.js'\nimport { createDebugger } from './debug.js'\nimport { getPluginApi } from './plugin-api.js'\n\nconst debug = createDebugger('nasti:environment')\n\nexport interface NastiEnvironmentInit {\n hot?: HotChannel\n mode?: 'dev' | 'build'\n /** 环境的候选插件(init 时经 applyToEnvironment 过滤) */\n plugins?: NastiPlugin[]\n /** 配置解析阶段创建的共享插件 API;通常自动从 ResolvedConfig 获取 */\n pluginApi?: PluginApi\n}\n\nexport class NastiEnvironment implements EnvironmentInstance {\n readonly name: string\n readonly consumer: 'client' | 'server'\n readonly mode: 'dev' | 'build'\n readonly config: ResolvedConfig\n readonly options: ResolvedEnvironmentOptions\n readonly hot: HotChannel\n driver?: EnvironmentDriver\n\n /** applyToEnvironment 过滤后的插件(init() 后可用) */\n plugins: NastiPlugin[] = []\n /** per-env 插件容器(init() 后可用;dev 管线使用) */\n pluginContainer: PluginContainer | null = null\n /** per-env 模块图(dev 管线使用) */\n moduleGraph: ModuleGraph\n\n private candidatePlugins: NastiPlugin[]\n private pluginApi: PluginApi\n private buildMetadata: EnvironmentBuildMetadata = {}\n private cssModules = new Map<string, EnvironmentCssModule>()\n private assetModules = new Map<string, string>()\n private transformRequestHandler?: (\n url: string,\n ) => Promise<{ code: string; map?: unknown } | null>\n private initialized = false\n\n constructor(name: string, config: ResolvedConfig, init: NastiEnvironmentInit = {}) {\n const options = config.environments[name]\n if (!options) {\n throw new Error(\n `[nasti] unknown environment \"${name}\" — declare it in config.environments`,\n )\n }\n this.name = name\n this.consumer = options.consumer\n this.mode = init.mode ?? (config.command === 'build' ? 'build' : 'dev')\n this.config = config\n this.options = options\n this.hot = init.hot ?? createNoopHotChannel()\n this.moduleGraph = new ModuleGraph(name)\n this.candidatePlugins = init.plugins ?? config.plugins\n this.pluginApi = init.pluginApi ?? getPluginApi(config)\n }\n\n /** 过滤插件并建 per-env PluginContainer */\n async init(): Promise<void> {\n if (this.initialized) return\n this.initialized = true\n this.plugins = resolveEnvironmentPlugins(this, this.candidatePlugins)\n this.pluginContainer = new PluginContainer(\n { ...this.config, plugins: this.plugins },\n this,\n )\n if (this.options.driver) {\n const claimed: Array<{ plugin: NastiPlugin; driver: EnvironmentDriver }> = []\n for (const plugin of this.plugins) {\n const driver = await plugin.createEnvironmentDriver?.(this, this.pluginApi)\n if (driver) claimed.push({ plugin, driver })\n }\n if (claimed.length === 0) {\n throw new Error(\n `[nasti] environment \"${this.name}\" requested driver ` +\n `\"${this.options.driver}\", but no plugin provided it`,\n )\n }\n if (claimed.length > 1) {\n throw new Error(\n `[nasti] environment \"${this.name}\" was claimed by multiple drivers: ` +\n claimed.map(({ plugin, driver }) => `${plugin.name} (${driver.name})`).join(', '),\n )\n }\n this.driver = claimed[0].driver\n debug?.(`env \"${this.name}\" uses driver \"${this.driver.name}\"`)\n }\n debug?.(`env \"${this.name}\" initialized (${this.plugins.length} plugins)`)\n }\n\n getDriverContext(): EnvironmentDriverContext {\n return {\n environment: this,\n config: this.config,\n api: this.pluginApi,\n logger: this.config.logger,\n }\n }\n\n configureDevPipeline(\n transformRequest: (url: string) => Promise<{ code: string; map?: unknown } | null>,\n ): void {\n this.transformRequestHandler = transformRequest\n }\n\n async transformRequest(url: string): Promise<{ code: string; map?: unknown } | null> {\n if (!this.transformRequestHandler) {\n throw new Error(\n `[nasti] environment \"${this.name}\" does not have an initialized dev transform pipeline`,\n )\n }\n return this.transformRequestHandler(url)\n }\n\n setCssModule(module: EnvironmentCssModule): void {\n this.cssModules.set(module.id, { ...module })\n }\n\n getCssModule(id: string): EnvironmentCssModule | undefined {\n const module = this.cssModules.get(id)\n return module ? { ...module } : undefined\n }\n\n getCssModules(): Readonly<Record<string, EnvironmentCssModule>> {\n return Object.freeze(\n Object.fromEntries(\n [...this.cssModules].map(([id, module]) => [id, { ...module }]),\n ),\n )\n }\n\n setAssetModule(id: string, fileName: string): void {\n this.assetModules.set(id, fileName)\n }\n\n getAssetModules(): Readonly<Record<string, string>> {\n return Object.freeze(Object.fromEntries(this.assetModules))\n }\n\n setBuildMetadata(metadata: EnvironmentBuildMetadata): void {\n const { entries: currentEntries, ...currentMetadata } = this.buildMetadata\n const { entries, ...nextMetadata } = metadata\n this.buildMetadata = {\n ...currentMetadata,\n ...nextMetadata,\n ...(currentEntries || entries\n ? { entries: { ...currentEntries, ...entries } }\n : {}),\n }\n }\n\n getBuildMetadata(): EnvironmentBuildMetadata {\n const { entries, ...metadata } = this.buildMetadata\n return {\n ...metadata,\n ...(entries ? { entries: { ...entries } } : {}),\n }\n }\n\n async close(): Promise<void> {\n try {\n await this.driver?.close?.(this.getDriverContext())\n } finally {\n await this.hot.close?.()\n }\n }\n}\n\n/** 按 applyToEnvironment 过滤环境插件(未声明 = 应用于所有环境) */\nexport function resolveEnvironmentPlugins(\n environment: EnvironmentInstance,\n plugins: NastiPlugin[],\n): NastiPlugin[] {\n return plugins.filter((p) => {\n if (!p.applyToEnvironment) return true\n try {\n return p.applyToEnvironment(environment)\n } catch (err: any) {\n environment.config.logger.error(\n `[nasti] plugin \"${p.name}\" applyToEnvironment threw: ${err.message}`,\n { error: err },\n )\n return false\n }\n })\n}\n"],"mappings":"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"}
|