-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Building multiple projects with same top-level configs (Rollup, tsconfig
) results in declarations for *all* projects output for each project
#72
Comments
Looks like your tsconfig includes everything under This plugin generates definitions for all ts files typescript sees during compilation (instead of only generating types for file rollup requests during build) because rollup ignores type-only imports. In your case you see a side-effect of that. If you run What tool do you use for generating rollup config? If it has a way to pass options to this plugin you can either create two tsconfigs with appropriate |
Same problem, plugin generates wrongs dts paths in lerna environment. Look at my project https://github.com/zerkalica/zerollup plugins: [
typescript({
abortOnError: true,
check: true,
exclude: ['*.spec*', '**/*.spec*'],
tsconfig: path.join(__dirname, 'tsconfig.json'),
tsconfigOverride: {
// compilerOptions: {
// rootDir: cwd
// },
include: [
__dirname + '/packages/*/src'
]
}
})
], With rootDir uncommented, ts generates errors:
tsconfig.json {
"compilerOptions": {
"baseUrl": "packages",
"paths": {
"@zerollup/*": [ "./*/src" ]
},
"allowSyntheticDefaultImports": false,
"declaration": true,
"module": "esnext",
"target": "es5",
"moduleResolution": "node",
"sourceMap": true,
"lib": [
"dom",
"esnext"
],
"jsx": "react",
"noImplicitAny": false,
"noUnusedLocals": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"removeComments": false,
"experimentalDecorators": true
},
"include": [
"packages/*/src"
],
"exclude": ["node_modules", "**/node_modules/*"]
} Inferno uses ts2 rollup plugin and have same problem with path: https://github.com/infernojs/inferno/blob/master/scripts/typings/build.js#L13 |
I managed to get it working. For reference, this is the main part of the script I'm using to generate rollup config: import autoExternal from 'rollup-plugin-auto-external';
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import typescript from 'rollup-plugin-typescript2';
const readFile = promisify(fs.readFile);
export default async ({ location, main, name }) => {
const pkg = JSON.parse(
await readFile(path.resolve(location, 'package.json'), {
encoding: 'utf-8',
}),
);
return {
input: path.resolve(location, main),
output: [
{ format: 'cjs', file: path.resolve(location, 'dist', `${name}.js`) },
{ format: 'es', file: path.resolve(location, 'dist', `${name}.mjs`) },
],
plugins: [
autoExternal({
builtins: true,
dependencies: true,
packagePath: location,
peerDependencies: true,
}),
typescript({
tsconfigOverride: {
compilerOptions: {
rootDir: path.resolve(location, 'src'),
},
include: [path.resolve(location, 'src')],
},
}),
],
};
}; |
It's not works for package in package directory which depends on another package in package directory. npm run build.plugin-template
|
@zerkalica You should remove your |
You can see my setup here: https://github.com/YoloDev/aspnet-node-utils |
Thank you @Alxandr Working configs: rollup.config.js plugins: [
typescript({
abortOnError: true,
check: true,
exclude: ['*.spec*', '**/*.spec*'],
tsconfig: path.join(__dirname, 'tsconfig.json'),
tsconfigOverride: {
compilerOptions: {
paths: [],
rootDir: path.join(cwd, 'src')
},
include: [path.join(cwd, 'src')]
}
})
], tsconfig.json {
"compilerOptions": {
"baseUrl": "packages",
"paths": {
"@zerollup/*": [ "./*/src" ]
},
"allowSyntheticDefaultImports": false,
"declaration": true,
"module": "esnext",
"target": "es5",
"moduleResolution": "node",
"sourceMap": true,
"lib": [
"dom",
"esnext"
],
"jsx": "react",
"noImplicitAny": false,
"noUnusedLocals": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"removeComments": false,
"experimentalDecorators": true
},
"exclude": ["node_modules", "**/node_modules/*"]
} |
@Alxandr @zerkalica looks like you both have a workaround. Doesn't look like I can do much to handle this situation automatically -- project structure information is unavailable to typescript before you define it in those overrides. Another option, possibly cleaner, is to have a base tsconfig and individual tsconfigs for subprojects (located in subproject folders) that all extend base file (see |
@ezolenko Yes. I get that, but I was trying to get this working with minimal things having to be replaced per package. Also, I didn't know that it was caused by where my tsconfig lives, but thought instead it was caused by where my rollup config lived. Therefore I split my rollup config up into one per package, but that didn't help, and as such I made this issue. I would suggest having some documentation/examples for this in the readme :). @zerkalica I can't speak to why you're not getting it working without keeping paths, but I can guess (as I don't have all the info). As said, the important part is in [Edit] |
@Alxandr
With src directory included, we can completely disable d.ts generation. May be you right. @ezolenko Have you some examples, how to do it without customizing tsconfig.json per each package in packages directory? |
@zerkalica I haven't tried that, but I suspect if you create base tsconfig file with all the interesting options in the root, then create per-package tsconfigs that Typescript will use tsconfig location as your source root and default values for |
If I'm not mistaken, that doesn't work. When you extend a tsconfig, you get it's base path and include path. At least that used to be the case. |
@zerkalica You're using lerna, right? I'm trying to set up a script (using lerna lifecycle methods) such that when the package is being published it changes the |
If derived tsconfig inherits default |
I try to use separate tsconfig.json per project (lerna demo project). And found a bug with multiple instances of ts plugin and declaration files. Use rollup.config.js import * as path from 'path'
import typescript from 'rollup-plugin-typescript2'
import resolve from 'rollup-plugin-node-resolve'
import replace from 'rollup-plugin-replace'
import commonjs from 'rollup-plugin-commonjs'
const pkgRoot = path.join(__dirname, 'packages')
export default [
{
input: path.join(pkgRoot, 'lib1', 'src', 'index.ts'),
output: {
format: 'es',
file: path.join(pkgRoot, 'lib1', 'dist', 'index.mjs')
},
plugins: [
resolve(),
commonjs(),
typescript({
// verbosity: 3,
tsconfig: path.join(pkgRoot, 'lib1', 'tsconfig.json')
})
]
},
{
input: path.join(pkgRoot, 'lib2', 'src', 'index.ts'),
output: {
format: 'es',
file: path.join(pkgRoot, 'lib2', 'dist', 'index.mjs')
},
plugins: [
resolve(),
commonjs(),
typescript({
// verbosity: 3,
tsconfig: path.join(pkgRoot, 'lib2', 'tsconfig.json')
})
]
}
]
packages/lib2/tsconfig.json {
"extends": "../../tsconfig.json",
"compilerOptions": {
"paths": {
"~/*": ["lib1/src/*"],
"zerollup-demo-lib1/*": ["lib1/src/*"],
"zerollup-demo-*": ["*/src"]
}
}
} tsconfig.json {
"compilerOptions": {
"baseUrl": "packages",
"newLine": "LF",
"allowSyntheticDefaultImports": false,
"module": "esnext",
"target": "es5",
"declaration": true,
"moduleResolution": "node",
"sourceMap": true,
"lib": [
"dom",
"esnext"
],
"jsx": "react",
"noImplicitAny": false,
"noUnusedLocals": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"removeComments": false,
"experimentalDecorators": true
}
} |
@zerkalica bug being? Just having a |
Does it work if you add |
@Alxandr What do you mean? baseUrl resolved relative main tsconfig.json. lib1 and lib2 configs inherits resolved baseUrl and typescript in vscode works fine with this aliases. I try this, but this not helps: packages/lib1/tsconfig.json {
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"paths": {
"~/*": ["lib1/src/*"],
"zerollup-demo-lib1/*": ["lib1/src/*"],
"zerollup-demo-*": ["*/src"]
}
}
} packages/lib2/tsconfig.json {
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"paths": {
"~/*": ["lib2/src/*"],
"zerollup-demo-lib2/*": ["lib2/src/*"],
"zerollup-demo-*": ["*/src"]
}
}
} @ezolenko packages/lib1/tsconfig.json {
"extends": "../../tsconfig.json",
"compilerOptions": {
"paths": {
"~/*": ["lib1/src/*"],
"zerollup-demo-lib1/*": ["lib1/src/*"],
"zerollup-demo-*": ["*/src"]
}
},
"include": [
"./src"
]
} packages/lib2/tsconfig.json {
"extends": "../../tsconfig.json",
"compilerOptions": {
"paths": {
"~/*": ["lib2/src/*"],
"zerollup-demo-lib2/*": ["lib2/src/*"],
"zerollup-demo-*": ["*/src"]
}
},
"include": [
"./src",
"../lib1/src"
]
}
|
After investigation, i think, generate d.ts per package is a bad idea. Tilda paths not working correctly in vscode, too complex setup (setup alias plugin, includes, excludes, rootDir in tsconfig.json per each packgage), too much caveats (alias plugin not working for index files) and boilerplate. Cleanest solution - is a completly disable d.ts generation, add src directory into package and set typings directory in package.json to src. Hacked solultion - use two instances of ts-plugin: first insance in first rollup config block generates d.ts for all packages in temporal declarationDir directory, second instance in other rollup config blocks with disabled declarations. This solution needs a plugin, which copies generated in temp dir d.ts to packages/*/dist/typings. rollup.config.js
rollup.config.jsimport * as path from 'path'
import typescript from 'rollup-plugin-typescript2'
import resolve from 'rollup-plugin-node-resolve'
import replace from 'rollup-plugin-replace'
import commonjs from 'rollup-plugin-commonjs'
import * as fsExtra from 'fs-extra'
const pkgRoot = path.join(__dirname, 'packages')
const tsPlugin = typescript({
tsconfig: path.join(__dirname, 'tsconfig.json'),
useTsconfigDeclarationDir: true,
tsconfigOverride: {
compilerOptions: {
declaration: true,
declarationDir: path.join(__dirname, 'dist')
}
}
})
const tsPlugin2 = typescript({
tsconfig: path.join(__dirname, 'tsconfig.json')
})
function moveDeclarations({declarationDir, packagesDir}) {
return {
name: 'move-ts-declarations',
onwrite() {
return fsExtra.readdir(declarationDir)
.then(dirs => Promise.all(dirs.map(dir =>
fsExtra.ensureDir(path.join(packagesDir, dir, 'dist'))
.then(() =>
fsExtra.move(
path.join(declarationDir, dir, 'src'),
path.join(packagesDir, dir, 'dist', 'typings'),
{overwrite: true}
)
)
)))
.then(() => fsExtra.remove(declarationDir))
}
}
}
export default [
{
input: path.join(pkgRoot, 'lib1', 'src', 'index.ts'),
output: {
format: 'es',
file: path.join(pkgRoot, 'lib1', 'dist', 'index.mjs')
},
plugins: [
resolve(),
commonjs(),
tsPlugin,
moveDeclarations({
declarationDir: path.join(__dirname, 'dist'),
packagesDir: path.join(__dirname, 'packages')
})
]
},
{
input: path.join(pkgRoot, 'lib2', 'src', 'index.ts'),
output: {
format: 'es',
file: path.join(pkgRoot, 'lib2', 'dist', 'index.mjs')
},
plugins: [
resolve(),
commonjs(),
tsPlugin2
]
}
] PS: I found another workaround. @Alxandr was right about rootDir and include. Problem in paths. configs
rollup.config.js part typescript({
tsconfig: path.join(__dirname, 'tsconfig.base.json'),
useTsconfigDeclarationDir: true,
tsconfigOverride: {
compilerOptions: {
declaration: true,
rootDir: path.join(pkgRoot, 'lib2', 'src'),
declarationDir: path.join(pkgRoot, 'lib2', 'dist', 'typings')
},
include: [path.join(pkgRoot, 'lib2', 'src')]
}
}) tsconfig.base.json{
"compilerOptions": {
"baseUrl": "packages",
"paths": {
"zerollup-demo-lib1/*": ["lib1/src/*"],
"zerollup-demo-lib2/*": ["lib2/src/*"],
"zerollup-demo-site1/*": ["site1/src/*"]
},
"newLine": "LF",
"allowSyntheticDefaultImports": false,
"module": "esnext",
"target": "es5",
"moduleResolution": "node",
"sourceMap": true,
"lib": [
"dom",
"esnext"
],
"jsx": "react",
"noImplicitAny": false,
"noUnusedLocals": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"removeComments": false,
"experimentalDecorators": true
},
"exclude": ["dist", "node_modules"],
"include": ["packages/*/src"]
} tsconfig.json{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"paths": {
"zerollup-demo-lib1/*": ["lib1/src/*"],
"zerollup-demo-lib2/*": ["lib2/src/*"],
"zerollup-demo-site1/*": ["site1/src/*"],
"zerollup-demo-*": ["*/src"]
}
}
} @ezolenko You use deep merge for "paths" in tsconfigOverride. With deep merge i can't remove some paths keys or replace whole paths from inherited config. tsc uses shallow merge for it. |
Publishing source files instead of type declarations is almost always a bad idea. You will have typing issues when users will try to use your library, especially if they have older version of the TypeScript or if they tsconfig configured differently. |
Just to share our experience. We also have a monorepo setup using Rush (better Lerna alternative) and we did have issues with type declaration generation paths. The thing is that we use our own built tool, which encapsulates Rollup and all configuration (I highly recommend this approach). We've managed to achieve the desired result using this configuration: const entryFilePath = `${projectPath}/index.ts`;
const typeScriptPluginOptions: any = {
tsconfig: `${builderPath}/config/tsconfig.json`, // using one base tsconfig for all packages
tsconfigOverride: {
compilerOptions: <CompilerOptions> {
rootDir: projectPath,
typeRoots: [
`${projectPath}/node_modules/@types`,
`${projectPath}/types`,
],
},
},
clean: isProduction,
verbosity: (isDebug ? 3 : 1),
cacheRoot: `${projectPath}/node_modules/.cache/rollup-plugin-typescript2`,
typescript: TypeScript,
};
// THIS IS THE IMPORTANT PART:
// Setting the paths manually to override default paths set by the plugin
Object.assign(typeScriptPluginOptions.tsconfigOverride, {
files: [entryFilePath],
include: [
`${projectPath}/*.ts`,
`${projectPath}/src/**/*.ts`,
`${projectPath}/src/**/*.tsx`,
],
exclude: [],
});
if (declarations) {
Object.assign(typeScriptPluginOptions.tsconfigOverride.compilerOptions, <CompilerOptions> {
declaration: true,
declarationDir: outputPath,
});
// Preventing plugin from overwriting the "declarationDir" option
typeScriptPluginOptions.useTsconfigDeclarationDir = true;
} |
ezolenko/rollup-plugin-typescript2#72 add separate tsconfig in package dir
tsconfig
) results in declarations for *all* projects output for each project
not a bug, this is
|
What happens and why it is wrong
I'm building 2 projects with one rollup.config file, and the result is this:
As can be seen, I get the
.d.ts
files for both projects in bothdist
folders.Environment
OSX.
Versions
rollup.config.js
It's auto-generated, so I can't really paste it.
tsconfig.json
plugin output with verbosity 3
log
The text was updated successfully, but these errors were encountered: