Skip to content

Commit

Permalink
feat: basic implementation of dts generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Timeless0911 committed Aug 1, 2024
1 parent f8965f1 commit fceec04
Show file tree
Hide file tree
Showing 41 changed files with 1,183 additions and 53 deletions.
4 changes: 2 additions & 2 deletions e2e/cases/alias/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { expect, test } from 'vitest';
import { buildAndGetJsResults } from '#shared';
import { buildAndGetResults } from '#shared';

test('source.alias', async () => {
const fixturePath = __dirname;
const { entries } = await buildAndGetJsResults(fixturePath);
const { entries } = await buildAndGetResults(fixturePath);

expect(entries.esm).toContain('hello world');
expect(entries.cjs).toContain('hello world');
Expand Down
6 changes: 3 additions & 3 deletions e2e/cases/autoExtension/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { extname, join } from 'node:path';
import { expect, test } from 'vitest';
import { buildAndGetJsResults } from '#shared';
import { buildAndGetResults } from '#shared';

test('autoExtension generate .mjs in build artifacts with esm format when type is commonjs', async () => {
const fixturePath = join(__dirname, 'type-commonjs');
const { entryFiles } = await buildAndGetJsResults(fixturePath);
const { entryFiles } = await buildAndGetResults(fixturePath);
expect(extname(entryFiles.esm!)).toEqual('.mjs');
expect(extname(entryFiles.cjs!)).toEqual('.js');
});

test('autoExtension generate .cjs in build artifacts with cjs format when type is module', async () => {
const fixturePath = join(__dirname, 'type-module');
const { entryFiles } = await buildAndGetJsResults(fixturePath);
const { entryFiles } = await buildAndGetResults(fixturePath);
expect(extname(entryFiles.esm!)).toEqual('.js');
expect(extname(entryFiles.cjs!)).toEqual('.cjs');
});
4 changes: 2 additions & 2 deletions e2e/cases/bundle-false/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { join } from 'node:path';
import { expect, test } from 'vitest';
import { buildAndGetJsResults } from '#shared';
import { buildAndGetResults } from '#shared';

test('bundle: false', async () => {
const fixturePath = join(__dirname, 'basic');
const { files } = await buildAndGetJsResults(fixturePath);
const { files } = await buildAndGetResults(fixturePath);

// TODO: record file paths with inline snapshot
// need to add path serialization
Expand Down
4 changes: 2 additions & 2 deletions e2e/cases/define/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { expect, test } from 'vitest';
import { buildAndGetJsResults } from '#shared';
import { buildAndGetResults } from '#shared';

test('source.define', async () => {
const fixturePath = __dirname;
const { entries } = await buildAndGetJsResults(fixturePath);
const { entries } = await buildAndGetResults(fixturePath);

expect(entries.esm).not.toContain('console.info(VERSION)');
expect(entries.esm).toContain('1.0.0');
Expand Down
44 changes: 44 additions & 0 deletions e2e/cases/dts/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`dts when bundle: false 1`] = `
{
"./dist/esm/index.d.ts": "export * from './utils/numbers';
export * from './utils/strings';
export * from './sum';
",
"./dist/esm/sum.d.ts": "export declare const numSum: number;
export declare const strSum: string;
",
"./dist/esm/utils/numbers.d.ts": "export declare const num1 = 1;
export declare const num2 = 2;
export declare const num3 = 3;
",
"./dist/esm/utils/strings.d.ts": "export declare const str1 = "str1";
export declare const str2 = "str2";
export declare const str3 = "str3";
",
}
`;

exports[`dts when bundle: true 1`] = `
{
"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 { }
",
}
`;
21 changes: 21 additions & 0 deletions e2e/cases/dts/bundle-false/rslib.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { defineConfig } from '@rslib/core';
import { generateBundleCjsConfig, generateBundleEsmConfig } from '#shared';

export default defineConfig({
lib: [
generateBundleEsmConfig(__dirname, {
bundle: false,
dts: {
bundle: false,
},
}),
generateBundleCjsConfig(__dirname, {
bundle: false,
}),
],
source: {
entry: {
main: ['./src/**'],
},
},
});
3 changes: 3 additions & 0 deletions e2e/cases/dts/bundle-false/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './utils/numbers';
export * from './utils/strings';
export * from './sum';
5 changes: 5 additions & 0 deletions e2e/cases/dts/bundle-false/src/sum.ts
Original file line number Diff line number Diff line change
@@ -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;
3 changes: 3 additions & 0 deletions e2e/cases/dts/bundle-false/src/utils/numbers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const num1 = 1;
export const num2 = 2;
export const num3 = 3;
3 changes: 3 additions & 0 deletions e2e/cases/dts/bundle-false/src/utils/strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const str1 = 'str1';
export const str2 = 'str2';
export const str3 = 'str3';
7 changes: 7 additions & 0 deletions e2e/cases/dts/bundle-false/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "@rslib/tsconfig/base",
"compilerOptions": {
"baseUrl": "./"
},
"include": ["src"]
}
6 changes: 6 additions & 0 deletions e2e/cases/dts/bundle/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "dts-bundle-test",
"version": "1.0.0",
"private": true,
"type": "module"
}
21 changes: 21 additions & 0 deletions e2e/cases/dts/bundle/rslib.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { defineConfig } from '@rslib/core';
import {
generateBundleCjsConfig,
generateBundleEsmConfig,
} from '../../../scripts/shared';

export default defineConfig({
lib: [
generateBundleEsmConfig(__dirname, {
dts: {
bundle: true,
},
}),
generateBundleCjsConfig(__dirname),
],
source: {
entry: {
main: './src/index.ts',
},
},
});
3 changes: 3 additions & 0 deletions e2e/cases/dts/bundle/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './utils/numbers';
export * from './utils/strings';
export * from './sum';
5 changes: 5 additions & 0 deletions e2e/cases/dts/bundle/src/sum.ts
Original file line number Diff line number Diff line change
@@ -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;
3 changes: 3 additions & 0 deletions e2e/cases/dts/bundle/src/utils/numbers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const num1 = 1;
export const num2 = 2;
export const num3 = 3;
3 changes: 3 additions & 0 deletions e2e/cases/dts/bundle/src/utils/strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const str1 = 'str1';
export const str2 = 'str2';
export const str3 = 'str3';
7 changes: 7 additions & 0 deletions e2e/cases/dts/bundle/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "@rslib/tsconfig/base",
"compilerOptions": {
"baseUrl": "./"
},
"include": ["src"]
}
20 changes: 20 additions & 0 deletions e2e/cases/dts/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { join } from 'node:path';
import { expect, test } from 'vitest';
import { buildAndGetResults } from '#shared';

test('dts when bundle: false', async () => {
const fixturePath = join(__dirname, 'bundle-false');
const { files, contents } = await buildAndGetResults(fixturePath, 'dts');

expect(files.esm?.length).toBe(4);
expect(files.esm?.[0]!.endsWith('.d.ts')).toEqual(true);
expect(contents.esm).toMatchSnapshot();
});

test('dts when bundle: true', async () => {
const fixturePath = join(__dirname, 'bundle');
const { entryFiles, entries } = await buildAndGetResults(fixturePath, 'dts');

expect(entryFiles.esm!.endsWith('index.d.ts')).toEqual(true);
expect(entries).toMatchSnapshot();
});
4 changes: 2 additions & 2 deletions e2e/cases/externals/browser/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { join } from 'node:path';
import { expect, test } from 'vitest';
import { buildAndGetJsResults } from '#shared';
import { buildAndGetResults } from '#shared';

test('should fail to build when `output.target` is not "node"', async () => {
const fixturePath = join(__dirname);
const build = buildAndGetJsResults(fixturePath);
const build = buildAndGetResults(fixturePath);
await expect(build).rejects.toThrowError('Rspack build failed!');
});
4 changes: 2 additions & 2 deletions e2e/cases/externals/node/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { join } from 'node:path';
import { expect, test } from 'vitest';
import { buildAndGetJsResults } from '#shared';
import { buildAndGetResults } from '#shared';

test('auto externalize Node.js built-in modules when `output.target` is "node"', async () => {
const fixturePath = join(__dirname);
const { entries } = await buildAndGetJsResults(fixturePath);
const { entries } = await buildAndGetResults(fixturePath);

for (const external of [
'import * as __WEBPACK_EXTERNAL_MODULE_fs__ from "fs"',
Expand Down
4 changes: 2 additions & 2 deletions e2e/cases/syntax/config/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { expect, test } from 'vitest';
import { buildAndGetJsResults } from '#shared';
import { buildAndGetResults } from '#shared';

test('should downgrade class private method by default', async () => {
const fixturePath = __dirname;
const { entries } = await buildAndGetJsResults(fixturePath);
const { entries } = await buildAndGetResults(fixturePath);

expect(entries.esm).toMatchSnapshot();
expect(entries.esm).not.toContain('#bar');
Expand Down
4 changes: 2 additions & 2 deletions e2e/cases/syntax/default/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { expect, test } from 'vitest';
import { buildAndGetJsResults } from '#shared';
import { buildAndGetResults } from '#shared';

test('should downgrade class private method by default', async () => {
const fixturePath = __dirname;
const { entries } = await buildAndGetJsResults(fixturePath);
const { entries } = await buildAndGetResults(fixturePath);

expect(entries.esm).toMatchSnapshot();
expect(entries.esm).toContain('#bar');
Expand Down
2 changes: 1 addition & 1 deletion e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"devDependencies": {
"@playwright/test": "1.43.1",
"@rsbuild/core": "1.0.1-beta.6",
"@rsbuild/core": "1.0.1-beta.8",
"@rslib/core": "workspace:*",
"@rslib/tsconfig": "workspace:*",
"@types/fs-extra": "^11.0.4",
Expand Down
56 changes: 43 additions & 13 deletions e2e/scripts/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,31 +37,58 @@ export function generateBundleCjsConfig(
return mergeConfig(cjsBasicConfig, config)!;
}

export async function getJsResults(rslibConfig: RslibConfig) {
export async function getResults(
rslibConfig: RslibConfig,
fixturePath: string,
type: 'js' | 'dts',
) {
const files: Record<string, string[]> = {};
const contents: Record<string, Record<string, string>> = {};
const entries: Record<string, string> = {};
const entryFiles: Record<string, string> = {};

for (const libConfig of rslibConfig.lib) {
const content = await globContentJSON(libConfig?.output?.distPath?.root!, {
let globFolder = '';
if (type === 'js') {
globFolder = libConfig?.output?.distPath?.root!;
} else if (type === 'dts' && libConfig.dts !== false) {
globFolder =
libConfig.dts?.distPath! ?? libConfig?.output?.distPath?.root!;
}

if (!globFolder) continue;

const regex = type === 'dts' ? /\.d.(ts|cts|mts)$/ : /\.(js|cjs|mjs)$/;

const rawContent = await globContentJSON(globFolder, {
absolute: true,
ignore: ['/**/*.map'],
});

const jsFiles = Object.keys(content).filter((file) =>
/\.(js|cjs|mjs)$/.test(file),
);
const content: Record<string, string> = {};

for (const key of Object.keys(rawContent)) {
const newKey = key.replace(fixturePath, '.');
content[newKey] = rawContent[key]!;
}

const fileSet = Object.keys(content).filter((file) => regex.test(file));
const filterContent: Record<string, string> = {};
for (const key of fileSet) {
if (content[key]) {
filterContent[key] = content[key];
}
}

if (jsFiles.length) {
files[libConfig.format!] = jsFiles;
contents[libConfig.format!] = content;
if (fileSet.length) {
files[libConfig.format!] = fileSet;
contents[libConfig.format!] = filterContent;
}

// Only applied in bundle mode, a shortcut to get single entry result
if (libConfig.bundle !== false && jsFiles.length === 1) {
entries[libConfig.format!] = Object.values(content)[0]!;
entryFiles[libConfig.format!] = jsFiles[0]!;
if (libConfig.bundle !== false && fileSet.length === 1) {
entries[libConfig.format!] = content[fileSet[0]!]!;
entryFiles[libConfig.format!] = fileSet[0]!;
}
}

Expand All @@ -73,11 +100,14 @@ export async function getJsResults(rslibConfig: RslibConfig) {
};
}

export const buildAndGetJsResults = async (fixturePath: string) => {
export const buildAndGetResults = async (
fixturePath: string,
type: 'js' | 'dts' = 'js',
) => {
const rslibConfig = await loadConfig(join(fixturePath, 'rslib.config.ts'));
process.chdir(fixturePath);
await build(rslibConfig);
const results = await getJsResults(rslibConfig);
const results = await getResults(rslibConfig, fixturePath, type);
return {
contents: results.contents,
files: results.files,
Expand Down
7 changes: 6 additions & 1 deletion packages/core/modern.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { defineConfig, moduleTools } from '@modern-js/module-tools';
import prebundleConfig from './prebundle.config.mjs';

const externals = ['@rsbuild/core', /[\\/]compiled[\\/]/, /node:/];
const externals = [
'@rsbuild/core',
/[\\/]compiled[\\/]/,
/node:/,
'typescript',
];
const define = {
RSLIB_VERSION: require('./package.json').version,
};
Expand Down
Loading

0 comments on commit fceec04

Please sign in to comment.