Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support DTS bundle file name #75

Merged
merged 4 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
18 changes: 18 additions & 0 deletions e2e/cases/dts/bundle/bundleName.config.ts
Original file line number Diff line number Diff line change
@@ -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',
},
},
});
17 changes: 14 additions & 3 deletions e2e/cases/dts/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});

Expand All @@ -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 () => {
Expand All @@ -135,6 +135,17 @@ 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 () => {
const fixturePath = join(__dirname, 'bundle');
const { entryFiles } = await buildAndGetResults(
fixturePath,
'bundleName.config.ts',
'dts',
);

expect(entryFiles.esm).toEqual('./dist/esm/bundleName.d.ts');
});
});
13 changes: 9 additions & 4 deletions packages/plugin-dts/src/apiExtractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ 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 = {
name: string;
cwd: string;
outDir: string;
dtsExtension: string;
entry?: string;
dtsEntry: DtsEntry;
tsconfigPath?: string;
};

Expand All @@ -23,18 +24,22 @@ export async function bundleDts(options: BundleOptions): Promise<void> {
cwd,
outDir,
dtsExtension,
entry = 'index.d.ts',
dtsEntry = {
name: 'index',
path: 'index.d.ts',
},
tsconfigPath = 'tsconfig.json',
} = options;
try {
const start = Date.now();
const untrimmedFilePath = join(
cwd,
relative(cwd, outDir),
`index${dtsExtension}`,
`${dtsEntry.name}${dtsExtension}`,
);
const mainEntryPointFilePath = dtsEntry.path!;
const internalConfig = {
mainEntryPointFilePath: entry,
mainEntryPointFilePath,
// TODO: use !externals
// bundledPackages: [],
dtsRollup: {
Expand Down
9 changes: 7 additions & 2 deletions packages/plugin-dts/src/dts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export async function generateDts(data: DtsGenOptions): Promise<void> {
const {
bundle,
distPath,
entryPath,
dtsEntry,
tsconfigPath,
name,
cwd,
Expand All @@ -37,6 +37,7 @@ export async function generateDts(data: DtsGenOptions): Promise<void> {
};

const declarationDir = getDeclarationDir(bundle!, distPath);
const { name: entryName, path: entryPath } = dtsEntry;
let entry = '';

if (bundle === true && entryPath) {
Expand All @@ -59,7 +60,10 @@ export async function generateDts(data: DtsGenOptions): Promise<void> {
name,
cwd,
outDir,
entry,
dtsEntry: {
name: entryName,
path: entry,
},
tsconfigPath,
dtsExtension,
});
Expand Down Expand Up @@ -99,6 +103,7 @@ process.on('message', async (data: DtsGenOptions) => {
try {
await generateDts(data);
} catch (e) {
logger.error(e);
process.send!('error');
process.exit(1);
}
Expand Down
18 changes: 15 additions & 3 deletions packages/plugin-dts/src/index.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
};

Expand Down Expand Up @@ -54,10 +60,16 @@ export const pluginDts = (options: PluginDtsOptions): RsbuildPlugin => ({
stdio: 'inherit',
});

// TODO: @microsoft/api-extractor only support single entry to bundle DTS
// use first element of Record<string, string> type entry config
const dtsEntry = processSourceEntry(
options.bundle!,
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,
Expand Down
29 changes: 28 additions & 1 deletion packages/plugin-dts/src/utils.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -70,3 +71,29 @@ export async function processDtsFiles(
}
}
}

export function processSourceEntry(
bundle: boolean,
entryConfig: NonNullable<RsbuildConfig['source']>['entry'],
): DtsEntry {
if (!bundle) {
return {
name: undefined,
path: undefined,
};
}

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,
};
}

throw new Error(
'@microsoft/api-extractor only support single entry of Record<string, string> type to bundle DTS, please check your entry config.',
);
}
Loading