插件 API

Nasti 的插件接口与 Vite 完全兼容。现有的 Vite / Rollup 插件可以直接使用。

基本结构

import type { NastiPlugin } from 'nasti-build'

function myPlugin(options = {}): NastiPlugin {
  return {
    name: 'my-plugin',      // 必需,唯一标识
    enforce: 'pre',          // 可选: 'pre' | 'post'
    apply: 'build',           // 可选: 'build' | 'serve'

    resolveId(source, importer) {
      // 解析模块标识符
    },
    load(id) {
      // 加载模块源代码
    },
    transform(code, id) {
      // 转换模块代码
    },
  }
}

通用钩子

以下钩子在开发和构建模式下都会执行:

resolveId

resolveId(source: string, importer: string | undefined, options: { isEntry: boolean }): string | null | { id: string; external?: boolean }

自定义模块解析逻辑。返回解析后的 ID,或 null 交给下一个插件处理。

load

load(id: string): string | null | { code: string; map?: any }

自定义模块加载。返回模块源码,或 null 使用默认加载。

transform

transform(code: string, id: string): string | null | { code: string; map?: any }

转换模块代码。代码会按插件顺序依次通过 transform 管道。

buildStart / buildEnd

buildStart(): void
buildEnd(error?: Error): void

构建生命周期钩子。

Nasti / Vite 专有钩子

config

config(config: NastiConfig, env: { mode: string; command: string }): NastiConfig | null

在配置解析前修改配置。

configResolved

configResolved(config: ResolvedConfig): void

读取最终配置。

configureServer

configureServer(server: DevServer): void | (() => void)

自定义开发服务器。返回函数会在内部中间件之后执行。

transformIndexHtml

transformIndexHtml(html: string): string | HtmlTagDescriptor[] | { html: string; tags: HtmlTagDescriptor[] }

转换入口 HTML 文件。

handleHotUpdate

handleHotUpdate(ctx: HmrContext): void | ModuleNode[]

自定义 HMR 更新处理。

插件顺序

插件按以下顺序执行:

  1. enforce: 'pre' 的插件
  2. 没有 enforce 的普通插件
  3. enforce: 'post' 的插件

条件应用

使用 apply 让插件只在特定模式下生效:

{
  apply: 'build',    // 仅在 nasti build 时生效
  apply: 'serve',    // 仅在 nasti dev 时生效
  apply: (config, { command }) => command === 'build',  // 函数形式
}

示例:Markdown 插件

function markdownPlugin(): NastiPlugin {
  return {
    name: 'markdown',
    transform(code, id) {
      if (!id.endsWith('.md')) return null
      const html = marked(code)
      return `export default ${JSON.stringify(html)}`
    },
  }
}