question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Generated types placed in unexpected directory -- need to set `rootDir` in tsconfig

See original GitHub issue

What happens and why it is wrong

I’m building a package using React, Typescript, Rollup, rollup-plugin-typescript2. While the generated JS files are fine, the generated definition files are in the wrong directory.

Current result:

MyLib
|_\lib
| |_index.js
| |_index.esm.js
| |_\src
|   |_index.d.ts
|   |_\components
|     |_Button.d.ts
|
|_\src
  |_index.ts
  |_\components
    |_Button.tsx

Expected result:

MyLib
|_\lib
| |_index.js
| |_index.esm.js
| |_index.d.ts
| |_\components
|   |_Button.d.ts
|
|_\src
  |_index.ts
  |_\components
    |_Button.tsx

Environment

Mac, Node v15.14.0

Versions
  npmPackages:
    rollup: ^2.52.7 => 2.52.7
    rollup-plugin-typescript2: ^0.30.0 => 0.30.0
    typescript: ^4.3.5 => 4.3.5

rollup.config.js

`rollup.config.js`:
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from 'rollup-plugin-typescript2';

const packageJson = require('./package.json');

export default {
  input: 'src/index.ts',
  output: [
    {
      file: packageJson.main,
      format: 'cjs',
      sourcemap: true
    },
    {
      file: packageJson.module,
      format: 'esm',
      sourcemap: true
    }
  ],
  plugins: [
    peerDepsExternal(),
    resolve(),
    commonjs(),
    typescript({ useTsconfigDeclarationDir: true })
  ]
};

tsconfig.json

`tsconfig.json`:
{
  "compilerOptions": {
    "target": "es5",
    "outDir": "lib",
    "lib": ["dom", "dom.iterable", "esnext"],
    "declaration": true,
    "declarationDir": "lib",
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": ["src"],
  "exclude": ["node_modules", "lib"]
}

package.json

`package.json`:
{
  "name": "@react/bricks",
  "version": "0.0.1",
  "description": "",
  "main": "lib/index.js",
  "module": "lib/index.esm.js",
  "types": "lib/index.d.ts",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "storybook": "start-storybook -s ./public -p 6006",
    "build-storybook": "build-storybook",
    "build": "rollup -c",
    "prepublishOnly": "npm run build"
  },
  "np": {
    "publish": false,
    "tests": false
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.14.6",
    "@rollup/plugin-commonjs": "^19.0.0",
    "@rollup/plugin-node-resolve": "^13.0.0",
    "@storybook/addon-actions": "^6.3.2",
    "@storybook/addon-essentials": "^6.3.2",
    "@storybook/addon-links": "^6.3.2",
    "@storybook/react": "^6.3.2",
    "@types/react": "^17.0.13",
    "@types/styled-components": "^5.1.11",
    "babel-loader": "^8.2.2",
    "rollup": "^2.52.7",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-typescript2": "^0.30.0",
    "typescript": "^4.3.5"
  },
  "peerDependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "styled-components": "^5.3.0"
  }
}

plugin output with verbosity 3

plugin output with verbosity 3:
rpt2: built-in options overrides: {
    "noEmitHelpers": false,
    "importHelpers": true,
    "noResolve": false,
    "noEmit": false,
    "inlineSourceMap": false,
    "outDir": "/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/placeholder",
    "moduleResolution": 2,
    "allowNonTsExtensions": true
}
rpt2: parsed tsconfig: {
    "options": {
        "target": 1,
        "outDir": "/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/placeholder",
        "lib": [
            "lib.dom.d.ts",
            "lib.dom.iterable.d.ts",
            "lib.esnext.d.ts"
        ],
        "declaration": true,
        "declarationDir": "/Users/asafdavid/dev/bricks/lib",
        "allowJs": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "module": 99,
        "moduleResolution": 2,
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": false,
        "jsx": 2,
        "configFilePath": "/Users/asafdavid/dev/bricks/tsconfig.json",
        "noEmitHelpers": false,
        "importHelpers": true,
        "noResolve": false,
        "inlineSourceMap": false,
        "allowNonTsExtensions": true
    },
    "fileNames": [
        "/Users/asafdavid/dev/bricks/src/index.ts",
        "/Users/asafdavid/dev/bricks/src/components/Button/Button.stories.tsx",
        "/Users/asafdavid/dev/bricks/src/components/Button/Button.tsx",
        "/Users/asafdavid/dev/bricks/src/components/Button/index.ts",
        "/Users/asafdavid/dev/bricks/src/components/WaveForm/WaveForm.stories.tsx",
        "/Users/asafdavid/dev/bricks/src/components/WaveForm/WaveForm.tsx",
        "/Users/asafdavid/dev/bricks/src/components/WaveForm/index.ts"
    ],
    "typeAcquisition": {
        "enable": false,
        "include": [],
        "exclude": []
    },
    "raw": {
        "compilerOptions": {
            "target": "es5",
            "outDir": "lib",
            "lib": [
                "dom",
                "dom.iterable",
                "esnext"
            ],
            "declaration": true,
            "declarationDir": "lib",
            "allowJs": true,
            "skipLibCheck": true,
            "esModuleInterop": true,
            "allowSyntheticDefaultImports": true,
            "strict": true,
            "forceConsistentCasingInFileNames": true,
            "module": "esnext",
            "moduleResolution": "node",
            "resolveJsonModule": true,
            "isolatedModules": true,
            "noEmit": true,
            "jsx": "react"
        },
        "include": [
            "src"
        ],
        "exclude": [
            "node_modules",
            "lib"
        ],
        "compileOnSave": false
    },
    "errors": [],
    "wildcardDirectories": {
        "/users/asafdavid/dev/bricks/src": 1
    },
    "compileOnSave": false
}
rpt2: typescript version: 4.3.5
rpt2: tslib version: 2.1.0
rpt2: rollup version: 2.52.7
rpt2: rollup-plugin-typescript2 version: 0.30.0
rpt2: plugin options:
{
    "useTsconfigDeclarationDir": true,
    "verbosity": 3,
    "check": true,
    "clean": false,
    "cacheRoot": "/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2",
    "include": [
        "*.ts+(|x)",
        "**/*.ts+(|x)"
    ],
    "exclude": [
        "*.d.ts",
        "**/*.d.ts"
    ],
    "abortOnError": true,
    "rollupCommonJSResolveHack": false,
    "tsconfigOverride": {},
    "transformers": [],
    "tsconfigDefaults": {},
    "objectHashIgnoreUnknownHack": false,
    "cwd": "/Users/asafdavid/dev/bricks",
    "typescript": "version 4.3.5"
}
rpt2: rollup config:
{
    "input": "src/index.ts",
    "plugins": [
        {
            "name": "peer-deps-external"
        },
        {
            "name": "node-resolve"
        },
        {
            "name": "commonjs"
        },
        {
            "name": "rpt2"
        },
        {
            "name": "stdin"
        }
    ],
    "output": [
        {
            "file": "lib/index.js",
            "format": "cjs",
            "plugins": [],
            "sourcemap": true
        },
        {
            "file": "lib/index.esm.js",
            "format": "esm",
            "plugins": [],
            "sourcemap": true
        }
    ]
}
rpt2: tsconfig path: /Users/asafdavid/dev/bricks/tsconfig.json
rpt2: included:
[
    "*.ts+(|x)",
    "**/*.ts+(|x)"
]
rpt2: excluded:
[
    "*.d.ts",
    "**/*.d.ts"
]
rpt2: Ambient types:
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/braces/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/color-convert/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/color-name/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/estree/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/glob/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/glob-base/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/graceful-fs/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/hast/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/hoist-non-react-statics/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/html-minifier-terser/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/is-function/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/istanbul-lib-coverage/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/istanbul-lib-report/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/istanbul-reports/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/json-schema/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/markdown-to-jsx/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/mdast/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/micromatch/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/minimatch/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/node/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/node-fetch/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/normalize-package-data/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/npmlog/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/overlayscrollbars/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/parse-json/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/parse5/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/pretty-hrtime/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/prop-types/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/qs/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/reach__router/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/react/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/react-syntax-highlighter/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/resolve/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/scheduler/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/source-list-map/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/styled-components/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/tapable/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/uglify-js/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/unist/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/webpack/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/webpack-env/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/webpack-sources/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/yargs/index.d.ts
rpt2:     /Users/asafdavid/dev/bricks/node_modules/@types/yargs-parser/index.d.ts
rpt2: transpiling '/Users/asafdavid/dev/bricks/src/index.ts'
rpt2:     cache: '/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/rpt2_58d2927530eb70256fcfce42cbbbdb4b07b518cb/code/cache/3b7b6b54ec7c86ef84d3f7f42c5f43121f477b42'
rpt2:     cache hit
rpt2:     cache: '/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/rpt2_58d2927530eb70256fcfce42cbbbdb4b07b518cb/syntacticDiagnostics/cache/3b7b6b54ec7c86ef84d3f7f42c5f43121f477b42'
rpt2:     cache hit
rpt2:     cache: '/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/rpt2_58d2927530eb70256fcfce42cbbbdb4b07b518cb/semanticDiagnostics/cache/3b7b6b54ec7c86ef84d3f7f42c5f43121f477b42'
rpt2:     cache hit
rpt2: generated declarations for '/Users/asafdavid/dev/bricks/src/index.ts'
rpt2: dependency '/Users/asafdavid/dev/bricks/src/components/Button/index.ts'
rpt2:     imported by '/Users/asafdavid/dev/bricks/src/index.ts'
rpt2: resolving './components/Button' imported by '/Users/asafdavid/dev/bricks/src/index.ts'
rpt2:     to '/Users/asafdavid/dev/bricks/src/components/Button/index.ts'
rpt2: transpiling '/Users/asafdavid/dev/bricks/src/components/Button/index.ts'
rpt2:     cache: '/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/rpt2_58d2927530eb70256fcfce42cbbbdb4b07b518cb/code/cache/cda840d6139a260eb6165f263421e86c307b9a87'
rpt2:     cache hit
rpt2:     cache: '/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/rpt2_58d2927530eb70256fcfce42cbbbdb4b07b518cb/syntacticDiagnostics/cache/cda840d6139a260eb6165f263421e86c307b9a87'
rpt2:     cache hit
rpt2:     cache: '/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/rpt2_58d2927530eb70256fcfce42cbbbdb4b07b518cb/semanticDiagnostics/cache/cda840d6139a260eb6165f263421e86c307b9a87'
rpt2:     cache hit
rpt2: generated declarations for '/Users/asafdavid/dev/bricks/src/components/Button/index.ts'
rpt2: dependency '/Users/asafdavid/dev/bricks/src/components/Button/Button.tsx'
rpt2:     imported by '/Users/asafdavid/dev/bricks/src/components/Button/index.ts'
rpt2: resolving './Button' imported by '/Users/asafdavid/dev/bricks/src/components/Button/index.ts'
rpt2:     to '/Users/asafdavid/dev/bricks/src/components/Button/Button.tsx'
rpt2: transpiling '/Users/asafdavid/dev/bricks/src/components/Button/Button.tsx'
rpt2:     cache: '/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/rpt2_58d2927530eb70256fcfce42cbbbdb4b07b518cb/code/cache/f0ae5f7eaf2bc41c426d76ac360260f27fd8b578'
rpt2:     cache hit
rpt2:     cache: '/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/rpt2_58d2927530eb70256fcfce42cbbbdb4b07b518cb/syntacticDiagnostics/cache/f0ae5f7eaf2bc41c426d76ac360260f27fd8b578'
rpt2:     cache hit
rpt2:     cache: '/Users/asafdavid/dev/bricks/node_modules/.cache/rollup-plugin-typescript2/rpt2_58d2927530eb70256fcfce42cbbbdb4b07b518cb/semanticDiagnostics/cache/f0ae5f7eaf2bc41c426d76ac360260f27fd8b578'
rpt2:     cache hit
rpt2: generated declarations for '/Users/asafdavid/dev/bricks/src/components/Button/Button.tsx'
rpt2: resolving '/Users/asafdavid/dev/bricks/node_modules/tslib/tslib.es6.js' imported by '/Users/asafdavid/dev/bricks/src/components/Button/Button.tsx'
rpt2:     to '/Users/asafdavid/dev/bricks/node_modules/tslib/tslib.es6.js'
rpt2: generating target 1
rpt2: rolling caches
rpt2: generating missed declarations for '/Users/asafdavid/dev/bricks/src/components/Button/Button.stories.tsx'
rpt2: generating missed declarations for '/Users/asafdavid/dev/bricks/src/components/WaveForm/WaveForm.stories.tsx'
rpt2: generating missed declarations for '/Users/asafdavid/dev/bricks/src/components/WaveForm/WaveForm.tsx'
rpt2: generating missed declarations for '/Users/asafdavid/dev/bricks/src/components/WaveForm/index.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/index.ts' to '/Users/asafdavid/dev/bricks/lib/src/index.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/Button/index.ts' to '/Users/asafdavid/dev/bricks/lib/src/components/Button/index.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/Button/Button.tsx' to '/Users/asafdavid/dev/bricks/lib/src/components/Button/Button.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/Button/Button.stories.tsx' to '/Users/asafdavid/dev/bricks/lib/src/components/Button/Button.stories.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/WaveForm/WaveForm.stories.tsx' to '/Users/asafdavid/dev/bricks/lib/src/components/WaveForm/WaveForm.stories.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/WaveForm/WaveForm.tsx' to '/Users/asafdavid/dev/bricks/lib/src/components/WaveForm/WaveForm.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/WaveForm/index.ts' to '/Users/asafdavid/dev/bricks/lib/src/components/WaveForm/index.d.ts'
rpt2: generating target 2
rpt2: rolling caches
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/index.ts' to '/Users/asafdavid/dev/bricks/lib/src/index.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/Button/index.ts' to '/Users/asafdavid/dev/bricks/lib/src/components/Button/index.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/Button/Button.tsx' to '/Users/asafdavid/dev/bricks/lib/src/components/Button/Button.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/Button/Button.stories.tsx' to '/Users/asafdavid/dev/bricks/lib/src/components/Button/Button.stories.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/WaveForm/WaveForm.stories.tsx' to '/Users/asafdavid/dev/bricks/lib/src/components/WaveForm/WaveForm.stories.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/WaveForm/WaveForm.tsx' to '/Users/asafdavid/dev/bricks/lib/src/components/WaveForm/WaveForm.d.ts'
rpt2: emitting declarations for '/Users/asafdavid/dev/bricks/src/components/WaveForm/index.ts' to '/Users/asafdavid/dev/bricks/lib/src/components/WaveForm/index.d.ts'

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:10 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
ezolenkocommented, Jul 20, 2021

Typescript adds src/ to the path because that’s on the relative path to your original files. So for <source root>/foo/bar/file.ts it creates <declaration root>/foo/bar/file.d.ts. You can try to either move tsconfig to src folder (and adjust everything else accordingly), or set baseUrl to ./src.

Another option is to set declaration dir to a different folder and, if you are creating npm package, set types in package config to that folder. Clients will find them through that.

2reactions
kbuenocommented, Mar 10, 2022

In case anyone else runs into this, essentially if you have more that one directory you are including in your tsconfig or more than one entry point in your rollup config as described above, typescript will follow the folder structure instead of putting the index.d.ts in the root of the destination folder (regardless of trying to use the useTsconfigDeclarationDir and declarationDir). For example, we had the input: 'src/index.ts', in rollup and "include": ["src/**/*", "scripts/token-parsers/**/*"], in tsconfig which caused a similar issue of the index.d.ts file being located in dist/src instead of dist as expected.

To fix it you can either:

  • Leave it as is and if you are using types in your package.json just point to the correct file like dist/src/index.d.ts
  • Move the index.ts file from src to the root of the project
  • Only use one directory in tsconfig includes option. For us that meant moving scripts/ into src/ folder
Read more comments on GitHub >

github_iconTop Results From Across the Web

TSConfig Option: rootDir - TypeScript
When TypeScript compiles files, it keeps the same directory structure in the output directory as exists in the input directory. For example, let's...
Read more >
typescript - Compiler adding unexpected artifacts to build folder
TypeScript outputs files according to the rootDir directory in tsconfig.json . If that isn't set, TypeScript by default figures it out by ...
Read more >
Configuring Jest
Jest will run .mjs and .js files with nearest package.json 's type field set to module as ECMAScript Modules.
Read more >
@rollup/plugin-typescript - npm
This can fix plugin errors when parsing files outside the current working directory (process.cwd()). tsconfig. Type: String | Boolean Default: ...
Read more >
Project References - TypeScript
composite · The rootDir setting, if not explicitly set, defaults to the directory containing the tsconfig file · All implementation files must be...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found