@dune2/vite
v0.2.0
Published
面向 Vite 的编译期插件,用于处理 `createIsomorphicFn()` 同构函数链:构建时按 `consumer` 保留目标分支(默认 `server`),缺失分支统一替换为 `() => {}`。
Readme
@dune2/vite
面向 Vite 的编译期插件,用于处理 createIsomorphicFn() 同构函数链:构建时按 consumer 保留目标分支(默认 server),缺失分支统一替换为 () => {}。
功能特性
- 基于 ast-grep 做 AST 级改写
- 仅在源码包含
createIsomorphicFn/createServerOnlyFn/createClientOnlyFn时参与转换 - 默认匹配
.ts/.tsx/.js/.jsx/.mjs/.cjs,可通过include自定义 - 跳过 Vite 虚拟模块(路径含
\0) - 支持静态配置与按环境动态配置(
Dune2ViteOptionsFactory) - 导出
createIsomorphicFnTransform/createServerOnlyFnTransform/createClientOnlyFnTransform,便于在测试或自定义工具链中复用 - 内部采用 rule / pattern 驱动的统一改写引擎,新增 transform 只需新增规则并注册
安装
pnpm add -D @dune2/vite
pnpm add vite # peer dependency,需由项目自行安装支持的 Vite 版本:^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0(见 package.json 的 peerDependencies)。
快速开始
在 vite.config.ts 注册插件(enforce: 'pre',会优先执行):
import { defineConfig } from 'vite';
import { dune2Vite } from '@dune2/vite';
export default defineConfig({
plugins: [dune2Vite()],
});转换规则
consumer 控制保留分支,默认值为 server。
| 源码 | consumer: 'server' | consumer: 'client' |
| ------------------------------------------ | -------------------- | -------------------- |
| createIsomorphicFn().server(s).client(c) | s | c |
| createIsomorphicFn().client(c).server(s) | s | c |
| createIsomorphicFn().server(s) | s | () => {} |
| createIsomorphicFn().client(c) | () => {} | c |
| createIsomorphicFn() | () => {} | () => {} |
| createServerOnlyFn(f) | f | 抛错函数 |
| createClientOnlyFn(f) | 抛错函数 | f |
示例:
// 输入
export const log = createIsomorphicFn()
.server((m) => console.log('server:', m))
.client((m) => console.log('client:', m));
// consumer: 'server' 输出
export const log = (m) => console.log('server:', m);
// consumer: 'client' 输出
export const log = (m) => console.log('client:', m);错误文案:
createServerOnlyFn在 client 侧替换为:createServerOnlyFn() functions can only be called on the server!createClientOnlyFn在 server 侧替换为:createClientOnlyFn() functions can only be called on the client!
配置项
interface Dune2ViteOptions {
/** 参与扫描的文件路径正则,默认 /\.[mc]?[jt]sx?$/ */
include?: RegExp;
/** 选择保留的分支,默认 'server' */
consumer?: 'server' | 'client';
}
type Dune2ViteOptionsFactory = (
environment: PartialEnvironment,
) => Dune2ViteOptions | false | null | undefined;Dune2ViteOptionsFactory 基于 plugin.applyToEnvironment 分发插件实例,适合同一份配置覆盖多种构建环境。
使用示例
import { dune2Vite } from '@dune2/vite';
// 1) 默认保留 server 分支
dune2Vite();
// 2) 显式保留 client 分支
dune2Vite({ consumer: 'client' });
// 3) 按环境动态选择分支
dune2Vite((environment) => {
if (environment.config.consumer === 'server') {
return { consumer: 'server' };
}
if (environment.config.consumer === 'client') {
return { consumer: 'client' };
}
return false;
});返回 false | null | undefined 会在当前环境停用插件。
高级用法
插件额外导出 createIsomorphicFnTransform、createServerOnlyFnTransform、createClientOnlyFnTransform,也导出 compileTransform 便于在自定义工具链中直接复用。
import {
createIsomorphicFnTransform,
createServerOnlyFnTransform,
createClientOnlyFnTransform,
compileTransform,
} from '@dune2/vite';
const code = `export const f = createIsomorphicFn().server(() => 1).client(() => 2);`;
const filename = '/virtual/entry.ts';
const serverCode = compileTransform(
code,
filename,
createIsomorphicFnTransform,
'server',
);
const clientCode = compileTransform(
code,
filename,
createIsomorphicFnTransform,
'client',
);若你在插件外按 AST 管线组合多个 transform,也可直接调用各 createXxxTransform。
开发
在 monorepo 根目录或本包目录执行:
cd packages/vite
pnpm run build # 类型检查 + tsdown 打包
pnpm run test