feat: add writeToDisk option for dev server support

- Add writeToDisk option to write .d.ts files directly to disk
- Useful for rsbuild/rspack dev server which uses in-memory FS
- Set writeToDisk: true in dev mode to see generated types

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
hyper 2026-03-31 15:54:38 +08:00
parent 377a47e49f
commit 525ae262fd
6 changed files with 39 additions and 5 deletions

View File

@ -43,6 +43,7 @@ module.exports = {
trim: true, // 修剪表头和值的前后空格 (默认 true)
// emitTypes: false, // 禁用类型定义生成 (默认 true)
// typesOutputDir: 'types', // 类型文件输出目录 (可选)
// writeToDisk: true, // 在 dev server 下写入磁盘 (默认 false)
},
},
},
@ -96,6 +97,7 @@ import type { RowType } from './data.schema.csv';
| `trim` | boolean | `true` | Trim headers and values |
| `emitTypes` | boolean | `true` | Generate TypeScript declaration file (.d.ts) |
| `typesOutputDir` | string | `''` | Output directory for generated type files (relative to output path) |
| `writeToDisk` | boolean | `false` | Write .d.ts files directly to disk (useful for dev server) |
## Schema Syntax

View File

@ -11,6 +11,8 @@ interface CsvLoaderOptions {
emitTypes?: boolean;
/** Output directory for generated type files (relative to output path) */
typesOutputDir?: string;
/** Write .d.ts files to disk (useful for dev server) */
writeToDisk?: boolean;
}
declare function csvLoader(this: LoaderContext<CsvLoaderOptions>, content: string): string | Buffer;

View File

@ -11,6 +11,8 @@ interface CsvLoaderOptions {
emitTypes?: boolean;
/** Output directory for generated type files (relative to output path) */
typesOutputDir?: string;
/** Write .d.ts files to disk (useful for dev server) */
writeToDisk?: boolean;
}
declare function csvLoader(this: LoaderContext<CsvLoaderOptions>, content: string): string | Buffer;

View File

@ -365,6 +365,7 @@ function createValidator(schema) {
// src/csv-loader/loader.ts
var path = __toESM(require("path"));
var fs = __toESM(require("fs"));
function schemaToTypeString(schema) {
switch (schema.type) {
case "string":
@ -411,6 +412,7 @@ function csvLoader(content) {
const trim = options?.trim ?? true;
const emitTypes = options?.emitTypes ?? true;
const typesOutputDir = options?.typesOutputDir ?? "";
const writeToDisk = options?.writeToDisk ?? false;
const records = (0, import_sync.parse)(content, {
delimiter,
quote,
@ -475,7 +477,13 @@ function csvLoader(content) {
const dtsFileName = relativePath.replace(/\.csv$/, ".d.ts");
const outputPath = typesOutputDir ? path.join(typesOutputDir, dtsFileName) : dtsFileName;
const dtsContent = generateTypeDefinition(this.resourcePath, propertyConfigs, `./${relativePath}`);
if (writeToDisk) {
const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || "", dtsFileName);
fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
fs.writeFileSync(absolutePath, dtsContent);
} else {
this.emitFile?.(outputPath, dtsContent);
}
}
return `export default ${json};`;
}

View File

@ -331,6 +331,7 @@ function createValidator(schema) {
// src/csv-loader/loader.ts
import * as path from "path";
import * as fs from "fs";
function schemaToTypeString(schema) {
switch (schema.type) {
case "string":
@ -377,6 +378,7 @@ function csvLoader(content) {
const trim = options?.trim ?? true;
const emitTypes = options?.emitTypes ?? true;
const typesOutputDir = options?.typesOutputDir ?? "";
const writeToDisk = options?.writeToDisk ?? false;
const records = parse(content, {
delimiter,
quote,
@ -441,8 +443,14 @@ function csvLoader(content) {
const dtsFileName = relativePath.replace(/\.csv$/, ".d.ts");
const outputPath = typesOutputDir ? path.join(typesOutputDir, dtsFileName) : dtsFileName;
const dtsContent = generateTypeDefinition(this.resourcePath, propertyConfigs, `./${relativePath}`);
if (writeToDisk) {
const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || "", dtsFileName);
fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
fs.writeFileSync(absolutePath, dtsContent);
} else {
this.emitFile?.(outputPath, dtsContent);
}
}
return `export default ${json};`;
}
export {

View File

@ -3,6 +3,7 @@ import { parse } from 'csv-parse/sync';
import { parseSchema, createValidator, parseValue } from '../index.js';
import type { Schema } from '../types.js';
import * as path from 'path';
import * as fs from 'fs';
export interface CsvLoaderOptions {
delimiter?: string;
@ -15,6 +16,8 @@ export interface CsvLoaderOptions {
emitTypes?: boolean;
/** Output directory for generated type files (relative to output path) */
typesOutputDir?: string;
/** Write .d.ts files to disk (useful for dev server) */
writeToDisk?: boolean;
}
interface PropertyConfig {
@ -91,6 +94,7 @@ export default function csvLoader(
const trim = options?.trim ?? true;
const emitTypes = options?.emitTypes ?? true;
const typesOutputDir = options?.typesOutputDir ?? '';
const writeToDisk = options?.writeToDisk ?? false;
const records = parse(content, {
delimiter,
@ -170,8 +174,16 @@ export default function csvLoader(
: dtsFileName;
const dtsContent = generateTypeDefinition(this.resourcePath, propertyConfigs, `./${relativePath}`);
if (writeToDisk) {
// Write directly to disk (useful for dev server)
const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || '', dtsFileName);
fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
fs.writeFileSync(absolutePath, dtsContent);
} else {
// Emit to in-memory filesystem (for production build)
this.emitFile?.(outputPath, dtsContent);
}
}
return `export default ${json};`;
}