From 3f7ff71720c9447e6c99e3a59cf13c4f096d6d4a Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Thu, 8 Aug 2024 19:53:28 +0800 Subject: [PATCH 1/4] feat: support DTS bundle file name --- e2e/cases/dts/bundle/bundleName.config.ts | 18 ++++++++++++++++ e2e/cases/dts/index.test.ts | 11 ++++++++++ packages/plugin-dts/src/apiExtractor.ts | 10 +++++---- packages/plugin-dts/src/dts.ts | 8 +++++-- packages/plugin-dts/src/index.ts | 21 +++++++++++++++--- packages/plugin-dts/src/utils.ts | 26 ++++++++++++++++++++++- 6 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 e2e/cases/dts/bundle/bundleName.config.ts diff --git a/e2e/cases/dts/bundle/bundleName.config.ts b/e2e/cases/dts/bundle/bundleName.config.ts new file mode 100644 index 000000000..6cdca50fa --- /dev/null +++ b/e2e/cases/dts/bundle/bundleName.config.ts @@ -0,0 +1,18 @@ +import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper'; +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig(__dirname, { + dts: { + bundle: true, + }, + }), + generateBundleCjsConfig(__dirname), + ], + source: { + entry: { + bundleName: './src/index.ts', + }, + }, +}); diff --git a/e2e/cases/dts/index.test.ts b/e2e/cases/dts/index.test.ts index 08a8f5ae2..4aa50d7cc 100644 --- a/e2e/cases/dts/index.test.ts +++ b/e2e/cases/dts/index.test.ts @@ -137,4 +137,15 @@ describe('dts when bundle: true', () => { expect(entryFiles.cjs).toEqual('./dist/cjs/index.d.cts'); }); + + test('bundleName -- set source.entry', async () => { + const fixturePath = join(__dirname, 'bundle'); + const { entryFiles } = await buildAndGetResults( + fixturePath, + 'bundleName.config.ts', + 'dts', + ); + + expect(entryFiles.esm).toEqual('./dist/esm/bundleName.d.ts'); + }); }); diff --git a/packages/plugin-dts/src/apiExtractor.ts b/packages/plugin-dts/src/apiExtractor.ts index a92e1a00a..0426f6750 100644 --- a/packages/plugin-dts/src/apiExtractor.ts +++ b/packages/plugin-dts/src/apiExtractor.ts @@ -6,6 +6,7 @@ import { } from '@microsoft/api-extractor'; import { logger } from '@rsbuild/core'; import color from 'picocolors'; +import type { DtsEntry } from 'src'; import { getTimeCost } from './utils'; export type BundleOptions = { @@ -13,7 +14,7 @@ export type BundleOptions = { cwd: string; outDir: string; dtsExtension: string; - entry?: string; + dtsEntry: DtsEntry; tsconfigPath?: string; }; @@ -23,7 +24,7 @@ export async function bundleDts(options: BundleOptions): Promise { cwd, outDir, dtsExtension, - entry = 'index.d.ts', + dtsEntry, tsconfigPath = 'tsconfig.json', } = options; try { @@ -31,10 +32,11 @@ export async function bundleDts(options: BundleOptions): Promise { const untrimmedFilePath = join( cwd, relative(cwd, outDir), - `index${dtsExtension}`, + `${dtsEntry.name ?? 'index'}${dtsExtension}`, ); + const mainEntryPointFilePath = dtsEntry.path ?? 'index.d.ts'; const internalConfig = { - mainEntryPointFilePath: entry, + mainEntryPointFilePath, // TODO: use !externals // bundledPackages: [], dtsRollup: { diff --git a/packages/plugin-dts/src/dts.ts b/packages/plugin-dts/src/dts.ts index d6babe2e2..f72786a7b 100644 --- a/packages/plugin-dts/src/dts.ts +++ b/packages/plugin-dts/src/dts.ts @@ -10,7 +10,7 @@ export async function generateDts(data: DtsGenOptions): Promise { const { bundle, distPath, - entryPath, + dtsEntry, tsconfigPath, name, cwd, @@ -37,6 +37,7 @@ export async function generateDts(data: DtsGenOptions): Promise { }; const declarationDir = getDeclarationDir(bundle!, distPath); + const { name: entryName, path: entryPath } = dtsEntry; let entry = ''; if (bundle === true && entryPath) { @@ -59,7 +60,10 @@ export async function generateDts(data: DtsGenOptions): Promise { name, cwd, outDir, - entry, + dtsEntry: { + name: entryName, + path: entry, + }, tsconfigPath, dtsExtension, }); diff --git a/packages/plugin-dts/src/index.ts b/packages/plugin-dts/src/index.ts index 648c506bd..5e1e474d3 100644 --- a/packages/plugin-dts/src/index.ts +++ b/packages/plugin-dts/src/index.ts @@ -1,6 +1,7 @@ import { fork } from 'node:child_process'; import { extname, join } from 'node:path'; import { type RsbuildPlugin, logger } from '@rsbuild/core'; +import { processSourceEntry } from './utils'; export type PluginDtsOptions = { bundle?: boolean; @@ -9,11 +10,16 @@ export type PluginDtsOptions = { dtsExtension?: string; }; +export type DtsEntry = { + name?: string; + path?: string; +}; + export type DtsGenOptions = PluginDtsOptions & { name: string; cwd: string; isWatch: boolean; - entryPath?: string; + dtsEntry: DtsEntry; tsconfigPath?: string; }; @@ -54,10 +60,19 @@ export const pluginDts = (options: PluginDtsOptions): RsbuildPlugin => ({ stdio: 'inherit', }); + let dtsEntry: DtsEntry = { + name: undefined, + path: undefined, + }; + + if (options.bundle) { + // TODO: temporarily use first element of Record + dtsEntry = processSourceEntry(config.source?.entry); + } + const dtsGenOptions: DtsGenOptions = { ...options, - // TODO: temporarily use main as dts entry, only accept single entry - entryPath: config.source?.entry?.main as string, + dtsEntry, tsconfigPath: config.source.tsconfigPath, name: environment.name, cwd: api.context.rootPath, diff --git a/packages/plugin-dts/src/utils.ts b/packages/plugin-dts/src/utils.ts index 320adef90..8a7a89e77 100644 --- a/packages/plugin-dts/src/utils.ts +++ b/packages/plugin-dts/src/utils.ts @@ -1,8 +1,9 @@ import fs from 'node:fs'; import path from 'node:path'; -import { logger } from '@rsbuild/core'; +import { type RsbuildConfig, logger } from '@rsbuild/core'; import fg from 'fast-glob'; import color from 'picocolors'; +import type { DtsEntry } from 'src'; import * as ts from 'typescript'; export function loadTsconfig(tsconfigPath: string): ts.ParsedCommandLine { @@ -70,3 +71,26 @@ export async function processDtsFiles( } } } + +export function processSourceEntry( + entryConfig: NonNullable['entry'], +): DtsEntry { + if ( + entryConfig && + Object.values(entryConfig).every((val) => typeof val === 'string') + ) { + return { + name: Object.keys(entryConfig)[0] as string, + path: Object.values(entryConfig)[0] as string, + }; + } + + logger.warn( + '@microsoft/api-extractor only support single entry of Record type to bundle DTS.', + ); + + return { + name: undefined, + path: undefined, + }; +} From 64c8a7d8f40b3c848efd67846f8eb1baea2242fd Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Thu, 8 Aug 2024 20:09:49 +0800 Subject: [PATCH 2/4] chore: update --- e2e/cases/dts/index.test.ts | 6 +++--- packages/plugin-dts/src/apiExtractor.ts | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/e2e/cases/dts/index.test.ts b/e2e/cases/dts/index.test.ts index 4aa50d7cc..08e0a903d 100644 --- a/e2e/cases/dts/index.test.ts +++ b/e2e/cases/dts/index.test.ts @@ -90,7 +90,7 @@ describe('dts when bundle: true', () => { 'dts', ); - expect(entryFiles.esm).toEqual('./dist/esm/index.d.ts'); + expect(entryFiles.esm).toEqual('./dist/esm/main.d.ts'); expect(entries).toMatchSnapshot(); }); @@ -113,7 +113,7 @@ describe('dts when bundle: true', () => { 'dts', ); - expect(entryFiles.esm).toEqual('./dist/custom/index.d.ts'); + expect(entryFiles.esm).toEqual('./dist/custom/main.d.ts'); }); test('abortOnError: false', async () => { @@ -135,7 +135,7 @@ describe('dts when bundle: true', () => { 'dts', ); - expect(entryFiles.cjs).toEqual('./dist/cjs/index.d.cts'); + expect(entryFiles.cjs).toEqual('./dist/cjs/main.d.cts'); }); test('bundleName -- set source.entry', async () => { diff --git a/packages/plugin-dts/src/apiExtractor.ts b/packages/plugin-dts/src/apiExtractor.ts index 0426f6750..60ee74bdd 100644 --- a/packages/plugin-dts/src/apiExtractor.ts +++ b/packages/plugin-dts/src/apiExtractor.ts @@ -14,7 +14,7 @@ export type BundleOptions = { cwd: string; outDir: string; dtsExtension: string; - dtsEntry: DtsEntry; + dtsEntry: Required; tsconfigPath?: string; }; @@ -24,7 +24,10 @@ export async function bundleDts(options: BundleOptions): Promise { cwd, outDir, dtsExtension, - dtsEntry, + dtsEntry = { + name: 'index', + path: 'index.d.ts', + }, tsconfigPath = 'tsconfig.json', } = options; try { @@ -32,9 +35,9 @@ export async function bundleDts(options: BundleOptions): Promise { const untrimmedFilePath = join( cwd, relative(cwd, outDir), - `${dtsEntry.name ?? 'index'}${dtsExtension}`, + `${dtsEntry.name}${dtsExtension}`, ); - const mainEntryPointFilePath = dtsEntry.path ?? 'index.d.ts'; + const mainEntryPointFilePath = dtsEntry.path; const internalConfig = { mainEntryPointFilePath, // TODO: use !externals From 441d4e33e667ec8c36dfda30b545183d02f7cd15 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Thu, 8 Aug 2024 20:13:30 +0800 Subject: [PATCH 3/4] chore: update --- packages/plugin-dts/src/apiExtractor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin-dts/src/apiExtractor.ts b/packages/plugin-dts/src/apiExtractor.ts index 60ee74bdd..e0106e153 100644 --- a/packages/plugin-dts/src/apiExtractor.ts +++ b/packages/plugin-dts/src/apiExtractor.ts @@ -14,7 +14,7 @@ export type BundleOptions = { cwd: string; outDir: string; dtsExtension: string; - dtsEntry: Required; + dtsEntry: DtsEntry; tsconfigPath?: string; }; @@ -37,7 +37,7 @@ export async function bundleDts(options: BundleOptions): Promise { relative(cwd, outDir), `${dtsEntry.name}${dtsExtension}`, ); - const mainEntryPointFilePath = dtsEntry.path; + const mainEntryPointFilePath = dtsEntry.path!; const internalConfig = { mainEntryPointFilePath, // TODO: use !externals From af2db53cf094d6ed9c2bcd0fcd51b4e2fbb8977e Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Fri, 9 Aug 2024 15:22:43 +0800 Subject: [PATCH 4/4] chore: update --- packages/plugin-dts/src/dts.ts | 1 + packages/plugin-dts/src/index.ts | 15 ++++++--------- packages/plugin-dts/src/utils.ts | 17 ++++++++++------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/plugin-dts/src/dts.ts b/packages/plugin-dts/src/dts.ts index f72786a7b..3f1e6b770 100644 --- a/packages/plugin-dts/src/dts.ts +++ b/packages/plugin-dts/src/dts.ts @@ -103,6 +103,7 @@ process.on('message', async (data: DtsGenOptions) => { try { await generateDts(data); } catch (e) { + logger.error(e); process.send!('error'); process.exit(1); } diff --git a/packages/plugin-dts/src/index.ts b/packages/plugin-dts/src/index.ts index 5e1e474d3..1ac77743c 100644 --- a/packages/plugin-dts/src/index.ts +++ b/packages/plugin-dts/src/index.ts @@ -60,15 +60,12 @@ export const pluginDts = (options: PluginDtsOptions): RsbuildPlugin => ({ stdio: 'inherit', }); - let dtsEntry: DtsEntry = { - name: undefined, - path: undefined, - }; - - if (options.bundle) { - // TODO: temporarily use first element of Record - dtsEntry = processSourceEntry(config.source?.entry); - } + // TODO: @microsoft/api-extractor only support single entry to bundle DTS + // use first element of Record type entry config + const dtsEntry = processSourceEntry( + options.bundle!, + config.source?.entry, + ); const dtsGenOptions: DtsGenOptions = { ...options, diff --git a/packages/plugin-dts/src/utils.ts b/packages/plugin-dts/src/utils.ts index 8a7a89e77..942006552 100644 --- a/packages/plugin-dts/src/utils.ts +++ b/packages/plugin-dts/src/utils.ts @@ -73,8 +73,16 @@ export async function processDtsFiles( } export function processSourceEntry( + bundle: boolean, entryConfig: NonNullable['entry'], ): DtsEntry { + if (!bundle) { + return { + name: undefined, + path: undefined, + }; + } + if ( entryConfig && Object.values(entryConfig).every((val) => typeof val === 'string') @@ -85,12 +93,7 @@ export function processSourceEntry( }; } - logger.warn( - '@microsoft/api-extractor only support single entry of Record type to bundle DTS.', + throw new Error( + '@microsoft/api-extractor only support single entry of Record type to bundle DTS, please check your entry config.', ); - - return { - name: undefined, - path: undefined, - }; }