UNPKG

zshy

Version:

Gold-standard build tool for TypeScript libraries

240 lines 11.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.compileProject = compileProject; const fs = __importStar(require("node:fs")); const path = __importStar(require("node:path")); const ts = __importStar(require("typescript")); const tx_cjs_interop_js_1 = require("./tx-cjs-interop.cjs"); const tx_cjs_interop_declaration_js_1 = require("./tx-cjs-interop-declaration.cjs"); const tx_export_equals_js_1 = require("./tx-export-equals.cjs"); const tx_extension_rewrite_js_1 = require("./tx-extension-rewrite.cjs"); const tx_import_meta_shim_js_1 = require("./tx-import-meta-shim.cjs"); const utils = __importStar(require("./utils.cjs")); async function compileProject(config, entryPoints, ctx) { // Deduplicate entry points before compilation // Track asset imports encountered during transformation const assetImports = new Set(); // Create compiler host const host = ts.createCompilerHost(config.compilerOptions); const originalWriteFile = host.writeFile; const jsExt = "." + config.ext; const dtsExt = config.ext === "mjs" ? ".d.mts" : config.ext === "cjs" ? ".d.cts" : ".d.ts"; // Track if we should write files (will be set after diagnostics check) let shouldWriteFiles = true; host.writeFile = (fileName, data, writeByteOrderMark, onError, sourceFiles) => { // Transform output file extensions let outputFileName = fileName; const processedData = data; if (fileName.endsWith(".js")) { outputFileName = fileName.replace(/\.js$/, jsExt); } if (fileName.endsWith(".d.ts")) { outputFileName = fileName.replace(/\.d\.ts$/, dtsExt); } // Handle source map files if (fileName.endsWith(".js.map")) { outputFileName = fileName.replace(/\.js\.map$/, jsExt + ".map"); } if (fileName.endsWith(".d.ts.map")) { outputFileName = fileName.replace(/\.d\.ts\.map$/, dtsExt + ".map"); } // Track the file that would be written ctx.writtenFiles.add(outputFileName); if (!config.dryRun && shouldWriteFiles && originalWriteFile) { originalWriteFile(outputFileName, processedData, writeByteOrderMark, onError, sourceFiles); } }; // Create the TypeScript program using unique entry points // For CJS builds, set noEmitOnError to false to allow emission despite ts1343 errors const programOptions = config.compilerOptions; const program = ts.createProgram({ rootNames: entryPoints, options: programOptions, host, }); // Create a transformer factory to rewrite extensions const extensionRewriteTransformer = (0, tx_extension_rewrite_js_1.createExtensionRewriteTransformer)({ rootDir: config.rootDir, ext: jsExt, onAssetImport: (assetPath) => { assetImports.add(assetPath); }, }); // Check for semantic errors const diagnostics = ts.getPreEmitDiagnostics(program); if (diagnostics.length > 0) { // Filter out ts1343 errors for CJS builds const filteredDiagnostics = diagnostics.filter((d) => { if (config.format === "cjs") { return d.code !== 1343 && d.code !== 1259; } }); // Ignore ts1343 (import.meta not available) for CJS const errorCount = filteredDiagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error).length; const warningCount = filteredDiagnostics.filter((d) => d.category === ts.DiagnosticCategory.Warning).length; // Update the build context with error and warning counts ctx.errorCount += errorCount; ctx.warningCount += warningCount; // Set shouldWriteFiles to false if there are errors (excluding ts1343 for CJS) if (errorCount > 0) { shouldWriteFiles = false; } if (errorCount > 0 || warningCount > 0) { utils.emojiLog("⚠️", `Found ${errorCount} error(s) and ${warningCount} warning(s)`, "warn"); } // Format diagnostics with color and context like tsc, keeping original order const formatHost = { getCurrentDirectory: () => process.cwd(), getCanonicalFileName: (fileName) => fileName, getNewLine: () => ts.sys.newLine, }; // Keep errors and warnings intermixed in their original order const relevantDiagnostics = filteredDiagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error || d.category === ts.DiagnosticCategory.Warning); if (relevantDiagnostics.length > 0) { console.log(ts.formatDiagnosticsWithColorAndContext(relevantDiagnostics, formatHost)); } } // Prepare transformers const before = [ extensionRewriteTransformer, ]; const after = []; const afterDeclarations = [extensionRewriteTransformer]; // Add import.meta shim transformer for CJS builds if (config.format === "cjs") { before.unshift((0, tx_import_meta_shim_js_1.createImportMetaShimTransformer)()); } // Add export = to export default transformer for ESM builds if (config.format === "esm") { (0, tx_export_equals_js_1.createExportEqualsTransformer)(); // before.push(createExportEqualsTransformer<ts.SourceFile>()); // afterDeclarations.push(createExportEqualsTransformer<ts.SourceFile | ts.Bundle>()); } // Add CJS interop transformer for single default exports if (config.cjsInterop && config.format === "cjs") { if (config.verbose) { utils.emojiLog("🔄", `Enabling CJS interop transform...`); } before.push((0, tx_cjs_interop_js_1.createCjsInteropTransformer)()); } // Add CJS interop transformer for declaration files (export = transformation) if (config.cjsInterop && config.format === "cjs") { afterDeclarations.push((0, tx_cjs_interop_declaration_js_1.createCjsInteropDeclarationTransformer)()); } // emit the files const emitResult = program.emit(undefined, undefined, undefined, undefined, { before, after, afterDeclarations, }); if (emitResult.emitSkipped) { utils.emojiLog("❌", "Emit was skipped due to errors", "error"); } else { // console.log(`✅ Emitted ${config.jsExtension} and ${config.dtsExtension} // files`); } // Report any emit diagnostics if (emitResult.diagnostics.length > 0) { // Filter out ts1343 errors for CJS builds const filteredEmitDiagnostics = config.format === "cjs" ? emitResult.diagnostics.filter((d) => d.code !== 1343) // Ignore ts1343 for CJS : emitResult.diagnostics; const emitErrors = filteredEmitDiagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error); const emitWarnings = filteredEmitDiagnostics.filter((d) => d.category === ts.DiagnosticCategory.Warning); // Update the build context with emit error and warning counts ctx.errorCount += emitErrors.length; ctx.warningCount += emitWarnings.length; utils.emojiLog("❌", `Found ${emitErrors.length} error(s) and ${emitWarnings.length} warning(s) during emit:`, "error"); console.log(); const formatHost = { getCurrentDirectory: () => process.cwd(), getCanonicalFileName: (fileName) => fileName, getNewLine: () => ts.sys.newLine, }; // Keep errors and warnings intermixed in their original order const relevantEmitDiagnostics = filteredEmitDiagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error || d.category === ts.DiagnosticCategory.Warning); if (relevantEmitDiagnostics.length > 0) { console.log(ts.formatDiagnosticsWithColorAndContext(relevantEmitDiagnostics, formatHost)); } } // Copy assets if any were found and rootDir is provided if (assetImports.size > 0) { if (config.verbose) { utils.emojiLog("📄", `Found ${assetImports.size} asset import(s), copying to output directory...`); } // utils.copyAssets(assetImports, config, ctx); for (const assetPath of assetImports) { try { // Asset paths are now relative to rootDir const sourceFile = path.resolve(config.rootDir, assetPath); if (!fs.existsSync(sourceFile)) { if (config.verbose) { utils.emojiLog("⚠️", `Asset not found: ${assetPath} (resolved to ${sourceFile})`, "warn"); } continue; } // Create the destination path in outDir, maintaining the same relative structure const destFile = path.resolve(config.compilerOptions.outDir, assetPath); const posixDestFile = utils.toPosix(destFile); // Skip if this asset has already been copied if (ctx.copiedAssets.has(posixDestFile)) { continue; } const destDir = path.dirname(destFile); // Track the file that would be copied // Use posix paths here because typescript also outputs them posix // style. ctx.writtenFiles.add(posixDestFile); ctx.copiedAssets.add(posixDestFile); if (!config.dryRun) { // Ensure destination directory exists fs.mkdirSync(destDir, { recursive: true }); // Copy the file fs.copyFileSync(sourceFile, destFile); } if (config.verbose) { const relativeSource = config.pkgJsonDir ? utils.relativePosix(config.pkgJsonDir, sourceFile) : sourceFile; const relativeDest = config.pkgJsonDir ? utils.relativePosix(config.pkgJsonDir, destFile) : destFile; utils.emojiLog("📄", `${config.dryRun ? "[dryrun] " : ""}Copied asset: ./${relativeSource} → ./${relativeDest}`); } } catch (error) { utils.emojiLog("❌", `Failed to copy asset ${assetPath}: ${error}`, "error"); } } } } //# sourceMappingURL=compile.js.map