rollup-plugin-typescript2 icon indicating copy to clipboard operation
rollup-plugin-typescript2 copied to clipboard

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

Open slavafomin opened this issue 4 years ago • 8 comments

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).

slavafomin avatar Mar 03 '20 14:03 slavafomin

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'.

ezolenko avatar Mar 04 '20 00:03 ezolenko

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 avatar Mar 04 '20 11:03 slavafomin

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

slavafomin avatar Mar 04 '20 11:03 slavafomin

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...

ezolenko avatar Mar 05 '20 19:03 ezolenko

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.

wegry avatar Mar 24 '20 21:03 wegry

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

slavafomin avatar Mar 25 '20 00:03 slavafomin

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 !

sumitramanga avatar Jan 19 '22 03:01 sumitramanga

I wrote up a root cause analysis and solution proposal for this in https://github.com/ezolenko/rollup-plugin-typescript2/issues/298#issuecomment-1146658442. 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 https://github.com/ezolenko/rollup-plugin-typescript2/issues/280#issuecomment-916419366

agilgur5 avatar Jun 05 '22 01:06 agilgur5

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 👍

agilgur5 avatar Sep 12 '22 22:09 agilgur5