rsbuild-plugin-dts
Version:
Rsbuild plugin that supports emitting declaration files for TypeScript.
97 lines (96 loc) • 6.29 kB
JavaScript
import * as __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__ from "node:child_process";
import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
import * as __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__ from "node:url";
import * as __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__ from "@rsbuild/core";
import * as __WEBPACK_EXTERNAL_MODULE_picocolors__ from "picocolors";
import * as __WEBPACK_EXTERNAL_MODULE_typescript__ from "typescript";
import * as __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__ from "./utils.js";
const src_rslib_entry_filename = (0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.fileURLToPath)(import.meta.url);
const src_rslib_entry_dirname = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.dirname)(src_rslib_entry_filename);
const PLUGIN_DTS_NAME = 'rsbuild:dts';
const pluginDts = (options = {})=>({
name: PLUGIN_DTS_NAME,
setup (api) {
options.bundle = options.bundle ?? false;
options.abortOnError = options.abortOnError ?? true;
options.build = options.build ?? false;
options.redirect = options.redirect ?? {};
options.redirect.path = options.redirect.path ?? true;
options.redirect.extension = options.redirect.extension ?? false;
const dtsPromises = [];
let promisesResult = [];
let childProcesses = [];
api.onBeforeEnvironmentCompile(async ({ isWatch, isFirstCompile, environment })=>{
if (!isFirstCompile) return;
const { config } = environment;
const dtsEntry = (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.processSourceEntry)(options.bundle, config.source?.entry);
const cwd = api.context.rootPath;
const tsconfigPath = __WEBPACK_EXTERNAL_MODULE_typescript__["default"].findConfigFile(cwd, __WEBPACK_EXTERNAL_MODULE_typescript__["default"].sys.fileExists, config.source.tsconfigPath);
if (!tsconfigPath) {
__WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.error(`Failed to resolve tsconfig file ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(`"${config.source.tsconfigPath}"`)} from ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(cwd)}. Please ensure that the file exists.`);
throw new Error();
}
const tsConfigResult = (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.loadTsconfig)(tsconfigPath);
const { options: rawCompilerOptions } = tsConfigResult;
const { declarationDir, outDir, composite, incremental } = rawCompilerOptions;
const dtsEmitPath = (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.getDtsEmitPath)(options.distPath, declarationDir, config.output?.distPath?.root);
(0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.warnIfOutside)(cwd, declarationDir, 'declarationDir');
(0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.warnIfOutside)(cwd, outDir, 'outDir');
if (false !== config.output.cleanDistPath) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.cleanDtsFiles)(dtsEmitPath);
if (options.bundle) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.clearTempDeclarationDir)(cwd);
if (composite || incremental || options.build) await (0, __WEBPACK_EXTERNAL_MODULE__utils_js_d88b7fe1__.cleanTsBuildInfoFile)(tsconfigPath, rawCompilerOptions);
const jsExtension = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.extname)(src_rslib_entry_filename);
const childProcess = (0, __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__.fork)((0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join)(src_rslib_entry_dirname, `./dts${jsExtension}`), [], {
stdio: 'inherit'
});
childProcesses.push(childProcess);
const dtsGenOptions = {
...options,
dtsEntry,
dtsEmitPath,
userExternals: config.output.externals,
tsconfigPath,
tsConfigResult,
name: environment.name,
cwd,
isWatch
};
childProcess.send(dtsGenOptions);
dtsPromises.push(new Promise((resolve)=>{
childProcess.on('message', (message)=>{
if ('success' === message) resolve({
status: 'success'
});
else if ('error' === message) resolve({
status: 'error',
errorMessage: `Error occurred in ${environment.name} DTS generation`
});
});
}));
});
api.onAfterBuild({
handler: async ({ isFirstCompile })=>{
if (!isFirstCompile) return;
promisesResult = await Promise.all(dtsPromises);
},
order: 'pre'
});
api.onAfterBuild(({ isFirstCompile })=>{
if (!isFirstCompile) return;
for (const result of promisesResult)if ('error' === result.status) {
if (options.abortOnError) throw new Error(result.errorMessage);
result.errorMessage && __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.error(result.errorMessage);
__WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__.logger.warn('With the `abortOnError` configuration currently turned off, type errors do not cause build failures, but they do not guarantee proper type file output.');
}
});
const killProcesses = ()=>{
for (const childProcess of childProcesses)if (!childProcess.killed) try {
childProcess.kill();
} catch (_err) {}
childProcesses = [];
};
api.onCloseBuild(killProcesses);
api.onCloseDevServer(killProcesses);
}
});
export { PLUGIN_DTS_NAME, pluginDts };