Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/plugin-dts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import { dirname, extname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { logger, type RsbuildConfig, type RsbuildPlugin } from '@rsbuild/core';
import color from 'picocolors';
import ts from 'typescript';
import type { ParsedCommandLine } from 'typescript';

import {
cleanDtsFiles,
cleanTsBuildInfoFile,
clearTempDeclarationDir,
getDtsEmitPath,
loadTsconfig,
processSourceEntry,
ts,
warnIfOutside,
} from './utils';

Expand Down Expand Up @@ -61,7 +63,7 @@ export type DtsGenOptions = Omit<PluginDtsOptions, 'bundle'> & {
dtsEmitPath: string;
build?: boolean;
tsconfigPath: string;
tsConfigResult: ts.ParsedCommandLine;
tsConfigResult: ParsedCommandLine;
userExternals?: NonNullable<RsbuildConfig['output']>['externals'];
apiExtractorOptions?: ApiExtractorOptions;
};
Expand Down
41 changes: 25 additions & 16 deletions packages/plugin-dts/src/tsc.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import { logger } from '@rsbuild/core';
import color from 'picocolors';
import ts from 'typescript';
import type {
CompilerHost,
CompilerOptions,
Diagnostic,
FormatDiagnosticsHost,
ParsedCommandLine,
Program,
System,
WatchStatusReporter,
} from 'typescript';
import type { DtsRedirect } from './index';
import {
getTimeCost,
processDtsFiles,
renameDtsFile,
ts,
updateDeclarationMapContent,
} from './utils';

const logPrefixTsc = color.dim('[tsc]');

const formatHost: ts.FormatDiagnosticsHost = {
const formatHost: FormatDiagnosticsHost = {
getCanonicalFileName: (path) => path,
getCurrentDirectory: ts.sys.getCurrentDirectory.bind(ts.sys),
getNewLine: () => ts.sys.newLine,
Expand All @@ -21,7 +31,7 @@ export type EmitDtsOptions = {
name: string;
cwd: string;
configPath: string;
tsConfigResult: ts.ParsedCommandLine;
tsConfigResult: ParsedCommandLine;
declarationDir: string;
dtsExtension: string;
rootDir: string;
Expand All @@ -32,7 +42,7 @@ export type EmitDtsOptions = {
};

async function handleDiagnosticsAndProcessFiles(
diagnostics: readonly ts.Diagnostic[],
diagnostics: readonly Diagnostic[],
configPath: string,
bundle: boolean,
declarationDir: string,
Expand Down Expand Up @@ -117,17 +127,17 @@ export async function emitDtsTsc(

const createProgram = ts.createSemanticDiagnosticsBuilderProgram;

const reportDiagnostic = (diagnostic: ts.Diagnostic) => {
const reportDiagnostic = (diagnostic: Diagnostic) => {
logger.error(
logPrefixTsc,
ts.formatDiagnosticsWithColorAndContext([diagnostic], formatHost),
);
};

const reportWatchStatusChanged: ts.WatchStatusReporter = async (
diagnostic: ts.Diagnostic,
const reportWatchStatusChanged: WatchStatusReporter = async (
diagnostic: Diagnostic,
_newLine: string,
_options: ts.CompilerOptions,
_options: CompilerOptions,
errorCount?: number,
) => {
const message = `${ts.flattenDiagnosticMessageText(
Expand Down Expand Up @@ -179,7 +189,7 @@ export async function emitDtsTsc(
}
};

const system: ts.System = {
const system: System = {
...ts.sys,
writeFile: (fileName, contents, writeByteOrderMark) => {
const newFileName = renameDtsFile(fileName, dtsExtension, bundle);
Expand All @@ -198,9 +208,8 @@ export async function emitDtsTsc(
if (!isWatch) {
// normal build - npx tsc
if (!build && !compilerOptions.composite) {
const originHost: ts.CompilerHost =
ts.createCompilerHost(compilerOptions);
const host: ts.CompilerHost = {
const originHost: CompilerHost = ts.createCompilerHost(compilerOptions);
const host: CompilerHost = {
...originHost,
writeFile: (
fileName,
Expand All @@ -227,7 +236,7 @@ export async function emitDtsTsc(
},
};

const program: ts.Program = ts.createProgram({
const program: Program = ts.createProgram({
rootNames: fileNames,
options: compilerOptions,
projectReferences,
Expand Down Expand Up @@ -257,9 +266,9 @@ export async function emitDtsTsc(
);
} else if (!build && compilerOptions.composite) {
// incremental build with composite true - npx tsc
const originHost: ts.CompilerHost =
const originHost: CompilerHost =
ts.createIncrementalCompilerHost(compilerOptions);
const host: ts.CompilerHost = {
const host: CompilerHost = {
...originHost,
writeFile: (
fileName,
Expand Down Expand Up @@ -296,7 +305,7 @@ export async function emitDtsTsc(
createProgram,
});

const allDiagnostics: ts.Diagnostic[] = [];
const allDiagnostics: Diagnostic[] = [];
allDiagnostics.push(
...program.getConfigFileParsingDiagnostics(),
...program.getSyntacticDiagnostics(),
Expand Down
30 changes: 22 additions & 8 deletions packages/plugin-dts/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'node:fs';
import fsP from 'node:fs/promises';

import { createRequire } from 'node:module';
import { platform } from 'node:os';
import path, {
basename,
Expand All @@ -12,15 +12,32 @@ import path, {
relative,
resolve,
} from 'node:path';
import { fileURLToPath } from 'node:url';
import { type NapiConfig, parseAsync } from '@ast-grep/napi';
import { logger, type RsbuildConfig } from '@rsbuild/core';
import MagicString from 'magic-string';
import color from 'picocolors';
import { convertPathToPattern, glob } from 'tinyglobby';
import { createMatchPath, loadConfig, type MatchPath } from 'tsconfig-paths';
import ts from 'typescript';
import type {
CompilerOptions,
Diagnostic,
ParsedCommandLine,
} from 'typescript';
import type { DtsEntry, DtsRedirect } from './index';

const __filename = fileURLToPath(import.meta.url);
const require = createRequire(__filename);

/**
* Currently, typescript only provides a CJS bundle, so we use require to load it
* for better startup performance. If we use `import ts from 'typescript'`,
* Node.js will use `cjs-module-lexer` to parse it, which slows down startup time.
*/
const ts = require('typescript') as typeof import('typescript');

export { ts };

const JS_EXTENSIONS: string[] = [
'js',
'mjs',
Expand All @@ -40,7 +57,7 @@ export const JS_EXTENSIONS_PATTERN: RegExp = new RegExp(
`\\.(${JS_EXTENSIONS.join('|')})$`,
);

export function loadTsconfig(tsconfigPath: string): ts.ParsedCommandLine {
export function loadTsconfig(tsconfigPath: string): ParsedCommandLine {
const configFile = ts.readConfigFile(
tsconfigPath,
ts.sys.readFile.bind(ts.sys),
Expand Down Expand Up @@ -139,10 +156,7 @@ export async function clearTempDeclarationDir(cwd: string): Promise<void> {
await emptyDir(dirPath);
}

export function getFileLoc(
diagnostic: ts.Diagnostic,
configPath: string,
): string {
export function getFileLoc(diagnostic: Diagnostic, configPath: string): string {
if (diagnostic.file) {
const { line, character } = ts.getLineAndCharacterOfPosition(
diagnostic.file,
Expand Down Expand Up @@ -605,7 +619,7 @@ export async function cleanDtsFiles(dir: string): Promise<void> {

export async function cleanTsBuildInfoFile(
tsconfigPath: string,
compilerOptions: ts.CompilerOptions,
compilerOptions: CompilerOptions,
): Promise<void> {
const tsconfigDir = dirname(tsconfigPath);
const { outDir, rootDir, tsBuildInfoFile } = compilerOptions;
Expand Down
Loading