Skip to content

Commit

Permalink
feat: add basic support to generate separate type declarations files …
Browse files Browse the repository at this point in the history
…when building ts dual packages
  • Loading branch information
promer94 committed Jun 28, 2023
1 parent acba9da commit da897e2
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 13 deletions.
15 changes: 9 additions & 6 deletions src/build-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
getExportPaths,
getExportConditionDist,
isEsmExportName,
getExportTypeDist,
} from './exports'
import {
isNotNull,
Expand Down Expand Up @@ -232,10 +233,10 @@ function buildOutputConfigs(
const name = filenameWithoutExtension(file)

// TODO: simplify dts file name detection
const dtsFile = exportCondition.export['types']
? resolve(cwd, exportCondition.export['types'])
: file
? name + '.d.ts'
const dtsFile = file
? file
: exportCondition.export['types']
? resolve(cwd, exportCondition.export['types'])
: resolve(
dtsDir,
(exportCondition.name === '.' ? 'index' : exportCondition.name) +
Expand Down Expand Up @@ -361,21 +362,23 @@ function buildConfig(

// Generate dts job - single config
if (dts) {
outputConfigs = [
const typeOutputExports = getExportTypeDist(exportCondition, cwd)
outputConfigs = typeOutputExports.map(v =>
buildOutputConfigs(
pkg,
exportPaths,
{
...bundleConfig,
format: 'es',
useTypescript,
file: v
},
exportCondition,
cwd,
tsOptions,
dts
),
]
)
} else {
// multi outputs with specified format
outputConfigs = outputExports.map((exportDist) => {
Expand Down
26 changes: 26 additions & 0 deletions src/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,32 @@ export function getExportPaths(pkg: PackageMetadata) {
return pathsMap
}

export const getExportTypeDist = (
parsedExportCondition: ParsedExportCondition,
cwd: string
) => {
const existed = new Set<string>()
const exportTypes = Object.keys(parsedExportCondition.export)
for (const key of exportTypes) {
if (key === 'types' || key === 'module') {
continue
}
const filePath = parsedExportCondition.export[key]
const ext = extname(filePath).slice(1)
const dtsExtentions: Record<string, string> = {
'js': '.d.ts',
'cjs': '.d.cts',
'mjs': '.d.mts',
}
const typeFile = getDistPath(`${filenameWithoutExtension(filePath) || ''}${dtsExtentions[ext]}`, cwd)
if (existed.has(typeFile)) {
continue
}
existed.add(typeFile)
}
return Array.from(existed)
}

export function getPackageType(pkg: PackageMetadata): PackageType {
return pkg.type || 'commonjs'
}
Expand Down
2 changes: 1 addition & 1 deletion src/logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function logSizeStats() {
const maxLength = Math.max(...stats.map(([filename]) => filename.length))
stats.forEach(([filename, prettiedSize]) => {
const padding = ' '.repeat(maxLength - filename.length)
const action = filename.endsWith('.d.ts') ? 'Typed' : 'Built'
const action = [".d.cts", ".d.mts", '.d.ts'].some(n => filename.endsWith(n)) ? 'Typed' : 'Built'
logger.log(` ✓ ${action} ${filename}${padding} - ${prettiedSize}`)
})
}
43 changes: 38 additions & 5 deletions test/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const testCases: {
'./dist/index.mjs': /const shared = true/,
'./dist/react-server.mjs': /'react-server'/,
'./dist/react-native.js': /'react-native'/,
'./dist/index.d.ts': /declare const shared = true/,
'./dist/index.d.mts': /declare const shared = true/,
})
},
},
Expand Down Expand Up @@ -123,15 +123,18 @@ const testCases: {
assertFilesContent(dir, contentsRegex)

const log = `\
✓ Typed dist/client/index.d.ts - 74 B
✓ Typed dist/server/index.d.mts - 87 B
✓ Typed dist/index.d.ts - 65 B
✓ Typed dist/client/index.d.cts - 74 B
✓ Typed dist/client/index.d.mts - 74 B
✓ Built dist/index.js - 110 B
✓ Built dist/shared/edge-light.mjs - 84 B
✓ Built dist/lite.js - 132 B
✓ Built dist/client/index.cjs - 138 B
✓ Built dist/client/index.mjs - 78 B
✓ Built dist/index.js - 110 B
✓ Built dist/shared/index.mjs - 53 B
✓ Built dist/lite.js - 132 B
✓ Built dist/shared/edge-light.mjs - 84 B
✓ Built dist/server/react-server.mjs - 53 B
✓ Built dist/server/index.mjs - 71 B
✓ Built dist/server/edge.mjs - 51 B
`

Expand All @@ -141,6 +144,36 @@ const testCases: {
})
},
},
{
name: 'ts-dual-esm-cjs',
args: [],
async expected(dir) {
const distFiles = [
join(dir, './dist/index.js'),
join(dir, './dist/index.mjs'),
join(dir, './dist/index.d.ts'),
join(dir, './dist/index.d.mts'),
]
for (const f of distFiles) {
expect(await existsFile(f)).toBe(true)
}
},
},
{
name: 'ts-dual-esm-cjs-type-module',
args: [],
async expected(dir) {
const distFiles = [
join(dir, './dist/index.js'),
join(dir, './dist/index.cjs'),
join(dir, './dist/index.d.ts'),
join(dir, './dist/index.d.cts'),
]
for (const f of distFiles) {
expect(await existsFile(f)).toBe(true)
}
},
},
{
name: 'single-entry',
args: [],
Expand Down
10 changes: 10 additions & 0 deletions test/integration/ts-dual-esm-cjs-type-module/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "ts-dual-esm-cjs-type-module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"type": "module",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
}
1 change: 1 addition & 0 deletions test/integration/ts-dual-esm-cjs-type-module/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => 'index'
5 changes: 5 additions & 0 deletions test/integration/ts-dual-esm-cjs-type-module/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"allowJs": true
}
}
9 changes: 9 additions & 0 deletions test/integration/ts-dual-esm-cjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "ts-dual-esm-cjs",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
}
1 change: 1 addition & 0 deletions test/integration/ts-dual-esm-cjs/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => 'index'
5 changes: 5 additions & 0 deletions test/integration/ts-dual-esm-cjs/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"allowJs": true
}
}
50 changes: 49 additions & 1 deletion test/lib-unit/exports.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PackageMetadata } from 'src/types'
import path from 'path'
import { getExportPaths, getExportConditionDist } from '../../src/exports'
import { getExportPaths, getExportConditionDist, getExportTypeDist } from '../../src/exports'

describe('lib exports', () => {
describe('getExportPaths', () => {
Expand Down Expand Up @@ -204,4 +204,52 @@ describe('lib exports', () => {
])
})
})
describe('getExportTypeDist', () => {
function getExportTypeDistHelper(
pkg: PackageMetadata,
exportName: string = '.'
) {
const parsedExportCondition = getExportPaths(pkg)
const parsedExport = {
source: `./src/${exportName === '.' ? 'index' : exportName}.ts`,
name: exportName,
export: parsedExportCondition[exportName],
}
// Get only basename to skip path.resolve result for `file` property
return getExportTypeDist(parsedExport, '').map(filename => path.basename(filename))
}
it('should handle the basic main fields paths (esm)', () => {
const pkg: PackageMetadata = {
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"module": "./dist/index.esm.js",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
}
const result = getExportTypeDistHelper(pkg)
expect(result).toEqual([
"index.d.mts",
"index.d.ts",
])
})
it('should handle type: module', () => {
const pkg: PackageMetadata = {
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"module": "./dist/index.esm.js",
"type": "module",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
}
const result = getExportTypeDistHelper(pkg)
expect(result).toEqual([
"index.d.ts",
"index.d.cts",
])
})
})
})

0 comments on commit da897e2

Please sign in to comment.