fix build error

This commit is contained in:
musistudio
2026-01-02 19:06:17 +08:00
parent 4c5a84e028
commit e2bd0397b4
3 changed files with 140 additions and 3 deletions

View File

@@ -4,11 +4,11 @@
"description": "A universal LLM API transformation server", "description": "A universal LLM API transformation server",
"main": "dist/cjs/server.cjs", "main": "dist/cjs/server.cjs",
"module": "dist/esm/server.mjs", "module": "dist/esm/server.mjs",
"types": "dist/plugins.d.ts", "types": "./dist/index.d.ts",
"type": "module", "type": "module",
"exports": { "exports": {
".": { ".": {
"types": "./dist/plugins.d.ts", "types": "./dist/index.d.ts",
"import": "./dist/esm/server.mjs", "import": "./dist/esm/server.mjs",
"require": "./dist/cjs/server.cjs" "require": "./dist/cjs/server.cjs"
} }

View File

@@ -1,7 +1,17 @@
import * as esbuild from "esbuild"; import * as esbuild from "esbuild";
import * as path from "path";
import * as fs from "fs";
import { fileURLToPath } from "url";
import { execSync } from "child_process";
import { pathAliasPlugin } from "./esbuild-plugin-path-alias";
const watch = process.argv.includes("--watch"); const watch = process.argv.includes("--watch");
// Get the absolute path to the src directory (ES module compatible)
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const baseUrl = path.resolve(__dirname, "..");
const baseConfig: esbuild.BuildOptions = { const baseConfig: esbuild.BuildOptions = {
entryPoints: ["src/server.ts"], entryPoints: ["src/server.ts"],
bundle: true, bundle: true,
@@ -9,10 +19,73 @@ const baseConfig: esbuild.BuildOptions = {
sourcemap: true, sourcemap: true,
platform: "node", platform: "node",
target: "node18", target: "node18",
plugins: [], plugins: [
// Add path alias plugin to resolve @/ imports
pathAliasPlugin({
alias: {
"@/*": "src/*",
},
baseUrl,
}),
],
external: ["fastify", "dotenv", "@fastify/cors", "undici", "tiktoken", "@CCR/shared", "lru-cache"], external: ["fastify", "dotenv", "@fastify/cors", "undici", "tiktoken", "@CCR/shared", "lru-cache"],
}; };
// Generate type declarations with resolved path aliases
function generateTypeDeclarations() {
console.log("Skipping type declaration generation (using manual plugins.d.ts)...");
// Type declarations are manually maintained in dist/plugins.d.ts
// This avoids issues with @/ path aliases in auto-generated declarations
}
// Replace @/ paths with relative paths in .d.ts files
function replacePathAliases(dir: string, baseDir = dir) {
const files = fs.readdirSync(dir);
for (const file of files) {
const fullPath = path.join(dir, file);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
replacePathAliases(fullPath, baseDir);
} else if (file.endsWith(".d.ts")) {
let content = fs.readFileSync(fullPath, "utf-8");
// Replace @/ imports with relative paths
content = content.replace(/from\s+["']@(\/[^"']+)["']/g, (_, importPath) => {
const absolutePath = path.resolve(baseUrl, "src", importPath.slice(2));
const currentDir = path.dirname(fullPath);
const relativePath = path.relative(currentDir, absolutePath);
const normalizedPath = relativePath.split(path.sep).join("/");
return `from "${normalizedPath}"`;
});
fs.writeFileSync(fullPath, content);
}
}
}
// Copy .d.ts files maintaining directory structure
function copyDtsFiles(sourceDir: string, targetDir: string) {
const files = fs.readdirSync(sourceDir);
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
for (const file of files) {
const sourcePath = path.join(sourceDir, file);
const targetPath = path.join(targetDir, file);
const stat = fs.statSync(sourcePath);
if (stat.isDirectory()) {
copyDtsFiles(sourcePath, targetPath);
} else if (file.endsWith(".d.ts")) {
fs.copyFileSync(sourcePath, targetPath);
}
}
}
const cjsConfig: esbuild.BuildOptions = { const cjsConfig: esbuild.BuildOptions = {
...baseConfig, ...baseConfig,
outdir: "dist/cjs", outdir: "dist/cjs",
@@ -30,6 +103,9 @@ const esmConfig: esbuild.BuildOptions = {
async function build() { async function build() {
console.log("Building CJS and ESM versions..."); console.log("Building CJS and ESM versions...");
// First, generate type declarations
generateTypeDeclarations();
const cjsCtx = await esbuild.context(cjsConfig); const cjsCtx = await esbuild.context(cjsConfig);
const esmCtx = await esbuild.context(esmConfig); const esmCtx = await esbuild.context(esmConfig);
@@ -53,6 +129,7 @@ async function build() {
console.log("✅ Build completed successfully!"); console.log("✅ Build completed successfully!");
console.log(" - CJS: dist/cjs/server.cjs"); console.log(" - CJS: dist/cjs/server.cjs");
console.log(" - ESM: dist/esm/server.mjs"); console.log(" - ESM: dist/esm/server.mjs");
console.log(" - Types: dist/*.d.ts");
} }
} }

View File

@@ -0,0 +1,60 @@
import * as esbuild from "esbuild";
import * as path from "path";
import * as fs from "fs";
/**
* esbuild plugin to resolve @/ path aliases
* Converts @/ imports to relative paths based on baseUrl
*/
export const pathAliasPlugin = (options: {
alias: Record<string, string>;
baseUrl: string;
}): esbuild.Plugin => {
return {
name: "path-alias",
setup(build) {
const { alias, baseUrl } = options;
// Resolve each alias pattern
for (const [pattern, target] of Object.entries(alias)) {
// Remove trailing /* from pattern if present
const patternKey = pattern.replace(/\/\*$/, "");
// Escape special regex characters in pattern
const escapedPattern = patternKey.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
build.onResolve(
{ filter: new RegExp(`^${escapedPattern}/`) },
(args) => {
// Extract the path after @/
const importPath = args.path.replace(new RegExp(`^${escapedPattern}/`), "");
// Remove file extension if present in import
const importPathWithoutExt = importPath.replace(/\.[^.]+$/, "");
const resolvedPath = path.resolve(baseUrl, target.replace(/\*$/, ""), importPathWithoutExt);
// Try to find the file with different extensions
const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
for (const ext of extensions) {
const fileWithExt = resolvedPath + ext;
if (fs.existsSync(fileWithExt) && fs.statSync(fileWithExt).isFile()) {
return { path: fileWithExt };
}
}
// Check if it's a directory with index file
if (fs.existsSync(resolvedPath) && fs.statSync(resolvedPath).isDirectory()) {
for (const ext of extensions) {
const indexPath = path.join(resolvedPath, `index${ext}`);
if (fs.existsSync(indexPath) && fs.statSync(indexPath).isFile()) {
return { path: indexPath };
}
}
}
// Return resolved path even if file doesn't exist (esbuild will handle error)
return { path: resolvedPath + ".ts" };
}
);
}
},
};
};