diff --git a/.gitignore b/.gitignore index ac9cb468f..7e189dc0a 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ test-results .env.local .env.*.local .rslib/**/* +!dist-path/ \ No newline at end of file diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index b79a86973..71dffc357 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -1500,6 +1500,7 @@ const composeDtsConfig = async ( banner: banner?.dts, footer: footer?.dts, redirect: redirect?.dts, + tsgo: dts?.tsgo, }), ], }; diff --git a/packages/core/src/types/config.ts b/packages/core/src/types/config.ts index 6312f2a1f..e00f2597f 100644 --- a/packages/core/src/types/config.ts +++ b/packages/core/src/types/config.ts @@ -94,6 +94,13 @@ export type Dts = * @see {@link https://rslib.rs/config/lib/dts#dtsalias} */ alias?: Record; + /** + * Whether to generate declaration files with `tsgo`. + * @experimental + * @defaultValue `false` + * @see {@link https://rslib.rs/config/lib/dts#dtstsgo} + */ + tsgo?: boolean; } | boolean; diff --git a/packages/plugin-dts/README.md b/packages/plugin-dts/README.md index 15d80cfcc..3f3b51583 100644 --- a/packages/plugin-dts/README.md +++ b/packages/plugin-dts/README.md @@ -136,6 +136,8 @@ pluginDts({ }); ``` +> When [tsgo](#tsgo) is enabled, if the project also enables [build](#build) or emits declaration files with different extensions to the same directory, `dtsExtension` may not work correctly. + ### alias - **Type:** `Record` @@ -280,6 +282,41 @@ import { foo } from './foo.mjs'; // expected output of './dist/bar.d.mts' - When set to `false`, the file extension will remain unchanged from the original import path in the rewritten import path of the output file (regardless of whether it is specified or specified as any value). +### tsgo + +- **Type:** `boolean` +- **Default:** `false` + +Whether to generate declaration files with [tsgo](https://github.com/microsoft/typescript-go), which can provide faster generation of declaration files, especially for large projects. + +> This feature is currently an **experimental feature**. Since tsgo is still in the **experimental stage**, there may be some bugs and unresolved issues or limitations. So, make sure to fully test it in your project before enabling this option. + +To enable this option, you need to: + +1. Install [@typescript/native-preview](https://www.npmjs.com/package/@typescript/native-preview) as a development dependency. + +```bash +npm add @typescript/native-preview -D +``` + +> `@typescript/native-preview` requires Node.js 20.6.0 or higher. + +2. Set `tsgo` to `true`. + +```js +pluginDts({ + tsgo: true, +}); +``` + +3. In order to ensure the consistency of local development, you need to install the corresponding [VS Code Preview Extension](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.native-preview) and add the following configuration in the VS Code settings: + +```json +{ + "typescript.experimental.useTsgo": true +} +``` + ## Contributing Please read the [Contributing Guide](https://github.com/web-infra-dev/rslib/blob/main/CONTRIBUTING.md). diff --git a/packages/plugin-dts/package.json b/packages/plugin-dts/package.json index 246da0c4c..ea50ea2d2 100644 --- a/packages/plugin-dts/package.json +++ b/packages/plugin-dts/package.json @@ -40,6 +40,7 @@ "@microsoft/api-extractor": "^7.52.11", "@rsbuild/core": "~1.5.3", "@rslib/tsconfig": "workspace:*", + "@typescript/native-preview": "7.0.0-dev.20250904.1", "rsbuild-plugin-publint": "^0.3.3", "rslib": "npm:@rslib/core@0.12.4", "typescript": "^5.9.2" @@ -47,12 +48,16 @@ "peerDependencies": { "@microsoft/api-extractor": "^7", "@rsbuild/core": "1.x", + "@typescript/native-preview": "7.x", "typescript": "^5" }, "peerDependenciesMeta": { "@microsoft/api-extractor": { "optional": true }, + "@typescript/native-preview": { + "optional": true + }, "typescript": { "optional": true } diff --git a/packages/plugin-dts/src/dts.ts b/packages/plugin-dts/src/dts.ts index 62eb4013c..028757672 100644 --- a/packages/plugin-dts/src/dts.ts +++ b/packages/plugin-dts/src/dts.ts @@ -11,7 +11,6 @@ import { import { logger } from '@rsbuild/core'; import color from 'picocolors'; import type { DtsEntry, DtsGenOptions } from './index'; -import { emitDts } from './tsc'; import { calcLongestCommonPath, ensureTempDeclarationDir, @@ -136,6 +135,7 @@ export async function generateDts(data: DtsGenOptions): Promise { path: true, extension: false, }, + tsgo, } = data; if (!isWatch) { logger.start(`generating declaration files... ${color.dim(`(${name})`)}`); @@ -248,7 +248,11 @@ export async function generateDts(data: DtsGenOptions): Promise { } }; - await emitDts( + const emitDts = tsgo + ? await import('./tsgo').then((mod) => mod.emitDtsTsgo) + : await import('./tsc').then((mod) => mod.emitDtsTsc); + + const hasError = await emitDts( { name, cwd, @@ -268,8 +272,14 @@ export async function generateDts(data: DtsGenOptions): Promise { build, ); - if (!isWatch) { - await bundleDtsIfNeeded(); + if (tsgo) { + if (!hasError) { + await bundleDtsIfNeeded(); + } + } else { + if (!isWatch) { + await bundleDtsIfNeeded(); + } } } diff --git a/packages/plugin-dts/src/index.ts b/packages/plugin-dts/src/index.ts index 443b4b7f2..3a1cf7260 100644 --- a/packages/plugin-dts/src/index.ts +++ b/packages/plugin-dts/src/index.ts @@ -44,6 +44,7 @@ export type PluginDtsOptions = { banner?: string; footer?: string; redirect?: DtsRedirect; + tsgo?: boolean; }; export type DtsEntry = { @@ -93,6 +94,7 @@ export const pluginDts = (options: PluginDtsOptions = {}): RsbuildPlugin => ({ options.redirect.path = options.redirect.path ?? true; options.redirect.extension = options.redirect.extension ?? false; options.alias = options.alias ?? {}; + options.tsgo = options.tsgo ?? false; const dtsPromises: Promise[] = []; let promisesResult: TaskResult[] = []; @@ -100,7 +102,7 @@ export const pluginDts = (options: PluginDtsOptions = {}): RsbuildPlugin => ({ api.onBeforeEnvironmentCompile( async ({ isWatch, isFirstCompile, environment }) => { - if (!isFirstCompile) { + if (!isFirstCompile && !options.tsgo) { return; } diff --git a/packages/plugin-dts/src/tsc.ts b/packages/plugin-dts/src/tsc.ts index 40cc13d26..9bf9e1545 100644 --- a/packages/plugin-dts/src/tsc.ts +++ b/packages/plugin-dts/src/tsc.ts @@ -2,7 +2,12 @@ import { logger } from '@rsbuild/core'; import color from 'picocolors'; import ts from 'typescript'; import type { DtsRedirect } from './index'; -import { getTimeCost, processDtsFiles } from './utils'; +import { + getTimeCost, + processDtsFiles, + renameDtsFile, + updateDeclarationMapContent, +} from './utils'; const logPrefixTsc = color.dim('[tsc]'); @@ -75,7 +80,7 @@ async function handleDiagnosticsAndProcessFiles( } } -export async function emitDts( +export async function emitDtsTsc( options: EmitDtsOptions, onComplete: (isSuccess: boolean) => void, bundle = false, @@ -174,45 +179,17 @@ export async function emitDts( } }; - const renameDtsFile = (fileName: string): string => { - if (bundle) { - return fileName; - } - - if (fileName.endsWith('.d.ts.map')) { - return fileName.replace(/\.d\.ts\.map$/, `${dtsExtension}.map`); - } - - return fileName.replace(/\.d\.ts$/, dtsExtension); - }; - - const updateDeclarationMapContent = ( - fileName: string, - content: string, - ): string => { - if (bundle || !compilerOptions.declarationMap) { - return content; - } - - if (fileName.endsWith('.d.ts')) { - return content.replace( - /(\/\/# sourceMappingURL=.+)\.d\.ts\.map/g, - `$1${dtsExtension}.map`, - ); - } - - if (fileName.endsWith('.d.ts.map')) { - return content.replace(/("file":"[^"]*)\.d\.ts"/g, `$1${dtsExtension}"`); - } - - return content; - }; - const system: ts.System = { ...ts.sys, writeFile: (fileName, contents, writeByteOrderMark) => { - const newFileName = renameDtsFile(fileName); - const newContents = updateDeclarationMapContent(fileName, contents); + const newFileName = renameDtsFile(fileName, dtsExtension, bundle); + const newContents = updateDeclarationMapContent( + fileName, + contents, + dtsExtension, + bundle, + compilerOptions.declarationMap, + ); ts.sys.writeFile(newFileName, newContents, writeByteOrderMark); }, }; @@ -232,8 +209,14 @@ export async function emitDts( onError, sourceFiles, ) => { - const newFileName = renameDtsFile(fileName); - const newContents = updateDeclarationMapContent(fileName, contents); + const newFileName = renameDtsFile(fileName, dtsExtension, bundle); + const newContents = updateDeclarationMapContent( + fileName, + contents, + dtsExtension, + bundle, + compilerOptions.declarationMap, + ); originHost.writeFile( newFileName, newContents, @@ -285,8 +268,14 @@ export async function emitDts( onError, sourceFiles, ) => { - const newFileName = renameDtsFile(fileName); - const newContents = updateDeclarationMapContent(fileName, contents); + const newFileName = renameDtsFile(fileName, dtsExtension, bundle); + const newContents = updateDeclarationMapContent( + fileName, + contents, + dtsExtension, + bundle, + compilerOptions.declarationMap, + ); originHost.writeFile( newFileName, newContents, diff --git a/packages/plugin-dts/src/tsgo.ts b/packages/plugin-dts/src/tsgo.ts new file mode 100644 index 000000000..0523c1f16 --- /dev/null +++ b/packages/plugin-dts/src/tsgo.ts @@ -0,0 +1,229 @@ +import { spawn } from 'node:child_process'; +import fsP from 'node:fs/promises'; +import { createRequire } from 'node:module'; +import path from 'node:path'; +import { logger } from '@rsbuild/core'; +import color from 'picocolors'; +import type ts from 'typescript'; +import type { DtsRedirect } from './index'; +import type { EmitDtsOptions } from './tsc'; +import { + getTimeCost, + globDtsFiles, + processDtsFiles, + renameDtsFile, + updateDeclarationMapContent, +} from './utils'; + +const require = createRequire(import.meta.url); + +const logPrefixTsgo = color.dim('[tsgo]'); + +const getTsgoBinPath = async (): Promise => { + const tsgoPkgPath = require.resolve( + '@typescript/native-preview/package.json', + ); + + const libPath = path.resolve( + path.dirname(tsgoPkgPath), + './lib/getExePath.js', + ); + + return import(libPath).then((mod) => { + const getExePath = mod.default; + return getExePath(); + }); +}; + +const generateTsgoArgs = ( + configPath: string, + declarationDir: string, + build: boolean, + isWatch: boolean, +): string[] => { + const args: string[] = []; + + if (build) { + args.push('--build', configPath); + } else { + args.push('--project', configPath); + args.push('--declarationDir', declarationDir); + } + + args.push('--noEmit', 'false'); + args.push('--declaration'); + args.push('--emitDeclarationOnly'); + + if (isWatch) { + // TODO: Enable watch mode when tsgo's watch support is ready. + // Currently, watch mode is proof-of-concept only. + // args.push('--watch'); + } + + return args; +}; + +async function handleDiagnosticsAndProcessFiles( + isWatch: boolean, + hasErrors: boolean, + tsConfigResult: ts.ParsedCommandLine, + configPath: string, + bundle: boolean, + declarationDir: string, + dtsExtension: string, + redirect: DtsRedirect, + rootDir: string, + paths: Record, + banner?: string, + footer?: string, + name?: string, +): Promise { + if (!bundle) { + const dtsFiles = await globDtsFiles(declarationDir, [ + '/**/*.d.ts', + '/**/*.d.ts.map', + ]); + await Promise.all( + dtsFiles.map(async (file) => { + const contents = await fsP.readFile(file, 'utf8'); + const newFileName = renameDtsFile(file, dtsExtension, bundle); + const newContents = updateDeclarationMapContent( + file, + contents, + dtsExtension, + bundle, + tsConfigResult.options.declarationMap, + ); + if (file !== newFileName || contents !== newContents) { + await fsP.writeFile(newFileName, newContents); + await fsP.unlink(file); + } + }), + ); + } + + await processDtsFiles( + bundle, + declarationDir, + dtsExtension, + redirect, + configPath, + rootDir, + paths, + banner, + footer, + ); + + if (hasErrors && !isWatch) { + const error = new Error( + `Failed to generate declaration files. ${color.dim(`(${name})`)}`, + ); + // do not log the stack trace, diagnostic messages are enough + error.stack = ''; + throw error; + } +} + +export async function emitDtsTsgo( + options: EmitDtsOptions, + _onComplete: (isSuccess: boolean) => void, + bundle = false, + isWatch = false, + build = false, +): Promise { + const start = Date.now(); + const { + configPath, + tsConfigResult, + declarationDir, + name, + dtsExtension, + rootDir, + banner, + footer, + paths, + redirect, + cwd, + } = options; + + const tsgoBinFile = await getTsgoBinPath(); + const args = generateTsgoArgs(configPath, declarationDir, build, isWatch); + + logger.debug(logPrefixTsgo, `Running: ${tsgoBinFile} ${args.join(' ')}`); + + return new Promise((resolve, reject) => { + const childProcess = spawn( + tsgoBinFile, + [ + ...args, + // Required parameter to enable colored stdout + '--pretty', + ], + { + cwd, + stdio: ['inherit', 'pipe', 'pipe'], + }, + ); + + let hasErrors = false; + + childProcess.stdout?.on('data', (data) => { + const output = data.toString(); + const lines = output.split('\n'); + for (const line of lines) { + if (line.trim()) { + // Reset color for each line to avoid color bleed + console.log(color.reset(`${logPrefixTsgo} ${line}`)); + } + } + }); + + childProcess.stderr?.on('data', (data) => { + const output = data.toString(); + const lines = output.split('\n').filter((line: string) => line.trim()); + for (const line of lines) { + logger.error(logPrefixTsgo, line); + } + }); + + childProcess.on('close', async (code) => { + try { + if (code !== 0) { + hasErrors = true; + } + + await handleDiagnosticsAndProcessFiles( + isWatch, + hasErrors, + tsConfigResult, + configPath, + bundle, + declarationDir, + dtsExtension, + redirect, + rootDir, + paths, + banner, + footer, + name, + ); + + if (!hasErrors) { + if (bundle) { + logger.info( + `declaration files prepared with tsgo in ${getTimeCost(start)} ${color.dim(`(${name})`)}`, + ); + } else { + logger.ready( + `declaration files generated with tsgo in ${getTimeCost(start)} ${color.dim(`(${name})`)}`, + ); + } + } + + resolve(hasErrors); + } catch (error) { + reject(error instanceof Error ? error : new Error(String(error))); + } + }); + }); +} diff --git a/packages/plugin-dts/src/utils.ts b/packages/plugin-dts/src/utils.ts index 1b022dd96..23126694b 100644 --- a/packages/plugin-dts/src/utils.ts +++ b/packages/plugin-dts/src/utils.ts @@ -584,7 +584,10 @@ export const globDtsFiles = async ( ): Promise => { const dtsFiles = await Promise.all( patterns.map(async (pattern) => - glob(convertPath(join(dir, pattern)), { absolute: true }), + glob(convertPath(join(dir, pattern)), { + absolute: true, + dot: true, + }), ), ); @@ -662,3 +665,50 @@ export function warnIfOutside( } } } + +/** + * Rename .d.ts and .d.ts.map files with corresponding extension + */ +export function renameDtsFile( + fileName: string, + dtsExtension: string, + bundle: boolean, +): string { + if (bundle) { + return fileName; + } + + if (fileName.endsWith('.d.ts.map')) { + return fileName.replace(/\.d\.ts\.map$/, `${dtsExtension}.map`); + } + + return fileName.replace(/\.d\.ts$/, dtsExtension); +} + +/** + * Update source map content for declaration files + */ +export function updateDeclarationMapContent( + fileName: string, + content: string, + dtsExtension: string, + bundle: boolean, + hasDeclarationMap = false, +): string { + if (bundle || !hasDeclarationMap) { + return content; + } + + if (fileName.endsWith('.d.ts')) { + return content.replace( + /(\/\/# sourceMappingURL=.+)\.d\.ts\.map/g, + `$1${dtsExtension}.map`, + ); + } + + if (fileName.endsWith('.d.ts.map')) { + return content.replace(/("file":"[^"]*)\.d\.ts"/g, `$1${dtsExtension}"`); + } + + return content; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e4c8b48e2..52ca8ea6d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -450,6 +450,9 @@ importers: '@rslib/tsconfig': specifier: workspace:* version: link:../../scripts/tsconfig + '@typescript/native-preview': + specifier: 7.0.0-dev.20250904.1 + version: 7.0.0-dev.20250904.1 rsbuild-plugin-publint: specifier: ^0.3.3 version: 0.3.3(@rsbuild/core@1.5.3) @@ -711,6 +714,68 @@ importers: tests/integration/directive/shebang: {} + tests/integration/dts-tsgo/build/__references__: {} + + tests/integration/dts-tsgo/build/abort-on-error: {} + + tests/integration/dts-tsgo/build/auto-extension: {} + + tests/integration/dts-tsgo/build/basic: {} + + tests/integration/dts-tsgo/build/clean: {} + + tests/integration/dts-tsgo/build/declaration-map: {} + + tests/integration/dts-tsgo/build/dist-path: {} + + tests/integration/dts-tsgo/build/process-files: {} + + tests/integration/dts-tsgo/bundle-false/abort-on-error: {} + + tests/integration/dts-tsgo/bundle-false/alias: {} + + tests/integration/dts-tsgo/bundle-false/auto-extension: {} + + tests/integration/dts-tsgo/bundle-false/basic: {} + + tests/integration/dts-tsgo/bundle-false/clean: {} + + tests/integration/dts-tsgo/bundle-false/declaration-dir: {} + + tests/integration/dts-tsgo/bundle-false/declaration-map: {} + + tests/integration/dts-tsgo/bundle-false/dist-path: {} + + tests/integration/dts-tsgo/bundle-false/tsconfig-path: {} + + tests/integration/dts-tsgo/bundle/abort-on-error: {} + + tests/integration/dts-tsgo/bundle/absolute-entry: {} + + tests/integration/dts-tsgo/bundle/auto-extension: {} + + tests/integration/dts-tsgo/bundle/basic: {} + + tests/integration/dts-tsgo/bundle/bundle-name: {} + + tests/integration/dts-tsgo/bundle/bundled-packages: + devDependencies: + '@reduxjs/toolkit': + specifier: ^2.8.2 + version: 2.8.2(react@19.1.1) + + tests/integration/dts-tsgo/bundle/clean: {} + + tests/integration/dts-tsgo/bundle/dist-path: {} + + tests/integration/dts-tsgo/bundle/multiple-entries: {} + + tests/integration/dts-tsgo/bundle/rootdir: + devDependencies: + '@types/chromecast-caf-sender': + specifier: ^1.0.11 + version: 1.0.11 + tests/integration/dts/build/__references__: {} tests/integration/dts/build/abort-on-error: {} @@ -935,6 +1000,21 @@ importers: specifier: ^5.9.2 version: 5.9.2 + tests/integration/redirect/dts-tsgo: + devDependencies: + '@rslib/core': + specifier: workspace:* + version: link:../../../../packages/core + '@types/express': + specifier: ^5.0.3 + version: 5.0.3 + express: + specifier: ^5.1.0 + version: 5.1.0 + typescript: + specifier: ^5.9.2 + version: 5.9.2 + tests/integration/redirect/js: devDependencies: '@types/lodash': @@ -3285,6 +3365,53 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-1rt4DhERW1VM4OwWYVIrCp1k1S4kpZAxzbCnprNinVJInhHexY2K0FFD9IGXKWSRANHg/OmJRQYTEoDKM6pqNw==} + engines: {node: '>=20.6.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-d2DMQnsXAkZDDk9bU/FhY/D74tbMAkboIGb+hq7kIIgOVcxOswhwLFZ/ajW/9NTesktz8Z14t40Ber+/Pny25A==} + engines: {node: '>=20.6.0'} + cpu: [x64] + os: [darwin] + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-+fv13RDSk+7wFYY846q5ig7X6G07JT7wbajk6p4rELXTIfS1c6gRHGhODETCfFVaPziP4IlvqyinNP8F8wc9uQ==} + engines: {node: '>=20.6.0'} + cpu: [arm64] + os: [linux] + + '@typescript/native-preview-linux-arm@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-YyfTK1SGmfeDJv6G3vSmVxjM914Xio7O57NzRKOyEQnmBT5tdXTzeWgkjrUh1jE8wCUu0f0ZZ+xDTwgys+E2ug==} + engines: {node: '>=20.6.0'} + cpu: [arm] + os: [linux] + + '@typescript/native-preview-linux-x64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-BjWJI42cUUilIyQHZpQQeSjC/Ifj/UaIf4oj6lRHDcg5qgLHWe5bAUxuNjE6i7wi+TTN9YxUvBDkMAcm/hI8wg==} + engines: {node: '>=20.6.0'} + cpu: [x64] + os: [linux] + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-rPv/mVaneZTuFESk/zDg3dFiZjpdipVMcLaF10Ns1fIyWdZ0ja79Ufm1eCFbk8KFNEX2dEx+vFEvD9n4bhEneg==} + engines: {node: '>=20.6.0'} + cpu: [arm64] + os: [win32] + + '@typescript/native-preview-win32-x64@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-+twwqKYEv5UdZX5FRaBo0bDQgw/uPQjU3hqaqaO0Dhp1Ou8Ce4oi5hgwauB1j29JwBbvOi9/yoEcjsjT2Wsaxw==} + engines: {node: '>=20.6.0'} + cpu: [x64] + os: [win32] + + '@typescript/native-preview@7.0.0-dev.20250904.1': + resolution: {integrity: sha512-IzPzhumNsWsIg4Kmt0y+0b2BBtsvD17rDmKj78yNeU3AsuA6xignQ5eDkFtRmLdGPVZwa8Yg5zPcJRFln98Ocw==} + engines: {node: '>=20.6.0'} + hasBin: true + '@typescript/vfs@1.6.1': resolution: {integrity: sha512-JwoxboBh7Oz1v38tPbkrZ62ZXNHAk9bJ7c9x0eI5zBfBnBYGhURdbnh7Z4smN/MV48Y5OCcZb58n972UtbazsA==} peerDependencies: @@ -10080,6 +10207,37 @@ snapshots: '@types/unist@3.0.3': {} + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-linux-arm@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-linux-x64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview-win32-x64@7.0.0-dev.20250904.1': + optional: true + + '@typescript/native-preview@7.0.0-dev.20250904.1': + optionalDependencies: + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20250904.1 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20250904.1 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20250904.1 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20250904.1 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20250904.1 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20250904.1 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20250904.1 + '@typescript/vfs@1.6.1(typescript@5.9.2)': dependencies: debug: 4.4.1 diff --git a/scripts/dictionary.txt b/scripts/dictionary.txt index 481c9b9ae..59e1114d0 100644 --- a/scripts/dictionary.txt +++ b/scripts/dictionary.txt @@ -138,6 +138,7 @@ treeshaking tsbuildinfo tsconfck tsdoc +tsgo tsup Twoslash unencapsulated diff --git a/tests/integration/banner-footer/index.test.ts b/tests/integration/banner-footer/index.test.ts index 1f00a9ee7..7eb1bcda2 100644 --- a/tests/integration/banner-footer/index.test.ts +++ b/tests/integration/banner-footer/index.test.ts @@ -10,51 +10,54 @@ enum BannerFooter { DTS_FOOTER = '/*! hello footer dts */', } -test('banner and footer should work in js, css and dts', async () => { - const fixturePath = __dirname; - const { js, css, dts } = await buildAndGetResults({ - fixturePath, - type: 'all', - }); +test.skipIf(process.version.startsWith('v18'))( + 'banner and footer should work in js, css and dts', + async () => { + const fixturePath = __dirname; + const { js, css, dts } = await buildAndGetResults({ + fixturePath, + type: 'all', + }); - const jsContents = Object.values(js.contents); - const cssContents = Object.values(css.contents); - const dtsContents = Object.values(dts.contents); + const jsContents = Object.values(js.contents); + const cssContents = Object.values(css.contents); + const dtsContents = Object.values(dts.contents); - // There are 5 cases included: - // 1. bundle esm - // 2. bundle cjs - // 3. bundleless esm - // 4. bundleless cjs - // 5. bundle esm with minify enabled - const checkBannerAndFooter = ( - contents: Record[], - type: 'js' | 'css' | 'dts', - ) => { - for (const content of Object.values(contents)) { - if (content) { - const expectedBanner = - type === 'js' - ? BannerFooter.JS_BANNER - : type === 'css' - ? BannerFooter.CSS_BANNER - : BannerFooter.DTS_BANNER; - const expectedFooter = - type === 'js' - ? BannerFooter.JS_FOOTER - : type === 'css' - ? BannerFooter.CSS_FOOTER - : BannerFooter.DTS_FOOTER; + // There are 5 cases included in both tsc and tsgo + // 1. bundle esm + // 2. bundle cjs + // 3. bundleless esm + // 4. bundleless cjs + // 5. bundle esm with minify enabled + const checkBannerAndFooter = ( + contents: Record[], + type: 'js' | 'css' | 'dts', + ) => { + for (const content of Object.values(contents)) { + if (content) { + const expectedBanner = + type === 'js' + ? BannerFooter.JS_BANNER + : type === 'css' + ? BannerFooter.CSS_BANNER + : BannerFooter.DTS_BANNER; + const expectedFooter = + type === 'js' + ? BannerFooter.JS_FOOTER + : type === 'css' + ? BannerFooter.CSS_FOOTER + : BannerFooter.DTS_FOOTER; - for (const value of Object.values(content)) { - expect(value).toContain(expectedBanner); - expect(value).toContain(expectedFooter); + for (const value of Object.values(content)) { + expect(value).toContain(expectedBanner); + expect(value).toContain(expectedFooter); + } } } - } - }; + }; - checkBannerAndFooter(jsContents, 'js'); - checkBannerAndFooter(cssContents, 'css'); - checkBannerAndFooter(dtsContents, 'dts'); -}); + checkBannerAndFooter(jsContents, 'js'); + checkBannerAndFooter(cssContents, 'css'); + checkBannerAndFooter(dtsContents, 'dts'); + }, +); diff --git a/tests/integration/banner-footer/rslib.config.ts b/tests/integration/banner-footer/rslib.config.ts index 42899acde..a18eada8d 100644 --- a/tests/integration/banner-footer/rslib.config.ts +++ b/tests/integration/banner-footer/rslib.config.ts @@ -89,6 +89,84 @@ export default defineConfig({ }, ...bannerFooterConfig, }), + // bundle esm + generateBundleEsmConfig({ + output: { + distPath: { + root: './dist/esm-tsgo/bundle', + }, + }, + dts: { + bundle: true, + tsgo: true, + }, + ...bannerFooterConfig, + }), + // bundle cjs + generateBundleCjsConfig({ + output: { + distPath: { + root: './dist/cjs-tsgo/bundle', + }, + }, + dts: { + bundle: true, + tsgo: true, + }, + ...bannerFooterConfig, + }), + // bundleless esm + generateBundleEsmConfig({ + output: { + distPath: { + root: './dist/esm-tsgo/bundleless', + }, + }, + bundle: false, + dts: { + bundle: false, + tsgo: true, + }, + source: { + entry: { + index: ['./src/**'], + }, + }, + ...bannerFooterConfig, + }), + // bundleless cjs + generateBundleCjsConfig({ + output: { + distPath: { + root: './dist/cjs-tsgo/bundleless', + }, + }, + bundle: false, + dts: { + bundle: false, + tsgo: true, + }, + source: { + entry: { + index: ['./src/**'], + }, + }, + ...bannerFooterConfig, + }), + // bundle esm with minify enabled + generateBundleEsmConfig({ + output: { + distPath: { + root: './dist/esm-tsgo/bundle-minify', + }, + minify: true, + }, + dts: { + bundle: true, + tsgo: true, + }, + ...bannerFooterConfig, + }), ], source: { entry: { diff --git a/tests/integration/banner-footer/tsconfig.json b/tests/integration/banner-footer/tsconfig.json index 888d3e460..5ee8bfa51 100644 --- a/tests/integration/banner-footer/tsconfig.json +++ b/tests/integration/banner-footer/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "@rslib/tsconfig/base", - "compilerOptions": { - "baseUrl": "./" - }, + "compilerOptions": {}, "include": ["src"] } diff --git a/tests/integration/dts-tsgo/__snapshots__/bundle.test.ts.snap b/tests/integration/dts-tsgo/__snapshots__/bundle.test.ts.snap new file mode 100644 index 000000000..0b1e7062c --- /dev/null +++ b/tests/integration/dts-tsgo/__snapshots__/bundle.test.ts.snap @@ -0,0 +1,136 @@ +// Rstest Snapshot v1 + +exports[`dts with tsgo when bundle: true > basic 3`] = ` +{ + "cjs": "export declare const num1 = 1; + +export declare const num2 = 2; + +export declare const num3 = 3; + +export declare const numSum: number; + +export declare const str1 = "str1"; + +export declare const str2 = "str2"; + +export declare const str3 = "str3"; + +export declare const strSum: string; + +export { } +", + "esm": "export declare const num1 = 1; + +export declare const num2 = 2; + +export declare const num3 = 3; + +export declare const numSum: number; + +export declare const str1 = "str1"; + +export declare const str2 = "str2"; + +export declare const str3 = "str3"; + +export declare const strSum: string; + +export { } +", +} +`; + +exports[`dts with tsgo when bundle: true > multiple entries 3`] = ` +[ + "export declare const num1 = 1; + +export declare const num2 = 2; + +export declare const num3 = 3; + +export declare const numSum: number; + +export declare const str1 = "str1"; + +export declare const str2 = "str2"; + +export declare const str3 = "str3"; + +export declare const strSum: string; + +export { } +", + "export declare const num1 = 1; + +export declare const num2 = 2; + +export declare const num3 = 3; + +export declare const numSum: number; + +export declare const str1 = "str1"; + +export declare const str2 = "str2"; + +export declare const str3 = "str3"; + +export declare const strSum: string; + +export { } +", + "export declare const numSum: number; + +export declare const strSum: string; + +export { } +", + "export declare const numSum: number; + +export declare const strSum: string; + +export { } +", +] +`; + +exports[`dts with tsgo when bundle: true > rootdir calculation should ignore declaration files 3`] = ` +{ + "cjs": "export declare const num1 = 1; + +export declare const num2 = 2; + +export declare const num3 = 3; + +export declare const numSum: number; + +export declare const str1 = "str1"; + +export declare const str2 = "str2"; + +export declare const str3 = "str3"; + +export declare const strSum: string; + +export { } +", + "esm": "export declare const num1 = 1; + +export declare const num2 = 2; + +export declare const num3 = 3; + +export declare const numSum: number; + +export declare const str1 = "str1"; + +export declare const str2 = "str2"; + +export declare const str3 = "str3"; + +export declare const strSum: string; + +export { } +", +} +`; diff --git a/tests/integration/dts-tsgo/__snapshots__/bundleFalse.test.ts.snap b/tests/integration/dts-tsgo/__snapshots__/bundleFalse.test.ts.snap new file mode 100644 index 000000000..51668fadc --- /dev/null +++ b/tests/integration/dts-tsgo/__snapshots__/bundleFalse.test.ts.snap @@ -0,0 +1,21 @@ +// Rstest Snapshot v1 + +exports[`dts with tsgo when bundle: false > basic 3`] = ` +{ + "/tests/integration/dts-tsgo/bundle-false/basic/dist/esm/index.d.ts": "export * from './sum'; +export * from './utils/numbers'; +export * from './utils/strings'; +", + "/tests/integration/dts-tsgo/bundle-false/basic/dist/esm/sum.d.ts": "export declare const numSum: number; +export declare const strSum: string; +", + "/tests/integration/dts-tsgo/bundle-false/basic/dist/esm/utils/numbers.d.ts": "export declare const num1 = 1; +export declare const num2 = 2; +export declare const num3 = 3; +", + "/tests/integration/dts-tsgo/bundle-false/basic/dist/esm/utils/strings.d.ts": "export declare const str1 = "str1"; +export declare const str2 = "str2"; +export declare const str3 = "str3"; +", +} +`; diff --git a/tests/integration/dts-tsgo/build.test.ts b/tests/integration/dts-tsgo/build.test.ts new file mode 100644 index 000000000..3bb0fef9e --- /dev/null +++ b/tests/integration/dts-tsgo/build.test.ts @@ -0,0 +1,214 @@ +import { spawnSync } from 'node:child_process'; +import { existsSync } from 'node:fs'; +import { join } from 'node:path'; +import { describe, expect, test } from '@rstest/core'; +import { buildAndGetResults, createTempFiles, queryContent } from 'test-helper'; + +describe.skipIf(process.version.startsWith('v18'))( + 'dts with tsgo when build: true', + () => { + test('basic', async () => { + const fixturePath = join(__dirname, 'build', 'basic'); + const { files } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/build/basic/dist/esm/index.d.ts", + "/tests/integration/dts-tsgo/build/basic/dist/esm/sum.d.ts", + ] + `); + + const referenceDistPath = join( + fixturePath, + '../__references__/dist/index.d.ts', + ); + expect(existsSync(referenceDistPath)).toBeTruthy(); + + const buildInfoPath = join(fixturePath, 'tsconfig.tsbuildinfo'); + expect(existsSync(buildInfoPath)).toBeTruthy(); + }); + + test('distPath', async () => { + const fixturePath = join(__dirname, 'build', 'dist-path'); + const { files } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/build/dist-path/dist/custom/index.d.ts", + ] + `); + + const buildInfoPath = join(fixturePath, 'tsconfig.tsbuildinfo'); + expect(existsSync(buildInfoPath)).toBeTruthy(); + }); + + test('autoExtension: true', async () => { + const fixturePath = join(__dirname, 'build', 'auto-extension'); + const { files } = await buildAndGetResults({ fixturePath, type: 'dts' }); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/build/auto-extension/dist/types/index.d.cts", + "/tests/integration/dts-tsgo/build/auto-extension/dist/types/sum.d.cts", + ] + `); + + const buildInfoPath = join(fixturePath, 'tsconfig.tsbuildinfo'); + expect(existsSync(buildInfoPath)).toBeTruthy(); + }); + + test('process files - auto extension and banner / footer', async () => { + const fixturePath = join(__dirname, 'build', 'process-files'); + const { contents } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(contents.esm).toMatchInlineSnapshot(` + { + "/tests/integration/dts-tsgo/build/process-files/dist/esm/index.d.mts": "/*! hello banner dts build*/ + export declare const num1 = 1; + + /*! hello banner dts build*/ + ", + } + `); + + const buildInfoPath = join(fixturePath, 'tsconfig.tsbuildinfo'); + expect(existsSync(buildInfoPath)).toBeTruthy(); + }); + + test('abortOnError: false', async () => { + const fixturePath = join(__dirname, 'build', 'abort-on-error'); + + const result = spawnSync('npx', ['rslib', 'build'], { + cwd: fixturePath, + // do not show output in test console + stdio: 'ignore', + shell: true, + }); + + expect(result.status).toBe(0); + + const buildInfoPath = join(fixturePath, 'tsconfig.tsbuildinfo'); + expect(existsSync(buildInfoPath)).toBeTruthy(); + }); + + test('should clean dts dist files', async () => { + const fixturePath = join(__dirname, 'build', 'clean'); + + const checkFiles = await createTempFiles(fixturePath, false); + + const { files } = await buildAndGetResults({ fixturePath, type: 'dts' }); + + for (const file of checkFiles) { + expect(existsSync(file)).toBe(false); + } + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/build/clean/dist-types/esm/index.d.ts", + "/tests/integration/dts-tsgo/build/clean/dist-types/esm/sum.d.ts", + ] + `); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/build/clean/dist-types/cjs/index.d.ts", + "/tests/integration/dts-tsgo/build/clean/dist-types/cjs/sum.d.ts", + ] + `); + + const referenceDistPath = join( + fixturePath, + '../__references__/dist/index.d.ts', + ); + expect(existsSync(referenceDistPath)).toBeTruthy(); + + const cjsBuildInfoPath = join(fixturePath, 'tsconfig.cjs.tsbuildinfo'); + expect(existsSync(cjsBuildInfoPath)).toBeTruthy(); + + const esmBuildInfoPath = join(fixturePath, 'tsconfig.esm.tsbuildinfo'); + expect(existsSync(esmBuildInfoPath)).toBeTruthy(); + }); + + test('declarationMap', async () => { + const fixturePath = join(__dirname, 'build', 'declaration-map'); + const { files, contents } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/build/declaration-map/dist/esm/index.d.ts", + "/tests/integration/dts-tsgo/build/declaration-map/dist/esm/index.d.ts.map", + ] + `); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/build/declaration-map/dist/cjs/index.d.cts", + "/tests/integration/dts-tsgo/build/declaration-map/dist/cjs/index.d.cts.map", + ] + `); + + const { content: indexDtsEsm } = queryContent( + contents.esm, + 'index.d.ts', + { + basename: true, + }, + ); + const { content: indexDtsCjs } = queryContent( + contents.cjs, + 'index.d.cts', + { + basename: true, + }, + ); + const { content: indexMapEsm } = queryContent( + contents.esm, + 'index.d.ts.map', + { + basename: true, + }, + ); + const { content: indexMapCjs } = queryContent( + contents.cjs, + 'index.d.cts.map', + { + basename: true, + }, + ); + expect(indexDtsEsm).toContain('//# sourceMappingURL=index.d.ts.map'); + expect(indexDtsCjs).toContain('//# sourceMappingURL=index.d.cts.map'); + expect(indexMapEsm).toContain('"file":"index.d.ts"'); + expect(indexMapCjs).toContain('"file":"index.d.cts"'); + + const referenceEsmDistPath = join( + fixturePath, + '../__references__/dist/index.d.ts', + ); + expect(existsSync(referenceEsmDistPath)).toBeTruthy(); + + // TODO: can not rename dts files in reference yet + // const referenceCjsDistPath = join( + // fixturePath, + // '../__references__/dist/index.d.cts', + // ); + // expect(existsSync(referenceCjsDistPath)).toBeTruthy(); + + const esmBuildInfoPath = join(fixturePath, 'tsconfig.esm.tsbuildinfo'); + const cjsBuildInfoPath = join(fixturePath, 'tsconfig.cjs.tsbuildinfo'); + expect(existsSync(esmBuildInfoPath)).toBeTruthy(); + expect(existsSync(cjsBuildInfoPath)).toBeTruthy(); + }); + }, +); diff --git a/tests/integration/dts-tsgo/build/__references__/package.json b/tests/integration/dts-tsgo/build/__references__/package.json new file mode 100644 index 000000000..06d356ba9 --- /dev/null +++ b/tests/integration/dts-tsgo/build/__references__/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-build-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/build/__references__/src/index.ts b/tests/integration/dts-tsgo/build/__references__/src/index.ts new file mode 100644 index 000000000..37537151f --- /dev/null +++ b/tests/integration/dts-tsgo/build/__references__/src/index.ts @@ -0,0 +1 @@ +export const b = 'hello world'; diff --git a/tests/integration/dts-tsgo/build/__references__/tsconfig.json b/tests/integration/dts-tsgo/build/__references__/tsconfig.json new file mode 100644 index 000000000..56bec502e --- /dev/null +++ b/tests/integration/dts-tsgo/build/__references__/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "composite": true + }, + "include": ["src"] +} diff --git a/tests/integration/dts-tsgo/build/abort-on-error/package.json b/tests/integration/dts-tsgo/build/abort-on-error/package.json new file mode 100644 index 000000000..105c00aaf --- /dev/null +++ b/tests/integration/dts-tsgo/build/abort-on-error/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-build-abort-on-error-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/build/abort-on-error/rslib.config.ts b/tests/integration/dts-tsgo/build/abort-on-error/rslib.config.ts new file mode 100644 index 000000000..7891e7fa0 --- /dev/null +++ b/tests/integration/dts-tsgo/build/abort-on-error/rslib.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + bundle: false, + build: true, + abortOnError: false, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: ['./src/**'], + }, + }, +}); diff --git a/tests/integration/dts-tsgo/build/abort-on-error/src/const.ts b/tests/integration/dts-tsgo/build/abort-on-error/src/const.ts new file mode 100644 index 000000000..88a6d19f4 --- /dev/null +++ b/tests/integration/dts-tsgo/build/abort-on-error/src/const.ts @@ -0,0 +1,3 @@ +export interface A { + a: number; +} diff --git a/tests/integration/dts-tsgo/build/abort-on-error/src/index.ts b/tests/integration/dts-tsgo/build/abort-on-error/src/index.ts new file mode 100644 index 000000000..2595bdbbf --- /dev/null +++ b/tests/integration/dts-tsgo/build/abort-on-error/src/index.ts @@ -0,0 +1,6 @@ +import type { A } from './const'; + +export const getA = (item: A) => { + item.a = '0'; + return item; +}; diff --git a/tests/integration/dts-tsgo/build/abort-on-error/tsconfig.json b/tests/integration/dts-tsgo/build/abort-on-error/tsconfig.json new file mode 100644 index 000000000..2f987306b --- /dev/null +++ b/tests/integration/dts-tsgo/build/abort-on-error/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "rootDir": "src", + "declaration": true, + "declarationDir": "./dist/esm" + }, + "include": ["src"], + "references": [ + { + "path": "../__references__" + } + ] +} diff --git a/tests/integration/dts-tsgo/build/auto-extension/package.json b/tests/integration/dts-tsgo/build/auto-extension/package.json new file mode 100644 index 000000000..997fc45b9 --- /dev/null +++ b/tests/integration/dts-tsgo/build/auto-extension/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-build-auto-extension-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/build/auto-extension/rslib.config.ts b/tests/integration/dts-tsgo/build/auto-extension/rslib.config.ts new file mode 100644 index 000000000..2c31c42af --- /dev/null +++ b/tests/integration/dts-tsgo/build/auto-extension/rslib.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleCjsConfig({ + bundle: false, + dts: { + autoExtension: true, + distPath: './dist/types', + bundle: false, + build: true, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: ['./src/**'], + }, + }, +}); diff --git a/tests/integration/dts-tsgo/build/auto-extension/src/index.ts b/tests/integration/dts-tsgo/build/auto-extension/src/index.ts new file mode 100644 index 000000000..cf1f61676 --- /dev/null +++ b/tests/integration/dts-tsgo/build/auto-extension/src/index.ts @@ -0,0 +1 @@ +export * from './sum'; diff --git a/tests/integration/dts-tsgo/build/auto-extension/src/sum.ts b/tests/integration/dts-tsgo/build/auto-extension/src/sum.ts new file mode 100644 index 000000000..bc0dd4eba --- /dev/null +++ b/tests/integration/dts-tsgo/build/auto-extension/src/sum.ts @@ -0,0 +1,10 @@ +export const num1 = 1; +export const num2 = 2; +export const num3 = 3; + +export const str1 = 'str1'; +export const str2 = 'str2'; +export const str3 = 'str3'; + +export const numSum = num1 + num2 + num3; +export const strSum = str1 + str2 + str3; diff --git a/tests/integration/dts-tsgo/build/auto-extension/tsconfig.json b/tests/integration/dts-tsgo/build/auto-extension/tsconfig.json new file mode 100644 index 000000000..fbd119bad --- /dev/null +++ b/tests/integration/dts-tsgo/build/auto-extension/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "rootDir": "src", + "declaration": true, + "declarationDir": "./dist/types" + }, + "include": ["src"], + "references": [ + { + "path": "../__references__" + } + ] +} diff --git a/tests/integration/dts-tsgo/build/basic/package.json b/tests/integration/dts-tsgo/build/basic/package.json new file mode 100644 index 000000000..0377ba55c --- /dev/null +++ b/tests/integration/dts-tsgo/build/basic/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-build-basic-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/build/basic/rslib.config.ts b/tests/integration/dts-tsgo/build/basic/rslib.config.ts new file mode 100644 index 000000000..811bb118b --- /dev/null +++ b/tests/integration/dts-tsgo/build/basic/rslib.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + bundle: false, + build: true, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: ['./src/**'], + }, + }, +}); diff --git a/tests/integration/dts-tsgo/build/basic/src/index.ts b/tests/integration/dts-tsgo/build/basic/src/index.ts new file mode 100644 index 000000000..cf1f61676 --- /dev/null +++ b/tests/integration/dts-tsgo/build/basic/src/index.ts @@ -0,0 +1 @@ +export * from './sum'; diff --git a/tests/integration/dts-tsgo/build/basic/src/sum.ts b/tests/integration/dts-tsgo/build/basic/src/sum.ts new file mode 100644 index 000000000..bc0dd4eba --- /dev/null +++ b/tests/integration/dts-tsgo/build/basic/src/sum.ts @@ -0,0 +1,10 @@ +export const num1 = 1; +export const num2 = 2; +export const num3 = 3; + +export const str1 = 'str1'; +export const str2 = 'str2'; +export const str3 = 'str3'; + +export const numSum = num1 + num2 + num3; +export const strSum = str1 + str2 + str3; diff --git a/tests/integration/dts-tsgo/build/basic/tsconfig.json b/tests/integration/dts-tsgo/build/basic/tsconfig.json new file mode 100644 index 000000000..2f987306b --- /dev/null +++ b/tests/integration/dts-tsgo/build/basic/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "rootDir": "src", + "declaration": true, + "declarationDir": "./dist/esm" + }, + "include": ["src"], + "references": [ + { + "path": "../__references__" + } + ] +} diff --git a/tests/integration/dts-tsgo/build/clean/package.json b/tests/integration/dts-tsgo/build/clean/package.json new file mode 100644 index 000000000..9a6b2d0bd --- /dev/null +++ b/tests/integration/dts-tsgo/build/clean/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-build-clean-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/build/clean/rslib.config.ts b/tests/integration/dts-tsgo/build/clean/rslib.config.ts new file mode 100644 index 000000000..97ca4aec7 --- /dev/null +++ b/tests/integration/dts-tsgo/build/clean/rslib.config.ts @@ -0,0 +1,36 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + distPath: './dist-types/esm', + bundle: false, + build: true, + tsgo: true, + }, + source: { + tsconfigPath: './tsconfig.esm.json', + }, + }), + generateBundleCjsConfig({ + bundle: false, + dts: { + distPath: './dist-types/cjs', + bundle: false, + build: true, + tsgo: true, + }, + source: { + tsconfigPath: './tsconfig.cjs.json', + }, + }), + ], + source: { + entry: { + index: ['./src/**'], + }, + }, +}); diff --git a/tests/integration/dts-tsgo/build/clean/src/index.ts b/tests/integration/dts-tsgo/build/clean/src/index.ts new file mode 100644 index 000000000..cf1f61676 --- /dev/null +++ b/tests/integration/dts-tsgo/build/clean/src/index.ts @@ -0,0 +1 @@ +export * from './sum'; diff --git a/tests/integration/dts-tsgo/build/clean/src/sum.ts b/tests/integration/dts-tsgo/build/clean/src/sum.ts new file mode 100644 index 000000000..bc0dd4eba --- /dev/null +++ b/tests/integration/dts-tsgo/build/clean/src/sum.ts @@ -0,0 +1,10 @@ +export const num1 = 1; +export const num2 = 2; +export const num3 = 3; + +export const str1 = 'str1'; +export const str2 = 'str2'; +export const str3 = 'str3'; + +export const numSum = num1 + num2 + num3; +export const strSum = str1 + str2 + str3; diff --git a/tests/integration/dts-tsgo/build/clean/tsconfig.cjs.json b/tests/integration/dts-tsgo/build/clean/tsconfig.cjs.json new file mode 100644 index 000000000..adc0b9181 --- /dev/null +++ b/tests/integration/dts-tsgo/build/clean/tsconfig.cjs.json @@ -0,0 +1,14 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "rootDir": "src", + "declaration": true, + "declarationDir": "./dist-types/cjs" + }, + "include": ["src"], + "references": [ + { + "path": "../__references__" + } + ] +} diff --git a/tests/integration/dts-tsgo/build/clean/tsconfig.esm.json b/tests/integration/dts-tsgo/build/clean/tsconfig.esm.json new file mode 100644 index 000000000..f36149f4f --- /dev/null +++ b/tests/integration/dts-tsgo/build/clean/tsconfig.esm.json @@ -0,0 +1,14 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "rootDir": "src", + "declaration": true, + "declarationDir": "./dist-types/esm" + }, + "include": ["src"], + "references": [ + { + "path": "../__references__" + } + ] +} diff --git a/tests/integration/dts-tsgo/build/declaration-map/package.json b/tests/integration/dts-tsgo/build/declaration-map/package.json new file mode 100644 index 000000000..f4ae81c60 --- /dev/null +++ b/tests/integration/dts-tsgo/build/declaration-map/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-build-declaration-map-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/build/declaration-map/rslib.config.ts b/tests/integration/dts-tsgo/build/declaration-map/rslib.config.ts new file mode 100644 index 000000000..6419acbfc --- /dev/null +++ b/tests/integration/dts-tsgo/build/declaration-map/rslib.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + autoExtension: true, + build: true, + tsgo: true, + }, + source: { + tsconfigPath: './tsconfig.esm.json', + }, + }), + generateBundleCjsConfig({ + bundle: false, + dts: { + autoExtension: true, + build: true, + tsgo: true, + }, + source: { + tsconfigPath: './tsconfig.cjs.json', + }, + }), + ], +}); diff --git a/tests/integration/dts-tsgo/build/declaration-map/src/index.ts b/tests/integration/dts-tsgo/build/declaration-map/src/index.ts new file mode 100644 index 000000000..cc798ff50 --- /dev/null +++ b/tests/integration/dts-tsgo/build/declaration-map/src/index.ts @@ -0,0 +1 @@ +export const a = 1; diff --git a/tests/integration/dts-tsgo/build/declaration-map/tsconfig.cjs.json b/tests/integration/dts-tsgo/build/declaration-map/tsconfig.cjs.json new file mode 100644 index 000000000..acf2f0390 --- /dev/null +++ b/tests/integration/dts-tsgo/build/declaration-map/tsconfig.cjs.json @@ -0,0 +1,15 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "rootDir": "src", + "declaration": true, + "declarationMap": true, + "declarationDir": "./dist/cjs" + }, + "include": ["src"], + "references": [ + { + "path": "../__references__" + } + ] +} diff --git a/tests/integration/dts-tsgo/build/declaration-map/tsconfig.esm.json b/tests/integration/dts-tsgo/build/declaration-map/tsconfig.esm.json new file mode 100644 index 000000000..69c88953d --- /dev/null +++ b/tests/integration/dts-tsgo/build/declaration-map/tsconfig.esm.json @@ -0,0 +1,15 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "rootDir": "src", + "declaration": true, + "declarationMap": true, + "declarationDir": "./dist/esm" + }, + "include": ["src"], + "references": [ + { + "path": "../__references__" + } + ] +} diff --git a/tests/integration/dts-tsgo/build/dist-path/package.json b/tests/integration/dts-tsgo/build/dist-path/package.json new file mode 100644 index 000000000..c44fded9d --- /dev/null +++ b/tests/integration/dts-tsgo/build/dist-path/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-build-dist-path-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/build/dist-path/rslib.config.ts b/tests/integration/dts-tsgo/build/dist-path/rslib.config.ts new file mode 100644 index 000000000..97dc1f979 --- /dev/null +++ b/tests/integration/dts-tsgo/build/dist-path/rslib.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + bundle: false, + build: true, + distPath: './dist/custom', + tsgo: true, + }, + }), + ], + source: { + entry: { + index: ['./src/**'], + }, + }, +}); diff --git a/tests/integration/dts-tsgo/build/dist-path/src/index.ts b/tests/integration/dts-tsgo/build/dist-path/src/index.ts new file mode 100644 index 000000000..dfa3258cb --- /dev/null +++ b/tests/integration/dts-tsgo/build/dist-path/src/index.ts @@ -0,0 +1 @@ +export const num1 = 1; diff --git a/tests/integration/dts-tsgo/build/dist-path/tsconfig.json b/tests/integration/dts-tsgo/build/dist-path/tsconfig.json new file mode 100644 index 000000000..1ec5d0035 --- /dev/null +++ b/tests/integration/dts-tsgo/build/dist-path/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "rootDir": "src", + "declaration": true, + "declarationDir": "./dist/custom" + }, + "include": ["src"], + "references": [ + { + "path": "../__references__" + } + ] +} diff --git a/tests/integration/dts-tsgo/build/process-files/package.json b/tests/integration/dts-tsgo/build/process-files/package.json new file mode 100644 index 000000000..e94debbcd --- /dev/null +++ b/tests/integration/dts-tsgo/build/process-files/package.json @@ -0,0 +1,5 @@ +{ + "name": "dts-tsgo-build-process-files-test", + "version": "1.0.0", + "private": true +} diff --git a/tests/integration/dts-tsgo/build/process-files/rslib.config.ts b/tests/integration/dts-tsgo/build/process-files/rslib.config.ts new file mode 100644 index 000000000..35ffb1d85 --- /dev/null +++ b/tests/integration/dts-tsgo/build/process-files/rslib.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + banner: { + dts: '/*! hello banner dts build*/', + }, + footer: { + dts: '/*! hello banner dts build*/', + }, + dts: { + bundle: false, + build: true, + autoExtension: true, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: ['./src/**'], + }, + }, +}); diff --git a/tests/integration/dts-tsgo/build/process-files/src/index.ts b/tests/integration/dts-tsgo/build/process-files/src/index.ts new file mode 100644 index 000000000..dfa3258cb --- /dev/null +++ b/tests/integration/dts-tsgo/build/process-files/src/index.ts @@ -0,0 +1 @@ +export const num1 = 1; diff --git a/tests/integration/dts-tsgo/build/process-files/tsconfig.json b/tests/integration/dts-tsgo/build/process-files/tsconfig.json new file mode 100644 index 000000000..2f987306b --- /dev/null +++ b/tests/integration/dts-tsgo/build/process-files/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "rootDir": "src", + "declaration": true, + "declarationDir": "./dist/esm" + }, + "include": ["src"], + "references": [ + { + "path": "../__references__" + } + ] +} diff --git a/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/index.ts b/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/index.ts new file mode 100644 index 000000000..fb828f24f --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/index.ts @@ -0,0 +1,3 @@ +export * from './sum'; +export * from './utils/numbers'; +export * from './utils/strings'; diff --git a/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/sum.ts b/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/sum.ts new file mode 100644 index 000000000..2759c8823 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/sum.ts @@ -0,0 +1,5 @@ +import { num1, num2, num3 } from './utils/numbers'; +import { str1, str2, str3 } from './utils/strings'; + +export const numSum = num1 + num2 + num3; +export const strSum = str1 + str2 + str3; diff --git a/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/utils/numbers.ts b/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/utils/numbers.ts new file mode 100644 index 000000000..c1d2a8cd2 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/utils/numbers.ts @@ -0,0 +1,3 @@ +export const num1 = 1; +export const num2 = 2; +export const num3 = 3; diff --git a/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/utils/strings.ts b/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/utils/strings.ts new file mode 100644 index 000000000..d35b5a606 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/__fixtures__/src/utils/strings.ts @@ -0,0 +1,3 @@ +export const str1 = 'str1'; +export const str2 = 'str2'; +export const str3 = 'str3'; diff --git a/tests/integration/dts-tsgo/bundle-false/__fixtures__/tsconfig.json b/tests/integration/dts-tsgo/bundle-false/__fixtures__/tsconfig.json new file mode 100644 index 000000000..5ee8bfa51 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/__fixtures__/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": {}, + "include": ["src"] +} diff --git a/tests/integration/dts-tsgo/bundle-false/abort-on-error/package.json b/tests/integration/dts-tsgo/bundle-false/abort-on-error/package.json new file mode 100644 index 000000000..11afcef18 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/abort-on-error/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-false-abort-on-error-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle-false/abort-on-error/rslib.config.ts b/tests/integration/dts-tsgo/bundle-false/abort-on-error/rslib.config.ts new file mode 100644 index 000000000..a96dbc210 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/abort-on-error/rslib.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + bundle: false, + abortOnError: false, + tsgo: true, + }, + }), + generateBundleCjsConfig({ + bundle: false, + }), + ], + source: { + entry: { + index: ['./src/**'], + }, + }, +}); diff --git a/tests/integration/dts-tsgo/bundle-false/abort-on-error/src/const.ts b/tests/integration/dts-tsgo/bundle-false/abort-on-error/src/const.ts new file mode 100644 index 000000000..88a6d19f4 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/abort-on-error/src/const.ts @@ -0,0 +1,3 @@ +export interface A { + a: number; +} diff --git a/tests/integration/dts-tsgo/bundle-false/abort-on-error/src/index.ts b/tests/integration/dts-tsgo/bundle-false/abort-on-error/src/index.ts new file mode 100644 index 000000000..2595bdbbf --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/abort-on-error/src/index.ts @@ -0,0 +1,6 @@ +import type { A } from './const'; + +export const getA = (item: A) => { + item.a = '0'; + return item; +}; diff --git a/tests/integration/dts-tsgo/bundle-false/abort-on-error/tsconfig.json b/tests/integration/dts-tsgo/bundle-false/abort-on-error/tsconfig.json new file mode 100644 index 000000000..5ee8bfa51 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/abort-on-error/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": {}, + "include": ["src"] +} diff --git a/tests/integration/dts-tsgo/bundle-false/alias/compile/prebundle-pkg/index.d.ts b/tests/integration/dts-tsgo/bundle-false/alias/compile/prebundle-pkg/index.d.ts new file mode 100644 index 000000000..4c82305cf --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/alias/compile/prebundle-pkg/index.d.ts @@ -0,0 +1,4 @@ +export declare function logger(): { + (...data: any[]): void; + (message?: any, ...optionalParams: any[]): void; +}; diff --git a/tests/integration/dts-tsgo/bundle-false/alias/compile/prebundle-pkg/index.js b/tests/integration/dts-tsgo/bundle-false/alias/compile/prebundle-pkg/index.js new file mode 100644 index 000000000..55cdb9deb --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/alias/compile/prebundle-pkg/index.js @@ -0,0 +1,3 @@ +export function logger() { + return console.log; +} diff --git a/tests/integration/dts-tsgo/bundle-false/alias/compile/prebundle-pkg/package.json b/tests/integration/dts-tsgo/bundle-false/alias/compile/prebundle-pkg/package.json new file mode 100644 index 000000000..5126af028 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/alias/compile/prebundle-pkg/package.json @@ -0,0 +1,5 @@ +{ + "name": "prebundle-pkg", + "version": "0.0.0", + "private": true +} diff --git a/tests/integration/dts-tsgo/bundle-false/alias/package.json b/tests/integration/dts-tsgo/bundle-false/alias/package.json new file mode 100644 index 000000000..81aa805bf --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/alias/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-false-alias-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle-false/alias/rslib.config.ts b/tests/integration/dts-tsgo/bundle-false/alias/rslib.config.ts new file mode 100644 index 000000000..84a84882f --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/alias/rslib.config.ts @@ -0,0 +1,25 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + dts: { + bundle: false, + alias: { + 'prebundle-pkg': './compile/prebundle-pkg', + }, + tsgo: true, + }, + }), + generateBundleCjsConfig({ + dts: { + bundle: false, + alias: { + 'prebundle-pkg': './compile/prebundle-pkg', + }, + tsgo: true, + }, + }), + ], +}); diff --git a/tests/integration/dts-tsgo/bundle-false/alias/src/index.ts b/tests/integration/dts-tsgo/bundle-false/alias/src/index.ts new file mode 100644 index 000000000..8fc482265 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/alias/src/index.ts @@ -0,0 +1 @@ +export {} from 'prebundle-pkg'; diff --git a/tests/integration/dts-tsgo/bundle-false/alias/tsconfig.json b/tests/integration/dts-tsgo/bundle-false/alias/tsconfig.json new file mode 100644 index 000000000..1d2e6432e --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/alias/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "skipLibCheck": true + }, + "include": ["src/**/*"] +} diff --git a/tests/integration/dts-tsgo/bundle-false/auto-extension/package.json b/tests/integration/dts-tsgo/bundle-false/auto-extension/package.json new file mode 100644 index 000000000..cca4a8b5e --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/auto-extension/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-false-auto-extension-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle-false/auto-extension/rslib.config.ts b/tests/integration/dts-tsgo/bundle-false/auto-extension/rslib.config.ts new file mode 100644 index 000000000..2a1bafcb5 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/auto-extension/rslib.config.ts @@ -0,0 +1,31 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + autoExtension: true, + distPath: './dist/types/esm', + bundle: false, + tsgo: true, + }, + }), + generateBundleCjsConfig({ + bundle: false, + dts: { + autoExtension: true, + distPath: './dist/types/cjs', + bundle: false, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: ['../__fixtures__/src/**'], + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle-false/basic/package.json b/tests/integration/dts-tsgo/bundle-false/basic/package.json new file mode 100644 index 000000000..9bdb94a03 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/basic/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-false-basic-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle-false/basic/rslib.config.ts b/tests/integration/dts-tsgo/bundle-false/basic/rslib.config.ts new file mode 100644 index 000000000..b95611b23 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/basic/rslib.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + bundle: false, + tsgo: true, + }, + }), + generateBundleCjsConfig({ + bundle: false, + dts: { + bundle: false, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: ['../__fixtures__/src/**'], + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle-false/clean/package.json b/tests/integration/dts-tsgo/bundle-false/clean/package.json new file mode 100644 index 000000000..93fb42720 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/clean/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-false-clean-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle-false/clean/rslib.config.ts b/tests/integration/dts-tsgo/bundle-false/clean/rslib.config.ts new file mode 100644 index 000000000..0e75393b7 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/clean/rslib.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + bundle: false, + distPath: './dist-types/esm', + tsgo: true, + }, + }), + generateBundleCjsConfig({ + bundle: false, + dts: { + bundle: false, + distPath: './dist-types/cjs', + tsgo: true, + }, + }), + ], + source: { + entry: { + index: ['../__fixtures__/src/**'], + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle-false/declaration-dir/package.json b/tests/integration/dts-tsgo/bundle-false/declaration-dir/package.json new file mode 100644 index 000000000..f64fc409c --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/declaration-dir/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-false-declaration-dir-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle-false/declaration-dir/rslib.config.ts b/tests/integration/dts-tsgo/bundle-false/declaration-dir/rslib.config.ts new file mode 100644 index 000000000..3730a8bf6 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/declaration-dir/rslib.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + bundle: false, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: ['../__fixtures__/src/**'], + }, + }, +}); diff --git a/tests/integration/dts-tsgo/bundle-false/declaration-dir/tsconfig.json b/tests/integration/dts-tsgo/bundle-false/declaration-dir/tsconfig.json new file mode 100644 index 000000000..04e915d38 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/declaration-dir/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "declaration": true, + "declarationDir": "./dist-types" + }, + "include": ["../__fixtures__/src"] +} diff --git a/tests/integration/dts-tsgo/bundle-false/declaration-map/package.json b/tests/integration/dts-tsgo/bundle-false/declaration-map/package.json new file mode 100644 index 000000000..072279bf9 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/declaration-map/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-false-declaration-map-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle-false/declaration-map/rslib.config.ts b/tests/integration/dts-tsgo/bundle-false/declaration-map/rslib.config.ts new file mode 100644 index 000000000..00f279cee --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/declaration-map/rslib.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + autoExtension: true, + tsgo: true, + }, + }), + generateBundleCjsConfig({ + bundle: false, + dts: { + autoExtension: true, + tsgo: true, + }, + }), + ], +}); diff --git a/tests/integration/dts-tsgo/bundle-false/declaration-map/src/index.ts b/tests/integration/dts-tsgo/bundle-false/declaration-map/src/index.ts new file mode 100644 index 000000000..cc798ff50 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/declaration-map/src/index.ts @@ -0,0 +1 @@ +export const a = 1; diff --git a/tests/integration/dts-tsgo/bundle-false/declaration-map/tsconfig.json b/tests/integration/dts-tsgo/bundle-false/declaration-map/tsconfig.json new file mode 100644 index 000000000..fbdefb504 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/declaration-map/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "declaration": true, + "declarationMap": true + }, + "include": ["src"] +} diff --git a/tests/integration/dts-tsgo/bundle-false/dist-path/package.json b/tests/integration/dts-tsgo/bundle-false/dist-path/package.json new file mode 100644 index 000000000..7cd343a16 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/dist-path/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-false-dist-path-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle-false/dist-path/rslib.config.ts b/tests/integration/dts-tsgo/bundle-false/dist-path/rslib.config.ts new file mode 100644 index 000000000..4bde7b478 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/dist-path/rslib.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + bundle: false, + distPath: './dist/custom', + tsgo: true, + }, + }), + generateBundleCjsConfig({ + bundle: false, + }), + ], + source: { + entry: { + index: ['../__fixtures__/src/**'], + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle-false/tsconfig-path/package.json b/tests/integration/dts-tsgo/bundle-false/tsconfig-path/package.json new file mode 100644 index 000000000..ec8ceda39 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/tsconfig-path/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-true-bundle-false-tsconfig-path-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle-false/tsconfig-path/rslib.config.ts b/tests/integration/dts-tsgo/bundle-false/tsconfig-path/rslib.config.ts new file mode 100644 index 000000000..04a1c203b --- /dev/null +++ b/tests/integration/dts-tsgo/bundle-false/tsconfig-path/rslib.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + dts: { + bundle: false, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: '../__fixtures__/src/index.ts', + }, + tsconfigPath: './path_not_exist/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle.test.ts b/tests/integration/dts-tsgo/bundle.test.ts new file mode 100644 index 000000000..7c4e03225 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle.test.ts @@ -0,0 +1,219 @@ +import { spawnSync } from 'node:child_process'; +import { existsSync } from 'node:fs'; +import { join } from 'node:path'; +import { describe, expect, test } from '@rstest/core'; +import { buildAndGetResults, createTempFiles, queryContent } from 'test-helper'; + +describe.skipIf(process.version.startsWith('v18'))( + 'dts with tsgo when bundle: true', + () => { + test('basic', async () => { + const fixturePath = join(__dirname, 'bundle', 'basic'); + const { files, entries } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot( + ` + [ + "/tests/integration/dts-tsgo/bundle/basic/dist/esm/index.d.ts", + ] + `, + ); + + expect(files.cjs).toMatchInlineSnapshot( + ` + [ + "/tests/integration/dts-tsgo/bundle/basic/dist/cjs/index.d.ts", + ] + `, + ); + + expect(entries).toMatchSnapshot(); + }); + + test('distPath', async () => { + const fixturePath = join(__dirname, 'bundle', 'dist-path'); + const { files } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot( + ` + [ + "/tests/integration/dts-tsgo/bundle/dist-path/dist/custom/index.d.ts", + ] + `, + ); + }); + + test('abortOnError: false', async () => { + const fixturePath = join(__dirname, 'bundle', 'abort-on-error'); + + const result = spawnSync('npx', ['rslib', 'build'], { + cwd: fixturePath, + // do not show output in test console + stdio: 'ignore', + shell: true, + }); + + expect(result.status).toBe(0); + }); + + test('autoExtension: true', async () => { + const fixturePath = join(__dirname, 'bundle', 'auto-extension'); + const { files } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.cjs).toMatchInlineSnapshot( + ` + [ + "/tests/integration/dts-tsgo/bundle/auto-extension/dist/cjs/index.d.cts", + ] + `, + ); + }); + + test('bundleName -- set source.entry', async () => { + const fixturePath = join(__dirname, 'bundle', 'bundle-name'); + const { files } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot( + ` + [ + "/tests/integration/dts-tsgo/bundle/bundle-name/dist/esm/bundleName.d.ts", + ] + `, + ); + }); + + test('entry is an absolute path', async () => { + const fixturePath = join(__dirname, 'bundle', 'absolute-entry'); + const { files } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot( + ` + [ + "/tests/integration/dts-tsgo/bundle/absolute-entry/dist/esm/index.d.ts", + ] + `, + ); + }); + + test('rootdir calculation should ignore declaration files', async () => { + const fixturePath = join(__dirname, 'bundle', 'rootdir'); + const { files, entries } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle/rootdir/dist/esm/index.d.ts", + ] + `); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle/rootdir/dist/cjs/index.d.ts", + ] + `); + + expect(entries).toMatchSnapshot(); + }); + + test('should clean dts dist files and .rslib folder', async () => { + const fixturePath = join(__dirname, 'bundle', 'clean'); + + const checkFiles = await createTempFiles(fixturePath, true); + + const { files } = await buildAndGetResults({ fixturePath, type: 'dts' }); + + for (const file of checkFiles) { + expect(existsSync(file)).toBe(false); + } + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle/clean/dist-types/esm/index.d.ts", + ] + `); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle/clean/dist-types/cjs/index.d.ts", + ] + `); + }); + + test('multiple entries', async () => { + const fixturePath = join(__dirname, 'bundle', 'multiple-entries'); + const { files, contents } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle/multiple-entries/dist/esm/index.d.ts", + "/tests/integration/dts-tsgo/bundle/multiple-entries/dist/esm/sum.d.ts", + ] + `); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle/multiple-entries/dist/cjs/index.d.ts", + "/tests/integration/dts-tsgo/bundle/multiple-entries/dist/cjs/sum.d.ts", + ] + `); + + const { content: indexEsm } = queryContent(contents.esm, 'index.d.ts', { + basename: true, + }); + const { content: indexCjs } = queryContent(contents.cjs, 'index.d.ts', { + basename: true, + }); + const { content: sumEsm } = queryContent(contents.esm, 'sum.d.ts', { + basename: true, + }); + const { content: sumCjs } = queryContent(contents.cjs, 'sum.d.ts', { + basename: true, + }); + + expect([indexEsm, indexCjs, sumEsm, sumCjs]).toMatchSnapshot(); + }); + + test('override with bundledPackages', async () => { + const fixturePath = join(__dirname, 'bundle', 'bundled-packages'); + const { entries } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + // default + expect(entries.esm0).toContain(`import { Action } from 'redux';`); + + // override empty array + expect(entries.esm1).toMatchInlineSnapshot(` + " + export * from "@reduxjs/toolkit"; + + export { } + " + `); + + // override with bundledPackages + expect(entries.esm2).not.toContain(`import { Action } from 'redux';`); + }); + }, +); diff --git a/tests/integration/dts-tsgo/bundle/__fixtures__/src/index.ts b/tests/integration/dts-tsgo/bundle/__fixtures__/src/index.ts new file mode 100644 index 000000000..fb828f24f --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/__fixtures__/src/index.ts @@ -0,0 +1,3 @@ +export * from './sum'; +export * from './utils/numbers'; +export * from './utils/strings'; diff --git a/tests/integration/dts-tsgo/bundle/__fixtures__/src/sum.ts b/tests/integration/dts-tsgo/bundle/__fixtures__/src/sum.ts new file mode 100644 index 000000000..2759c8823 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/__fixtures__/src/sum.ts @@ -0,0 +1,5 @@ +import { num1, num2, num3 } from './utils/numbers'; +import { str1, str2, str3 } from './utils/strings'; + +export const numSum = num1 + num2 + num3; +export const strSum = str1 + str2 + str3; diff --git a/tests/integration/dts-tsgo/bundle/__fixtures__/src/utils/numbers.ts b/tests/integration/dts-tsgo/bundle/__fixtures__/src/utils/numbers.ts new file mode 100644 index 000000000..c1d2a8cd2 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/__fixtures__/src/utils/numbers.ts @@ -0,0 +1,3 @@ +export const num1 = 1; +export const num2 = 2; +export const num3 = 3; diff --git a/tests/integration/dts-tsgo/bundle/__fixtures__/src/utils/strings.ts b/tests/integration/dts-tsgo/bundle/__fixtures__/src/utils/strings.ts new file mode 100644 index 000000000..d35b5a606 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/__fixtures__/src/utils/strings.ts @@ -0,0 +1,3 @@ +export const str1 = 'str1'; +export const str2 = 'str2'; +export const str3 = 'str3'; diff --git a/tests/integration/dts-tsgo/bundle/__fixtures__/tsconfig.json b/tests/integration/dts-tsgo/bundle/__fixtures__/tsconfig.json new file mode 100644 index 000000000..5ee8bfa51 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/__fixtures__/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": {}, + "include": ["src"] +} diff --git a/tests/integration/dts-tsgo/bundle/abort-on-error/package.json b/tests/integration/dts-tsgo/bundle/abort-on-error/package.json new file mode 100644 index 000000000..cc6c4a5f6 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/abort-on-error/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-abort-on-error-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle/abort-on-error/rslib.config.ts b/tests/integration/dts-tsgo/bundle/abort-on-error/rslib.config.ts new file mode 100644 index 000000000..3924b5584 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/abort-on-error/rslib.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + dts: { + bundle: true, + abortOnError: false, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: './src/index.ts', + }, + tsconfigPath: 'tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle/abort-on-error/src/const.ts b/tests/integration/dts-tsgo/bundle/abort-on-error/src/const.ts new file mode 100644 index 000000000..88a6d19f4 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/abort-on-error/src/const.ts @@ -0,0 +1,3 @@ +export interface A { + a: number; +} diff --git a/tests/integration/dts-tsgo/bundle/abort-on-error/src/index.ts b/tests/integration/dts-tsgo/bundle/abort-on-error/src/index.ts new file mode 100644 index 000000000..2595bdbbf --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/abort-on-error/src/index.ts @@ -0,0 +1,6 @@ +import type { A } from './const'; + +export const getA = (item: A) => { + item.a = '0'; + return item; +}; diff --git a/tests/integration/dts-tsgo/bundle/abort-on-error/tsconfig.json b/tests/integration/dts-tsgo/bundle/abort-on-error/tsconfig.json new file mode 100644 index 000000000..5ee8bfa51 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/abort-on-error/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": {}, + "include": ["src"] +} diff --git a/tests/integration/dts-tsgo/bundle/absolute-entry/package.json b/tests/integration/dts-tsgo/bundle/absolute-entry/package.json new file mode 100644 index 000000000..360f7cd7a --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/absolute-entry/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-absolute-entry-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle/absolute-entry/rslib.config.ts b/tests/integration/dts-tsgo/bundle/absolute-entry/rslib.config.ts new file mode 100644 index 000000000..0dfc52e20 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/absolute-entry/rslib.config.ts @@ -0,0 +1,20 @@ +import { join } from 'node:path'; +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + dts: { + bundle: true, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: join(__dirname, '../__fixtures__/src/index.ts'), + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle/auto-extension/package.json b/tests/integration/dts-tsgo/bundle/auto-extension/package.json new file mode 100644 index 000000000..5b072b527 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/auto-extension/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-auto-extension-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle/auto-extension/rslib.config.ts b/tests/integration/dts-tsgo/bundle/auto-extension/rslib.config.ts new file mode 100644 index 000000000..24ff80728 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/auto-extension/rslib.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleCjsConfig({ + dts: { + bundle: true, + autoExtension: true, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: '../__fixtures__/src/index.ts', + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle/basic/package.json b/tests/integration/dts-tsgo/bundle/basic/package.json new file mode 100644 index 000000000..82766bb33 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/basic/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-basic-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle/basic/rslib.config.ts b/tests/integration/dts-tsgo/bundle/basic/rslib.config.ts new file mode 100644 index 000000000..7e95c2f27 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/basic/rslib.config.ts @@ -0,0 +1,25 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + dts: { + bundle: true, + tsgo: true, + }, + }), + generateBundleCjsConfig({ + dts: { + bundle: true, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: '../__fixtures__/src/index.ts', + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle/bundle-name/package.json b/tests/integration/dts-tsgo/bundle/bundle-name/package.json new file mode 100644 index 000000000..c5437c022 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/bundle-name/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-bundle-name-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle/bundle-name/rslib.config.ts b/tests/integration/dts-tsgo/bundle/bundle-name/rslib.config.ts new file mode 100644 index 000000000..6ffdf3d60 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/bundle-name/rslib.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + dts: { + bundle: true, + tsgo: true, + }, + }), + ], + source: { + entry: { + bundleName: '../__fixtures__/src/index.ts', + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle/bundled-packages/package.json b/tests/integration/dts-tsgo/bundle/bundled-packages/package.json new file mode 100644 index 000000000..bdc3d7e28 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/bundled-packages/package.json @@ -0,0 +1,9 @@ +{ + "name": "dts-tsgo-bundle-bundled-packages-test", + "version": "1.0.0", + "private": true, + "type": "module", + "devDependencies": { + "@reduxjs/toolkit": "^2.8.2" + } +} diff --git a/tests/integration/dts-tsgo/bundle/bundled-packages/rslib.config.ts b/tests/integration/dts-tsgo/bundle/bundled-packages/rslib.config.ts new file mode 100644 index 000000000..1d0e80b00 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/bundled-packages/rslib.config.ts @@ -0,0 +1,52 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + dts: { + bundle: true, + tsgo: true, + }, + output: { + distPath: { + root: './dist/esm/default', + }, + }, + }), + generateBundleEsmConfig({ + dts: { + bundle: { + bundledPackages: [], + }, + tsgo: true, + }, + output: { + distPath: { + root: './dist/esm/override-empty-array', + }, + }, + }), + generateBundleEsmConfig({ + dts: { + bundle: { + bundledPackages: [ + '@reduxjs/toolkit', + '@standard-schema/spec', + '@standard-schema/utils', + 'immer', + 'redux', + 'redux-thunk', + 'reselect', + ], + }, + tsgo: true, + }, + output: { + distPath: { + root: './dist/esm/override-array-string', + }, + }, + }), + ], +}); diff --git a/tests/integration/dts-tsgo/bundle/bundled-packages/src/index.ts b/tests/integration/dts-tsgo/bundle/bundled-packages/src/index.ts new file mode 100644 index 000000000..a9c1fbbda --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/bundled-packages/src/index.ts @@ -0,0 +1 @@ +export * from '@reduxjs/toolkit'; diff --git a/tests/integration/dts-tsgo/bundle/bundled-packages/tsconfig.json b/tests/integration/dts-tsgo/bundle/bundled-packages/tsconfig.json new file mode 100644 index 000000000..5ee8bfa51 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/bundled-packages/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": {}, + "include": ["src"] +} diff --git a/tests/integration/dts-tsgo/bundle/clean/package.json b/tests/integration/dts-tsgo/bundle/clean/package.json new file mode 100644 index 000000000..a47725e0d --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/clean/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-clean-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle/clean/rslib.config.ts b/tests/integration/dts-tsgo/bundle/clean/rslib.config.ts new file mode 100644 index 000000000..75515e15a --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/clean/rslib.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + dts: { + bundle: true, + distPath: './dist-types/esm', + tsgo: true, + }, + }), + generateBundleCjsConfig({ + dts: { + bundle: true, + distPath: './dist-types/cjs', + tsgo: true, + }, + }), + ], + source: { + entry: { + index: '../__fixtures__/src/index.ts', + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle/dist-path/package.json b/tests/integration/dts-tsgo/bundle/dist-path/package.json new file mode 100644 index 000000000..99b80f57a --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/dist-path/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-dist-path-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle/dist-path/rslib.config.ts b/tests/integration/dts-tsgo/bundle/dist-path/rslib.config.ts new file mode 100644 index 000000000..4336bd842 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/dist-path/rslib.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + dts: { + bundle: true, + distPath: './dist/custom', + tsgo: true, + }, + }), + ], + source: { + entry: { + index: '../__fixtures__/src/index.ts', + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle/multiple-entries/package.json b/tests/integration/dts-tsgo/bundle/multiple-entries/package.json new file mode 100644 index 000000000..f91e66445 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/multiple-entries/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-tsgo-bundle-multiple-entries-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/dts-tsgo/bundle/multiple-entries/rslib.config.ts b/tests/integration/dts-tsgo/bundle/multiple-entries/rslib.config.ts new file mode 100644 index 000000000..e76e671f5 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/multiple-entries/rslib.config.ts @@ -0,0 +1,26 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + dts: { + bundle: true, + tsgo: true, + }, + }), + generateBundleCjsConfig({ + dts: { + bundle: true, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: '../__fixtures__/src/index.ts', + sum: '../__fixtures__/src/sum.ts', + }, + tsconfigPath: '../__fixtures__/tsconfig.json', + }, +}); diff --git a/tests/integration/dts-tsgo/bundle/rootdir/package.json b/tests/integration/dts-tsgo/bundle/rootdir/package.json new file mode 100644 index 000000000..219103863 --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/rootdir/package.json @@ -0,0 +1,9 @@ +{ + "name": "dts-tsgo-bundle-rootdir-test", + "version": "1.0.0", + "private": true, + "type": "module", + "devDependencies": { + "@types/chromecast-caf-sender": "^1.0.11" + } +} diff --git a/tests/integration/dts-tsgo/bundle/rootdir/rslib.config.ts b/tests/integration/dts-tsgo/bundle/rootdir/rslib.config.ts new file mode 100644 index 000000000..f8e4f74bc --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/rootdir/rslib.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + dts: { + bundle: true, + tsgo: true, + }, + }), + generateBundleCjsConfig({ + dts: { + bundle: true, + tsgo: true, + }, + }), + ], + source: { + entry: { + index: '../__fixtures__/src/index.ts', + }, + }, +}); diff --git a/tests/integration/dts-tsgo/bundle/rootdir/tsconfig.json b/tests/integration/dts-tsgo/bundle/rootdir/tsconfig.json new file mode 100644 index 000000000..46e1f344f --- /dev/null +++ b/tests/integration/dts-tsgo/bundle/rootdir/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@rslib/tsconfig/base", + "include": ["../__fixtures__/src", "node_modules/@types"] +} diff --git a/tests/integration/dts-tsgo/bundleFalse.test.ts b/tests/integration/dts-tsgo/bundleFalse.test.ts new file mode 100644 index 000000000..16738b0ab --- /dev/null +++ b/tests/integration/dts-tsgo/bundleFalse.test.ts @@ -0,0 +1,235 @@ +import { spawnSync } from 'node:child_process'; +import { existsSync } from 'node:fs'; +import { join } from 'node:path'; +import { describe, expect, test } from '@rstest/core'; +import stripAnsi from 'strip-ansi'; +import { + buildAndGetResults, + createTempFiles, + globContentJSON, + queryContent, +} from 'test-helper'; + +describe.skipIf(process.version.startsWith('v18'))( + 'dts with tsgo when bundle: false', + () => { + test('basic', async () => { + const fixturePath = join(__dirname, 'bundle-false', 'basic'); + const { files, contents } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle-false/basic/dist/esm/index.d.ts", + "/tests/integration/dts-tsgo/bundle-false/basic/dist/esm/sum.d.ts", + "/tests/integration/dts-tsgo/bundle-false/basic/dist/esm/utils/numbers.d.ts", + "/tests/integration/dts-tsgo/bundle-false/basic/dist/esm/utils/strings.d.ts", + ] + `); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle-false/basic/dist/cjs/index.d.ts", + "/tests/integration/dts-tsgo/bundle-false/basic/dist/cjs/sum.d.ts", + "/tests/integration/dts-tsgo/bundle-false/basic/dist/cjs/utils/numbers.d.ts", + "/tests/integration/dts-tsgo/bundle-false/basic/dist/cjs/utils/strings.d.ts", + ] + `); + + expect(contents.esm).toMatchSnapshot(); + }); + + test('distPath', async () => { + const fixturePath = join(__dirname, 'bundle-false', 'dist-path'); + const { files } = await buildAndGetResults({ fixturePath, type: 'dts' }); + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle-false/dist-path/dist/custom/index.d.ts", + "/tests/integration/dts-tsgo/bundle-false/dist-path/dist/custom/sum.d.ts", + "/tests/integration/dts-tsgo/bundle-false/dist-path/dist/custom/utils/numbers.d.ts", + "/tests/integration/dts-tsgo/bundle-false/dist-path/dist/custom/utils/strings.d.ts", + ] + `); + }); + + test('abortOnError: false', async () => { + const fixturePath = join(__dirname, 'bundle-false', 'abort-on-error'); + + const result = spawnSync('npx', ['rslib', 'build'], { + cwd: fixturePath, + // do not show output in test console + stdio: 'ignore', + shell: true, + }); + + expect(result.status).toBe(0); + }); + + test('autoExtension: true', async () => { + const fixturePath = join(__dirname, 'bundle-false', 'auto-extension'); + const { files } = await buildAndGetResults({ fixturePath, type: 'dts' }); + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle-false/auto-extension/dist/types/esm/index.d.ts", + "/tests/integration/dts-tsgo/bundle-false/auto-extension/dist/types/esm/sum.d.ts", + "/tests/integration/dts-tsgo/bundle-false/auto-extension/dist/types/esm/utils/numbers.d.ts", + "/tests/integration/dts-tsgo/bundle-false/auto-extension/dist/types/esm/utils/strings.d.ts", + ] + `); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle-false/auto-extension/dist/types/cjs/index.d.cts", + "/tests/integration/dts-tsgo/bundle-false/auto-extension/dist/types/cjs/sum.d.cts", + "/tests/integration/dts-tsgo/bundle-false/auto-extension/dist/types/cjs/utils/numbers.d.cts", + "/tests/integration/dts-tsgo/bundle-false/auto-extension/dist/types/cjs/utils/strings.d.cts", + ] + `); + }); + + test('should use declarationDir when not set dts.distPath', async () => { + const fixturePath = join(__dirname, 'bundle-false', 'declaration-dir'); + const distTypesPath = join(fixturePath, 'dist-types'); + + await buildAndGetResults({ fixturePath, type: 'dts' }); + + const distTypeFiles = await globContentJSON(distTypesPath, { + absolute: true, + }); + const distTypeFilePaths = Object.keys(distTypeFiles).sort(); + + expect(distTypeFilePaths).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle-false/declaration-dir/dist-types/index.d.ts", + "/tests/integration/dts-tsgo/bundle-false/declaration-dir/dist-types/sum.d.ts", + "/tests/integration/dts-tsgo/bundle-false/declaration-dir/dist-types/utils/numbers.d.ts", + "/tests/integration/dts-tsgo/bundle-false/declaration-dir/dist-types/utils/strings.d.ts", + ] + `); + }); + + test('should clean dts dist files', async () => { + const fixturePath = join(__dirname, 'bundle-false', 'clean'); + + const checkFiles = await createTempFiles(fixturePath, false); + + const { files } = await buildAndGetResults({ fixturePath, type: 'dts' }); + + for (const file of checkFiles) { + expect(existsSync(file)).toBe(false); + } + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle-false/clean/dist-types/esm/index.d.ts", + "/tests/integration/dts-tsgo/bundle-false/clean/dist-types/esm/sum.d.ts", + "/tests/integration/dts-tsgo/bundle-false/clean/dist-types/esm/utils/numbers.d.ts", + "/tests/integration/dts-tsgo/bundle-false/clean/dist-types/esm/utils/strings.d.ts", + ] + `); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle-false/clean/dist-types/cjs/index.d.ts", + "/tests/integration/dts-tsgo/bundle-false/clean/dist-types/cjs/sum.d.ts", + "/tests/integration/dts-tsgo/bundle-false/clean/dist-types/cjs/utils/numbers.d.ts", + "/tests/integration/dts-tsgo/bundle-false/clean/dist-types/cjs/utils/strings.d.ts", + ] + `); + }); + + test('should emit error when tsconfig not found', async () => { + const fixturePath = join(__dirname, 'bundle-false', 'tsconfig-path'); + await createTempFiles(fixturePath, false); + + try { + await buildAndGetResults({ fixturePath, type: 'dts' }); + } catch (err: any) { + expect(stripAnsi(err.message)).toMatchInlineSnapshot( + `"Failed to resolve tsconfig file "/tests/integration/dts-tsgo/bundle-false/tsconfig-path/path_not_exist/tsconfig.json" from /tests/integration/dts-tsgo/bundle-false/tsconfig-path. Please ensure that the file exists."`, + ); + } + }); + + test('alias', async () => { + const fixturePath = join(__dirname, 'bundle-false', 'alias'); + const { contents } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(contents.esm).toMatchInlineSnapshot(` + { + "/tests/integration/dts-tsgo/bundle-false/alias/dist/esm/index.d.ts": "export {} from '../../compile/prebundle-pkg'; + ", + } + `); + + expect(contents.cjs).toMatchInlineSnapshot(` + { + "/tests/integration/dts-tsgo/bundle-false/alias/dist/cjs/index.d.ts": "export {} from '../../compile/prebundle-pkg'; + ", + } + `); + }); + + test('declarationMap', async () => { + const fixturePath = join(__dirname, 'bundle-false', 'declaration-map'); + const { files, contents } = await buildAndGetResults({ + fixturePath, + type: 'dts', + }); + + expect(files.esm).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle-false/declaration-map/dist/esm/index.d.ts", + "/tests/integration/dts-tsgo/bundle-false/declaration-map/dist/esm/index.d.ts.map", + ] + `); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "/tests/integration/dts-tsgo/bundle-false/declaration-map/dist/cjs/index.d.cts", + "/tests/integration/dts-tsgo/bundle-false/declaration-map/dist/cjs/index.d.cts.map", + ] + `); + + const { content: indexDtsEsm } = queryContent( + contents.esm, + 'index.d.ts', + { + basename: true, + }, + ); + const { content: indexDtsCjs } = queryContent( + contents.cjs, + 'index.d.cts', + { + basename: true, + }, + ); + const { content: indexMapEsm } = queryContent( + contents.esm, + 'index.d.ts.map', + { + basename: true, + }, + ); + const { content: indexMapCjs } = queryContent( + contents.cjs, + 'index.d.cts.map', + { + basename: true, + }, + ); + expect(indexDtsEsm).toContain('//# sourceMappingURL=index.d.ts.map'); + expect(indexDtsCjs).toContain('//# sourceMappingURL=index.d.cts.map'); + expect(indexMapEsm).toContain('"file":"index.d.ts"'); + expect(indexMapCjs).toContain('"file":"index.d.cts"'); + }); + }, +); diff --git a/tests/integration/redirect/dts-tsgo/compile/prebundle-pkg/index.d.ts b/tests/integration/redirect/dts-tsgo/compile/prebundle-pkg/index.d.ts new file mode 100644 index 000000000..4c82305cf --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/compile/prebundle-pkg/index.d.ts @@ -0,0 +1,4 @@ +export declare function logger(): { + (...data: any[]): void; + (message?: any, ...optionalParams: any[]): void; +}; diff --git a/tests/integration/redirect/dts-tsgo/compile/prebundle-pkg/index.js b/tests/integration/redirect/dts-tsgo/compile/prebundle-pkg/index.js new file mode 100644 index 000000000..55cdb9deb --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/compile/prebundle-pkg/index.js @@ -0,0 +1,3 @@ +export function logger() { + return console.log; +} diff --git a/tests/integration/redirect/dts-tsgo/compile/prebundle-pkg/package.json b/tests/integration/redirect/dts-tsgo/compile/prebundle-pkg/package.json new file mode 100644 index 000000000..5126af028 --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/compile/prebundle-pkg/package.json @@ -0,0 +1,5 @@ +{ + "name": "prebundle-pkg", + "version": "0.0.0", + "private": true +} diff --git a/tests/integration/redirect/dts-tsgo/package.json b/tests/integration/redirect/dts-tsgo/package.json new file mode 100644 index 000000000..bcc4606cc --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/package.json @@ -0,0 +1,14 @@ +{ + "name": "redirect-dts-tsgo-test", + "version": "1.0.0", + "private": true, + "devDependencies": { + "@rslib/core": "workspace:*", + "@types/express": "^5.0.3", + "express": "^5.1.0", + "typescript": "^5.9.2" + }, + "peerDependencies": { + "express": "^4" + } +} diff --git a/tests/integration/redirect/dts-tsgo/rslib.config.ts b/tests/integration/redirect/dts-tsgo/rslib.config.ts new file mode 100644 index 000000000..1f266fc55 --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/rslib.config.ts @@ -0,0 +1,101 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + // 0 - default - path: true extension: false + generateBundleEsmConfig({ + dts: { + tsgo: true, + }, + output: { + distPath: { + root: './dist/default/esm', + }, + }, + }), + // 1 - path: false extension: false + generateBundleEsmConfig({ + dts: { + tsgo: true, + }, + output: { + distPath: { + root: './dist/path-false/esm', + }, + }, + redirect: { + dts: { + path: false, + }, + }, + }), + // 2 - path: true extension: true + generateBundleEsmConfig({ + dts: { + tsgo: true, + }, + output: { + distPath: { + root: './dist/extension-true/esm', + }, + }, + redirect: { + dts: { + extension: true, + }, + }, + }), + // 3 - path: false extension: true + generateBundleEsmConfig({ + dts: { + tsgo: true, + }, + output: { + distPath: { + root: './dist/path-false-extension-true/esm', + }, + }, + redirect: { + dts: { + path: false, + extension: true, + }, + }, + }), + // 4 - extension: true with dts.autoExtension true + generateBundleEsmConfig({ + dts: { + autoExtension: true, + tsgo: true, + }, + output: { + distPath: { + root: './dist/auto-extension-true/esm', + }, + }, + redirect: { + dts: { + extension: true, + }, + }, + }), + // 5 - extension: true with dts.autoExtension true + generateBundleCjsConfig({ + dts: { + autoExtension: true, + tsgo: true, + }, + output: { + distPath: { + root: './dist/auto-extension-true/cjs', + }, + }, + redirect: { + dts: { + extension: true, + }, + }, + }), + ], +}); diff --git a/tests/integration/redirect/dts-tsgo/src/.hidden-folder/index.ts b/tests/integration/redirect/dts-tsgo/src/.hidden-folder/index.ts new file mode 100644 index 000000000..afa9b24f7 --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/src/.hidden-folder/index.ts @@ -0,0 +1 @@ +export const hiddenFolder = 'This is a hidden folder'; diff --git a/tests/integration/redirect/dts-tsgo/src/.hidden.ts b/tests/integration/redirect/dts-tsgo/src/.hidden.ts new file mode 100644 index 000000000..4aa488db5 --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/src/.hidden.ts @@ -0,0 +1 @@ +export const hidden = 'This is a hidden file'; diff --git a/tests/integration/redirect/dts-tsgo/src/a.b/index.ts b/tests/integration/redirect/dts-tsgo/src/a.b/index.ts new file mode 100644 index 000000000..7cd8bd0a9 --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/src/a.b/index.ts @@ -0,0 +1 @@ +export const ab = 'a.b'; diff --git a/tests/integration/redirect/dts-tsgo/src/bar.baz.ts b/tests/integration/redirect/dts-tsgo/src/bar.baz.ts new file mode 100644 index 000000000..ba28c5f41 --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/src/bar.baz.ts @@ -0,0 +1 @@ +export const bar = 'bar-baz'; diff --git a/tests/integration/redirect/dts-tsgo/src/foo/foo.ts b/tests/integration/redirect/dts-tsgo/src/foo/foo.ts new file mode 100644 index 000000000..7891b894a --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/src/foo/foo.ts @@ -0,0 +1,5 @@ +import { logRequest } from '@src/logger'; +import { logger } from 'prebundle-pkg'; +import { logRequest as logRequest2 } from '../logger'; + +export { logRequest, logRequest2, logger }; diff --git a/tests/integration/redirect/dts-tsgo/src/foo/index.ts b/tests/integration/redirect/dts-tsgo/src/foo/index.ts new file mode 100644 index 000000000..77a95f681 --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/src/foo/index.ts @@ -0,0 +1 @@ +export type Barrel = string; diff --git a/tests/integration/redirect/dts-tsgo/src/index.ts b/tests/integration/redirect/dts-tsgo/src/index.ts new file mode 100644 index 000000000..a6a576679 --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/src/index.ts @@ -0,0 +1,29 @@ +import { logRequest } from '@src/logger'; +import { logger } from 'prebundle-pkg'; +import type { Baz } from 'self-entry'; +import type { LoggerOptions } from './types'; +import { defaultOptions } from './types.js'; + +import sources = require('@src/logger'); + +export { + sources, + type Baz as self, + logRequest, + logger, + type LoggerOptions, + defaultOptions, +}; + +export * from '@src/foo'; +export * from '@src/logger'; +export type { Foo } from '@src/types'; +// export { Router } from 'express'; +export * from 'prebundle-pkg'; +export type { Bar } from 'types'; +export * from './.hidden'; +export * from './.hidden-folder'; +export * from './a.b'; +export * from './bar.baz'; +export * from './foo'; +export * from './types'; diff --git a/tests/integration/redirect/dts-tsgo/src/logger.ts b/tests/integration/redirect/dts-tsgo/src/logger.ts new file mode 100644 index 000000000..09265c607 --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/src/logger.ts @@ -0,0 +1,25 @@ +// import type { Request } from 'express'; +import type { LoggerOptions } from './types'; + +export function logRequest(req: Request, options: LoggerOptions): void { + const { method, url } = req; + const logMessage = `${method} ${url}`; + + switch (options.logLevel) { + case 'debug': + console.debug(logMessage); + break; + case 'warn': + console.warn(logMessage); + break; + case 'error': + console.error(logMessage); + break; + default: + console.log(logMessage); + } + + if (options.logBody && req.body) { + console.log('Request body:', req.body); + } +} diff --git a/tests/integration/redirect/dts-tsgo/src/types.ts b/tests/integration/redirect/dts-tsgo/src/types.ts new file mode 100644 index 000000000..ef6a9bf2b --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/src/types.ts @@ -0,0 +1,21 @@ +export interface LoggerOptions { + logLevel: 'info' | 'debug' | 'warn' | 'error'; + logBody: boolean; +} + +export const defaultOptions: LoggerOptions = { + logLevel: 'info', + logBody: false, +}; + +export interface Foo { + foo: string; +} + +export interface Bar { + bar: string; +} + +export interface Baz { + baz: string; +} diff --git a/tests/integration/redirect/dts-tsgo/tsconfig.json b/tests/integration/redirect/dts-tsgo/tsconfig.json new file mode 100644 index 000000000..6db3ff6ac --- /dev/null +++ b/tests/integration/redirect/dts-tsgo/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "strict": true, + "skipLibCheck": true, + "paths": { + "@src/*": ["./src/*"], + "prebundle-pkg": ["./compile/prebundle-pkg"], + "self-entry": ["./src"], + "express": ["./node_modules/express"], + "*": ["./src/*"] + } + }, + "include": ["src/**/*"] +} diff --git a/tests/integration/redirect/dtsTsgo.test.ts b/tests/integration/redirect/dtsTsgo.test.ts new file mode 100644 index 000000000..6c77b9f92 --- /dev/null +++ b/tests/integration/redirect/dtsTsgo.test.ts @@ -0,0 +1,379 @@ +import path from 'node:path'; +import { beforeAll, describe, expect, test } from '@rstest/core'; +import { buildAndGetResults } from 'test-helper'; + +describe.skipIf(process.version.startsWith('v18'))( + 'dts redirect with tsgo', + () => { + let contents: Awaited>['contents']; + + beforeAll(async () => { + const fixturePath = path.resolve(__dirname, './dts-tsgo'); + contents = (await buildAndGetResults({ fixturePath, type: 'dts' })) + .contents; + }, 20000); + + test('redirect.dts.path: true with redirect.dts.extension: false - default', async () => { + expect(contents.esm0).toMatchInlineSnapshot(` + { + "/tests/integration/redirect/dts-tsgo/dist/default/esm/.hidden-folder/index.d.ts": "export declare const hiddenFolder = "This is a hidden folder"; + ", + "/tests/integration/redirect/dts-tsgo/dist/default/esm/.hidden.d.ts": "export declare const hidden = "This is a hidden file"; + ", + "/tests/integration/redirect/dts-tsgo/dist/default/esm/a.b/index.d.ts": "export declare const ab = "a.b"; + ", + "/tests/integration/redirect/dts-tsgo/dist/default/esm/bar.baz.d.ts": "export declare const bar = "bar-baz"; + ", + "/tests/integration/redirect/dts-tsgo/dist/default/esm/foo/foo.d.ts": "import { logRequest } from '../logger'; + import { logger } from '../../../../compile/prebundle-pkg'; + import { logRequest as logRequest2 } from '../logger'; + export { logRequest, logRequest2, logger }; + ", + "/tests/integration/redirect/dts-tsgo/dist/default/esm/foo/index.d.ts": "export type Barrel = string; + ", + "/tests/integration/redirect/dts-tsgo/dist/default/esm/index.d.ts": "import { logRequest } from './logger'; + import { logger } from '../../../compile/prebundle-pkg'; + import type { Baz } from './'; + import type { LoggerOptions } from './types'; + import { defaultOptions } from './types.js'; + import sources = require('./logger'); + export { sources, type Baz as self, logRequest, logger, type LoggerOptions, defaultOptions, }; + export * from './foo'; + export * from './logger'; + export type { Foo } from './types'; + // export { Router } from 'express'; + export * from '../../../compile/prebundle-pkg'; + export type { Bar } from './types'; + export * from './.hidden'; + export * from './.hidden-folder'; + export * from './a.b'; + export * from './bar.baz'; + export * from './foo'; + export * from './types'; + ", + "/tests/integration/redirect/dts-tsgo/dist/default/esm/logger.d.ts": "// import type { Request } from 'express'; + import type { LoggerOptions } from './types'; + export declare function logRequest(req: Request, options: LoggerOptions): void; + ", + "/tests/integration/redirect/dts-tsgo/dist/default/esm/types.d.ts": "export interface LoggerOptions { + logLevel: 'info' | 'debug' | 'warn' | 'error'; + logBody: boolean; + } + export declare const defaultOptions: LoggerOptions; + export interface Foo { + foo: string; + } + export interface Bar { + bar: string; + } + export interface Baz { + baz: string; + } + ", + } + `); + }); + + test('redirect.dts.path: false with redirect.dts.extension: false', async () => { + expect(contents.esm1).toMatchInlineSnapshot(` + { + "/tests/integration/redirect/dts-tsgo/dist/path-false/esm/.hidden-folder/index.d.ts": "export declare const hiddenFolder = "This is a hidden folder"; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false/esm/.hidden.d.ts": "export declare const hidden = "This is a hidden file"; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false/esm/a.b/index.d.ts": "export declare const ab = "a.b"; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false/esm/bar.baz.d.ts": "export declare const bar = "bar-baz"; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false/esm/foo/foo.d.ts": "import { logRequest } from '@src/logger'; + import { logger } from 'prebundle-pkg'; + import { logRequest as logRequest2 } from '../logger'; + export { logRequest, logRequest2, logger }; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false/esm/foo/index.d.ts": "export type Barrel = string; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false/esm/index.d.ts": "import { logRequest } from '@src/logger'; + import { logger } from 'prebundle-pkg'; + import type { Baz } from 'self-entry'; + import type { LoggerOptions } from './types'; + import { defaultOptions } from './types.js'; + import sources = require('@src/logger'); + export { sources, type Baz as self, logRequest, logger, type LoggerOptions, defaultOptions, }; + export * from '@src/foo'; + export * from '@src/logger'; + export type { Foo } from '@src/types'; + // export { Router } from 'express'; + export * from 'prebundle-pkg'; + export type { Bar } from 'types'; + export * from './.hidden'; + export * from './.hidden-folder'; + export * from './a.b'; + export * from './bar.baz'; + export * from './foo'; + export * from './types'; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false/esm/logger.d.ts": "// import type { Request } from 'express'; + import type { LoggerOptions } from './types'; + export declare function logRequest(req: Request, options: LoggerOptions): void; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false/esm/types.d.ts": "export interface LoggerOptions { + logLevel: 'info' | 'debug' | 'warn' | 'error'; + logBody: boolean; + } + export declare const defaultOptions: LoggerOptions; + export interface Foo { + foo: string; + } + export interface Bar { + bar: string; + } + export interface Baz { + baz: string; + } + ", + } + `); + }); + + test('redirect.dts.path: true with redirect.dts.extension: true', async () => { + expect(contents.esm2).toMatchInlineSnapshot(` + { + "/tests/integration/redirect/dts-tsgo/dist/extension-true/esm/.hidden-folder/index.d.ts": "export declare const hiddenFolder = "This is a hidden folder"; + ", + "/tests/integration/redirect/dts-tsgo/dist/extension-true/esm/.hidden.d.ts": "export declare const hidden = "This is a hidden file"; + ", + "/tests/integration/redirect/dts-tsgo/dist/extension-true/esm/a.b/index.d.ts": "export declare const ab = "a.b"; + ", + "/tests/integration/redirect/dts-tsgo/dist/extension-true/esm/bar.baz.d.ts": "export declare const bar = "bar-baz"; + ", + "/tests/integration/redirect/dts-tsgo/dist/extension-true/esm/foo/foo.d.ts": "import { logRequest } from '../logger.js'; + import { logger } from '../../../../compile/prebundle-pkg'; + import { logRequest as logRequest2 } from '../logger.js'; + export { logRequest, logRequest2, logger }; + ", + "/tests/integration/redirect/dts-tsgo/dist/extension-true/esm/foo/index.d.ts": "export type Barrel = string; + ", + "/tests/integration/redirect/dts-tsgo/dist/extension-true/esm/index.d.ts": "import { logRequest } from './logger.js'; + import { logger } from '../../../compile/prebundle-pkg'; + import type { Baz } from './index.js'; + import type { LoggerOptions } from './types.js'; + import { defaultOptions } from './types.js'; + import sources = require('./logger.js'); + export { sources, type Baz as self, logRequest, logger, type LoggerOptions, defaultOptions, }; + export * from './foo/index.js'; + export * from './logger.js'; + export type { Foo } from './types.js'; + // export { Router } from 'express'; + export * from '../../../compile/prebundle-pkg'; + export type { Bar } from './types.js'; + export * from './.hidden.js'; + export * from './.hidden-folder/index.js'; + export * from './a.b/index.js'; + export * from './bar.baz.js'; + export * from './foo/index.js'; + export * from './types.js'; + ", + "/tests/integration/redirect/dts-tsgo/dist/extension-true/esm/logger.d.ts": "// import type { Request } from 'express'; + import type { LoggerOptions } from './types.js'; + export declare function logRequest(req: Request, options: LoggerOptions): void; + ", + "/tests/integration/redirect/dts-tsgo/dist/extension-true/esm/types.d.ts": "export interface LoggerOptions { + logLevel: 'info' | 'debug' | 'warn' | 'error'; + logBody: boolean; + } + export declare const defaultOptions: LoggerOptions; + export interface Foo { + foo: string; + } + export interface Bar { + bar: string; + } + export interface Baz { + baz: string; + } + ", + } + `); + }); + + test('redirect.dts.path: false with dts.redirect.extension: true', async () => { + expect(contents.esm3).toMatchInlineSnapshot(` + { + "/tests/integration/redirect/dts-tsgo/dist/path-false-extension-true/esm/.hidden-folder/index.d.ts": "export declare const hiddenFolder = "This is a hidden folder"; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false-extension-true/esm/.hidden.d.ts": "export declare const hidden = "This is a hidden file"; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false-extension-true/esm/a.b/index.d.ts": "export declare const ab = "a.b"; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false-extension-true/esm/bar.baz.d.ts": "export declare const bar = "bar-baz"; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false-extension-true/esm/foo/foo.d.ts": "import { logRequest } from '@src/logger'; + import { logger } from 'prebundle-pkg'; + import { logRequest as logRequest2 } from '../logger.js'; + export { logRequest, logRequest2, logger }; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false-extension-true/esm/foo/index.d.ts": "export type Barrel = string; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false-extension-true/esm/index.d.ts": "import { logRequest } from '@src/logger'; + import { logger } from 'prebundle-pkg'; + import type { Baz } from 'self-entry'; + import type { LoggerOptions } from './types.js'; + import { defaultOptions } from './types.js'; + import sources = require('@src/logger'); + export { sources, type Baz as self, logRequest, logger, type LoggerOptions, defaultOptions, }; + export * from '@src/foo'; + export * from '@src/logger'; + export type { Foo } from '@src/types'; + // export { Router } from 'express'; + export * from 'prebundle-pkg'; + export type { Bar } from 'types'; + export * from './.hidden.js'; + export * from './.hidden-folder/index.js'; + export * from './a.b/index.js'; + export * from './bar.baz.js'; + export * from './foo/index.js'; + export * from './types.js'; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false-extension-true/esm/logger.d.ts": "// import type { Request } from 'express'; + import type { LoggerOptions } from './types.js'; + export declare function logRequest(req: Request, options: LoggerOptions): void; + ", + "/tests/integration/redirect/dts-tsgo/dist/path-false-extension-true/esm/types.d.ts": "export interface LoggerOptions { + logLevel: 'info' | 'debug' | 'warn' | 'error'; + logBody: boolean; + } + export declare const defaultOptions: LoggerOptions; + export interface Foo { + foo: string; + } + export interface Bar { + bar: string; + } + export interface Baz { + baz: string; + } + ", + } + `); + }); + + test('redirect.dts.extension: true with dts.autoExtension: true', async () => { + expect(contents.esm4).toMatchInlineSnapshot(` + { + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/esm/.hidden-folder/index.d.mts": "export declare const hiddenFolder = "This is a hidden folder"; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/esm/.hidden.d.mts": "export declare const hidden = "This is a hidden file"; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/esm/a.b/index.d.mts": "export declare const ab = "a.b"; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/esm/bar.baz.d.mts": "export declare const bar = "bar-baz"; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/esm/foo/foo.d.mts": "import { logRequest } from '../logger.mjs'; + import { logger } from '../../../../compile/prebundle-pkg'; + import { logRequest as logRequest2 } from '../logger.mjs'; + export { logRequest, logRequest2, logger }; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/esm/foo/index.d.mts": "export type Barrel = string; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/esm/index.d.mts": "import { logRequest } from './logger.mjs'; + import { logger } from '../../../compile/prebundle-pkg'; + import type { Baz } from './index.mjs'; + import type { LoggerOptions } from './types.mjs'; + import { defaultOptions } from './types.mjs'; + import sources = require('./logger.mjs'); + export { sources, type Baz as self, logRequest, logger, type LoggerOptions, defaultOptions, }; + export * from './foo/index.mjs'; + export * from './logger.mjs'; + export type { Foo } from './types.mjs'; + // export { Router } from 'express'; + export * from '../../../compile/prebundle-pkg'; + export type { Bar } from './types.mjs'; + export * from './.hidden.mjs'; + export * from './.hidden-folder/index.mjs'; + export * from './a.b/index.mjs'; + export * from './bar.baz.mjs'; + export * from './foo/index.mjs'; + export * from './types.mjs'; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/esm/logger.d.mts": "// import type { Request } from 'express'; + import type { LoggerOptions } from './types.mjs'; + export declare function logRequest(req: Request, options: LoggerOptions): void; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/esm/types.d.mts": "export interface LoggerOptions { + logLevel: 'info' | 'debug' | 'warn' | 'error'; + logBody: boolean; + } + export declare const defaultOptions: LoggerOptions; + export interface Foo { + foo: string; + } + export interface Bar { + bar: string; + } + export interface Baz { + baz: string; + } + ", + } + `); + expect(contents.cjs).toMatchInlineSnapshot(` + { + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/cjs/.hidden-folder/index.d.ts": "export declare const hiddenFolder = "This is a hidden folder"; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/cjs/.hidden.d.ts": "export declare const hidden = "This is a hidden file"; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/cjs/a.b/index.d.ts": "export declare const ab = "a.b"; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/cjs/bar.baz.d.ts": "export declare const bar = "bar-baz"; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/cjs/foo/foo.d.ts": "import { logRequest } from '../logger.js'; + import { logger } from '../../../../compile/prebundle-pkg'; + import { logRequest as logRequest2 } from '../logger.js'; + export { logRequest, logRequest2, logger }; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/cjs/foo/index.d.ts": "export type Barrel = string; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/cjs/index.d.ts": "import { logRequest } from './logger.js'; + import { logger } from '../../../compile/prebundle-pkg'; + import type { Baz } from './index.js'; + import type { LoggerOptions } from './types.js'; + import { defaultOptions } from './types.js'; + import sources = require('./logger.js'); + export { sources, type Baz as self, logRequest, logger, type LoggerOptions, defaultOptions, }; + export * from './foo/index.js'; + export * from './logger.js'; + export type { Foo } from './types.js'; + // export { Router } from 'express'; + export * from '../../../compile/prebundle-pkg'; + export type { Bar } from './types.js'; + export * from './.hidden.js'; + export * from './.hidden-folder/index.js'; + export * from './a.b/index.js'; + export * from './bar.baz.js'; + export * from './foo/index.js'; + export * from './types.js'; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/cjs/logger.d.ts": "// import type { Request } from 'express'; + import type { LoggerOptions } from './types.js'; + export declare function logRequest(req: Request, options: LoggerOptions): void; + ", + "/tests/integration/redirect/dts-tsgo/dist/auto-extension-true/cjs/types.d.ts": "export interface LoggerOptions { + logLevel: 'info' | 'debug' | 'warn' | 'error'; + logBody: boolean; + } + export declare const defaultOptions: LoggerOptions; + export interface Foo { + foo: string; + } + export interface Bar { + bar: string; + } + export interface Baz { + baz: string; + } + ", + } + `); + }); + }, +); diff --git a/website/docs/en/config/lib/dts.mdx b/website/docs/en/config/lib/dts.mdx index 6228da934..88516411c 100644 --- a/website/docs/en/config/lib/dts.mdx +++ b/website/docs/en/config/lib/dts.mdx @@ -15,6 +15,7 @@ type Dts = abortOnError?: boolean; autoExtension?: boolean; alias?: Record; + tsgo?: boolean; } | boolean; ``` @@ -216,7 +217,9 @@ When `dts.autoExtension` is set to `true`, the declaration file extension will b ::: note -It follows the same logic as [lib.autoExtension](/config/lib/auto-extension), but the default value is different since the declaration file extension may cause some issues with different module resolution strategies. +1. It follows the same logic as [lib.autoExtension](/config/lib/auto-extension), but the default value is different since the declaration file extension may cause some issues with different module resolution strategies. + +2. When [dts.tsgo](/config/lib/dts#dtstsgo) is enabled, if the project also enables [dts.build](/config/lib/dts#dtsbuild) or emits declaration files with different extensions to the same directory, `dts.autoExtension` may not work correctly. ::: @@ -245,3 +248,50 @@ export default { ], }; ``` + +### dts.tsgo + +- **Type:** `boolean` +- **Default:** `false` + +Whether to generate declaration files with [tsgo](https://github.com/microsoft/typescript-go), which can provide faster generation of declaration files, especially for large projects. + +::: tip + +This feature is currently an **experimental feature**. Since tsgo is still in the **experimental stage**, there may be some bugs and unresolved issues or limitations. So, make sure to fully test it in your project before enabling this option. + +::: + +To enable this option, you need to: + +1. Install [@typescript/native-preview](https://www.npmjs.com/package/@typescript/native-preview) as a development dependency. + + + +::: tip Version requirements + +`@typescript/native-preview` requires Node.js 20.6.0 or higher. + +::: + +2. Configure in the Rslib config file: + +```ts title="rslib.config.ts" +export default { + lib: [ + { + dts: { + tsgo: true, // [!code highlight] + }, + }, + ], +}; +``` + +3. In order to ensure the consistency of local development, you need to install the corresponding [VS Code Preview Extension](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.native-preview) and add the following configuration in the VS Code settings: + +```json title=".vscode/settings.json" +{ + "typescript.experimental.useTsgo": true +} +``` diff --git a/website/docs/en/guide/advanced/dts.mdx b/website/docs/en/guide/advanced/dts.mdx index 158f2e3ba..11755389b 100644 --- a/website/docs/en/guide/advanced/dts.mdx +++ b/website/docs/en/guide/advanced/dts.mdx @@ -40,23 +40,100 @@ Bundleless declaration files involves generating a separate declaration file for ## How to generate declaration files in Rslib -Rslib defaults to generating bundleless declaration files, which using [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) and bundle declaration files is also supported by [API Extractor](https://api-extractor.com/). - -If you want to generate bundleless declaration files, you can: - -- Set `dts: true` or `dts: { bundle: false }` in the Rslib configuration file. +Rslib supports generating declaration files using both the [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) and [tsgo](https://github.com/microsoft/typescript-go), and also supports bundling declaration files with [API Extractor](https://api-extractor.com/). + +| Type | Supported Method | Description | +| ---------- | --------------------------------------- | -------------- | +| bundleless | TypeScript Compiler API | Default method | +| bundleless | tsgo | | +| bundle | TypeScript Compiler API + API Extractor | Default method | +| bundle | tsgo + API Extractor | | + +### Generate bundleless declaration files + +Configure in the Rslib config file: + +```ts title="rslib.config.ts" +export default { + lib: [ + { + dts: true; // [!code highlight] + // or + // [!code highlight:3] + dts: { + bundle: false; + } + }, + ], +}; +``` -If you want to generate bundle declaration files, you can: +### Generate bundle declaration files -1. Install `@microsoft/api-extractor` as `devDependencies`, which is the underlying tool used for bundling declaration files. +1. Install `@microsoft/api-extractor` as a development dependency, which is the underlying tool used for bundling declaration files. import { PackageManagerTabs } from '@theme'; -2. Set `dts: { bundle: true }` in the Rslib configuration file. +2. Configure in the Rslib config file: + +```ts title="rslib.config.ts" +export default { + lib: [ + { + // [!code highlight:3] + dts: { + bundle: true; + } + }, + ], +}; +``` + +### Generate declaration files with tsgo + +::: tip + +This feature is currently an **experimental feature**. Since tsgo is still in the **experimental stage**, there may be some bugs and unresolved issues or limitations. So, make sure to fully test it in your project before enabling this option. + +::: + +1. Install `@typescript/native-preview` as a development dependency: + + + +::: tip Version requirements + +`@typescript/native-preview` requires Node.js 20.6.0 or higher. + +::: + +2. Configure in the Rslib config file: + +```ts title="rslib.config.ts" +export default { + lib: [ + { + dts: { + tsgo: true, // [!code highlight] + }, + }, + ], +}; +``` + +3. In order to ensure the consistency of local development, you need to install the corresponding [VS Code Preview Extension](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.native-preview) and add the following configuration in the VS Code settings: + +```json title=".vscode/settings.json" +{ + "typescript.experimental.useTsgo": true +} +``` + +### Notes -It should be noted that during the generation of declaration files, Rslib will automatically enforce some configuration options in `tsconfig.json` to ensure that the [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) generates only declaration files. +During the generation of declaration files, Rslib will automatically enforce some configuration options in `tsconfig.json` to ensure that the [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) or [tsgo](https://github.com/microsoft/typescript-go) generates only declaration files. ```json { @@ -84,6 +161,7 @@ The priority from highest to lowest of final output directory of declaration fil | [dts.abortOnError](/config/lib/dts#dtsabortonerror) | Whether to abort the build process when an error occurs during declaration files generation. | | [dts.autoExtension](/config/lib/dts#dtsautoextension) | Whether to automatically set the declaration file extension based on the [format](/config/lib/format) option. | | [dts.alias](/config/lib/dts#dtsalias) | The path alias of the declaration files. | +| [dts.tsgo](/config/lib/dts#dtstsgo) | Whether to generate declaration files with [tsgo](https://github.com/microsoft/TypeScript/pull/48729). | | [banner.dts](/config/lib/banner#bannerdts) | Inject content into the top of each declaration output file. | | [footer.dts](/config/lib/footer#footerdts) | Inject content into the bottom of each declaration file. | | [redirect.dts.path](/config/lib/redirect#redirectdtspath) | Whether to automatically redirect the import paths of TypeScript declaration output files. | diff --git a/website/docs/zh/config/lib/dts.mdx b/website/docs/zh/config/lib/dts.mdx index 22ec5a1a5..2f9757f9c 100644 --- a/website/docs/zh/config/lib/dts.mdx +++ b/website/docs/zh/config/lib/dts.mdx @@ -15,6 +15,7 @@ type Dts = abortOnError?: boolean; autoExtension?: boolean; alias?: Record; + tsgo?: boolean; } | boolean; ``` @@ -216,7 +217,9 @@ export default { ::: note -这遵循与 [lib.autoExtension](/config/lib/auto-extension) 相同的逻辑,但默认值不同,因为类型声明文件扩展名可能会在不同的模块解析策略中造成一些问题。 +1. 这遵循与 [lib.autoExtension](/config/lib/auto-extension) 相同的逻辑,但默认值不同,因为类型声明文件扩展名可能会在不同的模块解析策略中造成一些问题。 + +2. 当开启 [dts.tsgo](/config/lib/dts#dtstsgo) 时,如果项目同时开启了 [dts.build](/config/lib/dts#dtsbuild) 或者将不同后缀的类型声明文件输出到同一目录,`dts.autoExtension` 无法正常生效。 ::: @@ -245,3 +248,50 @@ export default { ], }; ``` + +### dts.tsgo + +- **类型:** `boolean` +- **默认值:** `false` + +是否使用 [tsgo](https://github.com/microsoft/typescript-go) 生成类型声明文件。tsgo 可以提供更快的类型声明文件生成速度,尤其是对于大型项目。 + +::: tip + +此功能目前为**实验性功能**。由于 tsgo 仍处于**实验阶段**,可能会存在一些 bug 以及未解决的问题或限制。因此,在启用该选项前,请确保在你的项目中进行充分测试。 + +::: + +启用该选项,你需要: + +1. 安装 [@typescript/native-preview](https://www.npmjs.com/package/@typescript/native-preview) 作为开发依赖。 + + + +::: tip 版本要求 + +`@typescript/native-preview` 要求 Node.js 20.6.0 或更高版本。 + +::: + +2. 在 Rslib 配置文件中设置: + +```ts title="rslib.config.ts" +export default { + lib: [ + { + dts: { + tsgo: true, // [!code highlight] + }, + }, + ], +}; +``` + +3. 为了保证本地开发的一致性,你需要安装对应的 [VS Code 预览版扩展](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.native-preview),并在 VS Code 设置中添加如下配置: + +```json title=".vscode/settings.json" +{ + "typescript.experimental.useTsgo": true +} +``` diff --git a/website/docs/zh/guide/advanced/dts.mdx b/website/docs/zh/guide/advanced/dts.mdx index fb20581e5..cd7fd9ca6 100644 --- a/website/docs/zh/guide/advanced/dts.mdx +++ b/website/docs/zh/guide/advanced/dts.mdx @@ -40,23 +40,103 @@ Bundleless 类型为库中的每个模块生成单独的声明文件,就像 `t ## 如何在 Rslib 中生成类型声明文件 -Rslib 默认使用 [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) 生成 bundleless 类型,用 [API Extractor](https://api-extractor.com/) 生成 bundle 类型。 - -如果你想生成 bundleless 类型,可以: - -- 设置 `dts: true` 或者 `dts: { bundle: false }` 在 Rslib 配置文件。 +Rslib 支持使用 [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) 和 [tsgo](https://github.com/microsoft/typescript-go) 两种方式来生成类型声明文件,并且支持使用 [API Extractor](https://api-extractor.com/) 将生成的类型声明文件打包。 + +| 类型 | 支持方式 | 说明 | +| ---------- | --------------------------------------- | -------- | +| bundleless | TypeScript Compiler API | 默认方式 | +| bundleless | tsgo | | +| bundle | TypeScript Compiler API + API Extractor | 默认方式 | +| bundle | tsgo + API Extractor | | + +### 生成 bundleless 类型 + +在 Rslib 配置文件中设置: + +```ts title="rslib.config.ts" +export default { + lib: [ + { + dts: true; // [!code highlight] + // 或者 + // [!code highlight:3] + dts: { + bundle: false; + } + }, + ], +}; +``` -如果你想生成 bundle 类型,可以: +### 生成 bundle 类型 -1. 安装 `@microsoft/api-extractor` 作为 `devDependencies`, 这是用于打包类型声明文件的底层工具。 +1. 安装 `@microsoft/api-extractor` 作为开发依赖,这是用于打包类型声明文件的底层工具。 import { PackageManagerTabs } from '@theme'; -2. 在 Rslib 配置文件中设置 `dts: { bundle: true }`。 +2. 在 Rslib 配置文件中设置: + +```ts title="rslib.config.ts" +export default { + lib: [ + { + // [!code highlight:3] + dts: { + bundle: true; + } + }, + ], +}; +``` + +### 使用 tsgo 生成类型声明文件 + +::: tip + +此功能目前为**实验性功能**。由于 tsgo 仍处于**实验阶段**,可能会存在一些 bug 以及未解决的问题或限制。因此,在启用该选项前,请确保在你的项目中进行充分测试。 + +::: + +1. 安装 `@typescript/native-preview` 作为开发依赖: + + + +::: tip 版本要求 + +`@typescript/native-preview` 要求 Node.js 20.6.0 或更高版本。 + +::: + +2. 在 Rslib 配置文件中设置: + +```ts title="rslib.config.ts" +export default { + lib: [ + { + dts: { + tsgo: true, // [!code highlight] + }, + }, + ], +}; +``` + +3. 为了保证本地开发的一致性,你需要安装对应的 [VS Code 预览版扩展](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.native-preview),并在 VS Code 设置中添加如下配置: + +```json title=".vscode/settings.json" +{ + "typescript.experimental.useTsgo": true +} +``` + +### 注意事项 -需要注意的是,Rslib 在生成类型声明文件的过程中,默认会强制设置 `tsconfig.json` 中的一些配置项以保证 [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) 能够仅生成类型声明文件。 +Rslib 在生成类型声明文件的过程中,默认会强制设置 `tsconfig.json` +中的一些配置项以保证 [TypeScript Compiler +API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) 或 [tsgo](https://github.com/microsoft/typescript-go) +能够仅生成类型声明文件。 ```json { @@ -76,15 +156,16 @@ import { PackageManagerTabs } from '@theme'; ## 类型声明文件的相关配置 -| 配置项 | 描述说明 | -| ------------------------------------------------------------------- | ---------------------------------------------------------------------- | -| [dts.bundle](/config/lib/dts#dtsbundle) | 是否打包类型声明文件。 | -| [dts.distPath](/config/lib/dts#dtsdistpath) | 类型声明文件的输出目录。 | -| [dts.build](/config/lib/dts#dtsbuild) | 是否在生成类型声明文件时构建项目的 project references。 | -| [dts.abortOnError](/config/lib/dts#dtsabortonerror) | 当类型声明文件生成过程中出现错误时,是否中止构建过程。 | -| [dts.autoExtension](/config/lib/dts#dtsautoextension) | 是否根据 [format](/config/lib/format) 选项自动设置类型声明文件扩展名。 | -| [dts.alias](/config/lib/dts#dtsalias) | 类型声明文件的路径别名。 | -| [banner.dts](/config/lib/banner#bannerdts) | 在每个类型声明文件顶部注入内容。 | -| [footer.dts](/config/lib/footer#footerdts) | 在每个类型声明文件底部注入内容。 | -| [redirect.dts.path](/config/lib/redirect#redirectdtspath) | 是否自动重定向类型声明文件中的导入路径。 | -| [redirect.dts.extension](/config/lib/redirect#redirectdtsextension) | 是否根据类型声明文件自动重定向文件扩展名到导入路径。 | +| 配置项 | 描述说明 | +| ------------------------------------------------------------------- | ------------------------------------------------------------------------------ | +| [dts.bundle](/config/lib/dts#dtsbundle) | 是否打包类型声明文件。 | +| [dts.distPath](/config/lib/dts#dtsdistpath) | 类型声明文件的输出目录。 | +| [dts.build](/config/lib/dts#dtsbuild) | 是否在生成类型声明文件时构建项目的 project references。 | +| [dts.abortOnError](/config/lib/dts#dtsabortonerror) | 当类型声明文件生成过程中出现错误时,是否中止构建过程。 | +| [dts.autoExtension](/config/lib/dts#dtsautoextension) | 是否根据 [format](/config/lib/format) 选项自动设置类型声明文件扩展名。 | +| [dts.alias](/config/lib/dts#dtsalias) | 类型声明文件的路径别名。 | +| [dts.tsgo](/config/lib/dts#dtstsgo) | 是否使用 [tsgo](https://github.com/microsoft/typescript-go) 生成类型声明文件。 | +| [banner.dts](/config/lib/banner#bannerdts) | 在每个类型声明文件顶部注入内容。 | +| [footer.dts](/config/lib/footer#footerdts) | 在每个类型声明文件底部注入内容。 | +| [redirect.dts.path](/config/lib/redirect#redirectdtspath) | 是否自动重定向类型声明文件中的导入路径。 | +| [redirect.dts.extension](/config/lib/redirect#redirectdtsextension) | 是否根据类型声明文件自动重定向文件扩展名到导入路径。 |