Skip to content

Commit

Permalink
fix: make declaration files work with multiple entrypoints
Browse files Browse the repository at this point in the history
closes #316
  • Loading branch information
egoist committed Oct 22, 2021
1 parent 0f7837d commit a4a5404
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 3 deletions.
47 changes: 47 additions & 0 deletions src/rollup.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import path from 'path'
import { parentPort } from 'worker_threads'
import { InputOptions, OutputOptions, Plugin } from 'rollup'
import { NormalizedOptions } from './'
Expand All @@ -19,6 +20,48 @@ type RollupConfig = {
outputConfig: OutputOptions
}

const findLowestCommonAncestor = (filepaths: string[]) => {
if (filepaths.length <= 1) return ''
const [first, ...rest] = filepaths
let ancestor = first.split('/')
for (const filepath of rest) {
const directories = filepath.split('/', ancestor.length)
let index = 0
for (const directory of directories) {
if (directory === ancestor[index]) {
index += 1
} else {
ancestor = ancestor.slice(0, index)
break
}
}
ancestor = ancestor.slice(0, index)
}

return ancestor.length <= 1 && ancestor[0] === ''
? '/' + ancestor[0]
: ancestor.join('/')
}

// Make sure the Rollup entry is an object
// We use the base path (without extension) as the entry name
// To make declaration files work with multiple entrypoints
// See #316
const toObjectEntry = (entry: string[]) => {
entry = entry.map((e) => e.replace(/\\/g, '/'))
const ancester = findLowestCommonAncestor(entry)
return entry.reduce((result, item) => {
const key = item
.replace(ancester, '')
.replace(/^\//, '')
.replace(/\.[a-z]+$/, '')
return {
...result,
[key]: item,
}
}, {})
}

const getRollupConfig = async (
options: NormalizedOptions
): Promise<RollupConfig> => {
Expand All @@ -37,6 +80,10 @@ const getRollupConfig = async (
? { entry: options.entryPoints }
: { entry: options.entryPoints, ...options.dts }

if (Array.isArray(dtsOptions.entry)) {
dtsOptions.entry = toObjectEntry(dtsOptions.entry)
}

let tsResolveOptions: TsResolveOptions | undefined

if (dtsOptions.resolve) {
Expand Down
33 changes: 30 additions & 3 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ async function run(
testDir: string,
files: { [name: string]: string },
options: {
entry?: string[]
flags?: string[]
env?: Record<string, string>
} = {}
Expand All @@ -34,10 +35,12 @@ async function run(
})
)

const entry = options.entry || ['input.ts']

// Run tsup cli
const { exitCode, stdout, stderr } = await execa(
bin,
['input.ts', ...(options.flags || [])],
[...entry, ...(options.flags || [])],
{
cwd: testDir,
env: { ...process.env, ...options.env },
Expand All @@ -49,13 +52,14 @@ async function run(
}

// Get output
const output = await fs.readFile(resolve(testDir, 'dist/input.js'), 'utf8')
const outFiles = await glob('**/*', {
cwd: resolve(testDir, 'dist'),
}).then((res) => res.sort())

return {
output,
get output() {
return fs.readFileSync(resolve(testDir, 'dist/input.js'), 'utf8')
},
outFiles,
logs,
getFileContent(filename: string) {
Expand Down Expand Up @@ -987,3 +991,26 @@ test('code splitting in cjs format', async () => {
"
`)
})

test('declaration files with multiple entrypoints #316', async () => {
const { getFileContent } = await run(
getTestName(),
{
'src/index.ts': `export const foo = 1`,
'src/bar/index.ts': `export const bar = 'bar'`,
},
{ flags: ['--dts'], entry: ['src/index.ts', 'src/bar/index.ts'] }
)
expect(await getFileContent('dist/index.d.ts')).toMatchInlineSnapshot(`
"declare const foo = 1;
export { foo };
"
`)
expect(await getFileContent('dist/bar/index.d.ts')).toMatchInlineSnapshot(`
"declare const bar = \\"bar\\";
export { bar };
"
`)
})

1 comment on commit a4a5404

@vercel
Copy link

@vercel vercel bot commented on a4a5404 Oct 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.