Skip to content

Commit

Permalink
feat(typescript): support multiple output targets with declarations (#…
Browse files Browse the repository at this point in the history
…687)

* feat(typescript): support multiple output targets with declarations

* Split statement into multiple for readability

Co-authored-by: Tiger Oakes <contact@tigeroakes.com>

Co-authored-by: Tiger Oakes <contact@tigeroakes.com>
  • Loading branch information
benmccann and NotWoods committed Dec 3, 2020
1 parent 8c3a3a6 commit a54d2a1
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 29 deletions.
8 changes: 6 additions & 2 deletions packages/typescript/src/index.ts
Expand Up @@ -125,11 +125,15 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
const output = findTypescriptOutput(ts, parsedOptions, fileName, emittedFiles, tsCache);
output.declarations.forEach((id) => {
const code = getEmittedFile(id, emittedFiles, tsCache);
if (!code) return;
let baseDir = outputOptions.dir;
if (!baseDir && tsconfig) {
baseDir = tsconfig.substring(0, tsconfig.lastIndexOf('/'));
}
if (!code || !baseDir) return;

this.emitFile({
type: 'asset',
fileName: normalizePath(path.relative(outputOptions.dir!, id)),
fileName: normalizePath(path.relative(baseDir, id)),
source: code
});
});
Expand Down
8 changes: 1 addition & 7 deletions packages/typescript/src/options/validate.ts
Expand Up @@ -53,13 +53,7 @@ export function validatePaths(
}

for (const dirProperty of DIRECTORY_PROPS) {
if (compilerOptions[dirProperty]) {
if (!outputOptions.dir) {
context.error(
`@rollup/plugin-typescript: Rollup 'dir' option must be used when Typescript compiler option '${dirProperty}' is specified.`
);
}

if (compilerOptions[dirProperty] && outputOptions.dir) {
// Checks if the given path lies within Rollup output dir
const fromRollupDirToTs = relative(outputOptions.dir, compilerOptions[dirProperty]!);
if (fromRollupDirToTs.startsWith('..')) {
Expand Down
2 changes: 2 additions & 0 deletions packages/typescript/test/fixtures/multiple-files/src/index.ts
@@ -0,0 +1,2 @@
const anExampleVariable: string = 'Index Page';
console.log(anExampleVariable);
@@ -0,0 +1,2 @@
const anotherExampleVariable: string = 'Server File';
console.log(anotherExampleVariable);
27 changes: 27 additions & 0 deletions packages/typescript/test/fixtures/multiple-files/tsconfig.json
@@ -0,0 +1,27 @@
{
"compilerOptions" : {
"outDir": ".",
"rootDir": "src",
"skipLibCheck": true,

"lib": ["es2020"],
"target": "es2020",

"declaration": true,

"noEmitOnError": true,
"noErrorTruncation": true,

"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,

"strict": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": ["src"],
"exclude": ["node_modules"]
}
43 changes: 23 additions & 20 deletions packages/typescript/test/test.js
Expand Up @@ -206,16 +206,6 @@ test.serial('ensures outDir is located in Rollup output dir', async (t) => {
onwarn
});

const noDirError = await t.throwsAsync(() =>
getCode(bundle, { format: 'esm', file: 'fixtures/basic/other/out.js' }, true)
);
t.true(
noDirError.message.includes(
`Rollup 'dir' option must be used when Typescript compiler option 'outDir' is specified`
),
`Unexpected error message: ${noDirError.message}`
);

const wrongDirError = await t.throwsAsync(() =>
getCode(bundle, { format: 'esm', dir: 'fixtures/basic/dist' }, true)
);
Expand All @@ -240,16 +230,6 @@ test.serial('ensures declarationDir is located in Rollup output dir', async (t)
onwarn
});

const noDirError = await t.throwsAsync(() =>
getCode(bundle, { format: 'esm', file: 'fixtures/basic/other/out.js' }, true)
);
t.true(
noDirError.message.includes(
`Rollup 'dir' option must be used when Typescript compiler option 'declarationDir' is specified`
),
`Unexpected error message: ${noDirError.message}`
);

const wrongDirError = await t.throwsAsync(() =>
getCode(bundle, { format: 'esm', dir: 'fixtures/basic/dist' }, true)
);
Expand All @@ -261,6 +241,29 @@ test.serial('ensures declarationDir is located in Rollup output dir', async (t)
);
});

test.serial('ensures multiple outputs can be built', async (t) => {
// In a rollup.config.js we would pass an array
// The rollup method that's exported as a library won't do that so we must make two calls
const bundle1 = await rollup({
input: 'fixtures/multiple-files/src/index.ts',
plugins: [typescript({ tsconfig: 'fixtures/multiple-files/tsconfig.json' })]
});

const output1 = await getCode(bundle1, { file: 'fixtures/multiple-files/index.js', format: 'cjs' }, true);

const bundle2 = await rollup({
input: 'fixtures/multiple-files/src/server.ts',
plugins: [typescript({ tsconfig: 'fixtures/multiple-files/tsconfig.json' })]
});

const output2 = await getCode(bundle2, { file: 'fixtures/multiple-files/server.js', format: 'cjs' }, true);

t.deepEqual(
[...new Set(output1.concat(output2).map((out) => out.fileName))].sort(),
['index.d.ts', 'index.js', 'server.d.ts', 'server.js']
);
});

test.serial('relative paths in tsconfig.json are resolved relative to the file', async (t) => {
const bundle = await rollup({
input: 'fixtures/relative-dir/main.ts',
Expand Down

0 comments on commit a54d2a1

Please sign in to comment.