Skip to content
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

Declarations not generated for type-only files not explicitly specified in tsconfig #211

Closed
slavafomin opened this issue Mar 3, 2020 · 9 comments · Fixed by #406
Closed
Assignees
Labels
kind: bug Something isn't working properly topic: type-only / emit-less imports Related to importing type-only files that will not be emitted

Comments

@slavafomin
Copy link

slavafomin commented Mar 3, 2020

Hello, again!

I've noticed the following behavior: TypeScript declarations are not generated for source modules from which only types are imported and which are not explicitly added to the project using files or include options in tsconfig.json.

Project configuration

// tsconfig.json
{
  "compilerOptions": {
    "outDir": "dist/",
    "declarationDir": "dist/types/",
    "declaration": true
  },
  
  // specifying only entry-point
  "files": ["src/index.ts"]
}
// rollup.config.js

import typeScriptPlugin2 from 'rollup-plugin-typescript2';

export default {
  input: 'src/index.ts',
  output: {
    file: 'dist/index.js',
    format: 'esm',
  },
  plugins: [
    typeScriptPlugin2({
      verbosity: 2,
      clean: true,
      useTsconfigDeclarationDir: true,
    }),
  ],
};

Source files

// src/index.ts

// importing only type symbol from './foo.ts'
import { Foo } from './foo';

export class Main {
  constructor(foo: Foo) {
    console.log(foo);
  }
}
// src/foo.ts

// type symbol
export type Foo = 'foo';

// constant symbol (not imported)
export const defaultFoo: Foo = 'foo';
// src/unused.ts

export type Unused = 'unused';

Generated files

// dist/index.js

var Main = /** @class */ (function () {
    function Main(foo) {
        console.log(foo);
    }
    return Main;
}());

export { Main };
// dist/types/index.d.ts

// Error: TS2307: Cannot find module './foo'.
import { Foo } from './foo';

export declare class Main {
    constructor(foo: Foo);
}
  • the dist/types/unused.d.ts is not generated, which is GOOD.
  • however, the dist/types/foo.d.ts is not generated, which is BAD.

And if I would set "include": ["src/"], the dist/types/unused.d.ts would be generated, however, it shouldn't, because it's not imported anywhere.


Our goal here is to specify only the entry point of our project and let the compiler to handle only source files that are actually used in the project and avoid processing, generating declarations and reporting errors for files that are not used (redundant).

@ezolenko
Copy link
Owner

ezolenko commented Mar 4, 2020

That's supposed to work after #175, mostly anyway.

Could you run it with verbosity 4 and see if it correctly finds files to import and correctly ignores files from tsconfig that are not imported by anything.

You should see what imports what when and things like skipping declarations for unused 'file' or generating missed declarations for 'file' or emitting declarations for 'file'.

@slavafomin
Copy link
Author

Sure, here's the output:

$ rm -rf ./dist; npx rollup -c ./rollup.config.js

loaded rollup.config.js with warnings
(!) Unused external imports
default imported from external module 'rollup-plugin-typescript' but never used

src/index.ts → dist/index.js...
rpt2: built-in options overrides: {
    "noEmitHelpers": false,
    "importHelpers": true,
    "noResolve": false,
    "noEmit": false,
    "inlineSourceMap": false,
    "outDir": "…/ts-gen-types/node_modules/.cache/rollup-plugin-typescript2/placeholder",
    "moduleResolution": 2,
    "allowNonTsExtensions": true,
    "module": 5
}
rpt2: parsed tsconfig: {
    "options": {
        "outDir": "…/ts-gen-types/node_modules/.cache/rollup-plugin-typescript2/placeholder",
        "declarationDir": "…/ts-gen-types/dist/types",
        "declaration": true,
        "configFilePath": "…/ts-gen-types/tsconfig.json",
        "noEmitHelpers": false,
        "importHelpers": true,
        "noResolve": false,
        "noEmit": false,
        "inlineSourceMap": false,
        "moduleResolution": 2,
        "allowNonTsExtensions": true,
        "module": 5
    },
    "fileNames": [
        "…/ts-gen-types/src/index.ts"
    ],
    "typeAcquisition": {
        "enable": false,
        "include": [],
        "exclude": []
    },
    "raw": {
        "compilerOptions": {
            "outDir": "dist/",
            "declarationDir": "dist/types/",
            "declaration": true
        },
        "files": [
            "src/index.ts"
        ],
        "compileOnSave": false
    },
    "errors": [],
    "wildcardDirectories": {},
    "compileOnSave": false,
    "configFileSpecs": {
        "filesSpecs": [
            "src/index.ts"
        ],
        "excludeSpecs": [
            "dist/",
            "dist/types/"
        ],
        "validatedExcludeSpecs": [
            "dist/",
            "dist/types/"
        ],
        "wildcardDirectories": {}
    }
}
rpt2: typescript version: 3.8.3
rpt2: tslib version: 1.10.0
rpt2: rollup version: 1.32.0
rpt2: rollup-plugin-typescript2 version: 0.26.0
rpt2: plugin options:
{
    "verbosity": 4,
    "clean": true,
    "useTsconfigDeclarationDir": true,
    "check": true,
    "cacheRoot": "…/ts-gen-types/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": "…/ts-gen-types",
    "typescript": "version 3.8.3"
}
rpt2: rollup config:
{
    "chunkGroupingSize": 5000,
    "experimentalCacheExpiry": 10,
    "external": [],
    "inlineDynamicImports": false,
    "input": "src/index.ts",
    "perf": false,
    "plugins": [
        {
            "name": "rpt2"
        },
        {
            "name": "stdin"
        }
    ],
    "strictDeprecations": false
}
rpt2: tsconfig path: …/ts-gen-types/tsconfig.json
rpt2: included:
[
    "*.ts+(|x)",
    "**/*.ts+(|x)"
]
rpt2: excluded:
[
    "*.d.ts",
    "**/*.d.ts"
]
rpt2: transpiling '…/ts-gen-types/src/index.ts'
rpt2: generated declarations for '…/ts-gen-types/src/index.ts'
rpt2: generating target 1
rpt2: rolling caches
rpt2: emitting declarations for '…/ts-gen-types/src/index.ts' to '…/ts-gen-types/dist/types/index.d.ts'
created dist/index.js in 945ms

@slavafomin
Copy link
Author

I've also pushed my test case project here:
https://github.com/slavafomin/rollup-plugin-typescript2--issue-211

@ezolenko ezolenko added the kind: bug Something isn't working properly label Mar 5, 2020
@ezolenko
Copy link
Owner

ezolenko commented Mar 5, 2020

Yep, I see it...

The file shows up in allImportedFiles, but it is ignored by both rollup (because type-only) and tsconfig. tsc run still generates d.ts for it.

We need to somehow include such files in _onwrite, but exclude all the node_modules stuff. Might have to parse d.ts after all...

@wegry
Copy link

wegry commented Mar 24, 2020

To get around this for now, I've been running yarn tsc --emitDeclarationOnly && yarn rollup -c to get the declaration files without a runtime component and then use this plugin's output for everything else.

@slavafomin
Copy link
Author

@wegry I've also been thinking about letting declarations to be generated in a separate process.

@sumitramanga
Copy link

The above comment worked for me too! I've been having troubles running this command - rollup -c && npx dts-bundle-generator -o dist/index.d.ts dist/types/index.d.ts. It created the types under each file within my lib folder (located outside of the dist folder). Instead of in the typings folder. But running the declaration files separately done the trick. Thank you @wegry !

@agilgur5 agilgur5 added the topic: type-only / emit-less imports Related to importing type-only files that will not be emitted label Jun 4, 2022
@agilgur5 agilgur5 changed the title Type declarations are generated incorrectly when source files are not explicitly specified Type declarations are not generated for type-only files when they are not explicitly specified in tsconfig Jun 5, 2022
@agilgur5
Copy link
Collaborator

agilgur5 commented Jun 5, 2022

I wrote up a root cause analysis and solution proposal for this in #298 (comment).
Will need to a good bit of testing for the solution, but think I have a working approach outlined at least!

We need to somehow include such files in _onwrite, but exclude all the node_modules stuff. Might have to parse *.d.ts after all...

Per the proposed solution, I don't think we need to parse declaration files, but we do need to parse the import chain in rpt2 itself (as we can't rely on Rollup to find imports of type-only files), as mentioned in #280 (comment)

@agilgur5 agilgur5 self-assigned this Jun 5, 2022
@agilgur5 agilgur5 changed the title Type declarations are not generated for type-only files when they are not explicitly specified in tsconfig Type declarations are not generated for type-only files when not explicitly specified in tsconfig Jun 5, 2022
@agilgur5 agilgur5 changed the title Type declarations are not generated for type-only files when not explicitly specified in tsconfig Declarations not generated for type-only files when not explicitly specified in tsconfig Jun 5, 2022
@agilgur5 agilgur5 changed the title Declarations not generated for type-only files when not explicitly specified in tsconfig Declarations not generated for type-only files not explicitly specified in tsconfig Jun 21, 2022
@agilgur5
Copy link
Collaborator

agilgur5 commented Sep 12, 2022

This has been fixed by #406 and released in 0.34.0 🎉

I've also pushed my test case project here:
https://github.com/slavafomin/rollup-plugin-typescript2--issue-211

I also confirmed that, with the files: ["src/index.ts"] configuration and rpt2 0.34.0, foo.d.ts gets generated and unused.d.ts is not created 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug Something isn't working properly topic: type-only / emit-less imports Related to importing type-only files that will not be emitted
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants