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

Declaration is missing imported type when using pnpm? #330

Closed
ubbcou opened this issue May 17, 2022 · 11 comments · Fixed by #332
Closed

Declaration is missing imported type when using pnpm? #330

ubbcou opened this issue May 17, 2022 · 11 comments · Fixed by #332
Labels
kind: bug Something isn't working properly solution: duplicate This issue or pull request already exists topic: monorepo / symlinks Related to monorepos and/or symlinks (Lerna, Yarn, PNPM, Rush, etc) topic: TS Compiler API Docs Related to the severely lacking TS Compiler API Docs

Comments

@ubbcou
Copy link

ubbcou commented May 17, 2022

What happens and why it is wrong

When i want to using api-extractor to genderation my d.ts file, i found an error : InternalError: Internal Error: Unable to follow symbol for "Ref"

In the source code, I imported type. And then it lost in my rollup output code.

source code

// origin
import { ref, Ref } from 'vue'

export function useTmp() {
  const bl = ref(false) as Ref<boolean>
  return {
    bl
  }
}
// output
export declare function useTmp(): {
    bl: Ref<boolean>;
};

I think there should be something like this in the output code: import { Ref } from 'vue', but it didn't.

What should I do about it? Thanks.

Environment

Versions

    rollup: ^2.73.0 => 2.73.0 
    rollup-plugin-typescript2: ^0.31.2 => 0.31.2 
    typescript: ^4.6.4 => 4.6.4 

rollup.config.js

:
const typescript = require('rollup-plugin-typescript2')
const path = require('path')

export default {
  input: 'src/index.ts',
  external: ['vue'],
  output: {
    file: 'dist/index.js',
    format: 'esm',
    globals: {
      vue: 'Vue'
    }
  },
  plugins: [
    typescript({
      clean: true,
      verbosity: 3,
      check: false, // FIXED: https://github.com/ezolenko/rollup-plugin-typescript2/issues/234
      tsconfig: path.resolve(__dirname, 'tsconfig.json'),
      tsconfigOverride: {
        compilerOptions: {
          declaration: true,
          rootDir: path.resolve(__dirname),
        },
      },
    }),
  ]
}

tsconfig.json

:
{
  "compilerOptions": {
    "baseUrl": ".",
    "outDir": "dist",
    "sourceMap": false,
    "target": "es2016",
    "useDefineForClassFields": false,
    "module": "esnext",
    "moduleResolution": "node",
    "allowJs": true,
    "strict": true,
    "noUnusedLocals": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "removeComments": false,
    "jsx": "preserve",
    "lib": ["esnext", "dom"],
    "rootDir": "."
  },
  "include": [
    "src"
  ]
}

package.json

:
{
  "name": "tmp-rollup-api-extrator",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "rollup -c",
    "build:dts": "node ./scripts/dts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@microsoft/api-extractor": "^7.24.0",
    "@types/node": "^17.0.33",
    "rollup": "^2.73.0",
    "rollup-plugin-typescript2": "^0.31.2",
    "typescript": "^4.6.4",
    "vue": "^3.2.33"
  }
}

plugin output with verbosity 3

:
> rollup -c

rpt2: built-in options overrides: {
    "noEmitHelpers": false,
    "importHelpers": true,
    "noResolve": false,
    "noEmit": false,
    "inlineSourceMap": false,
    "outDir": "C:\\Users\\ash\\Desktop\\tmp-rollup-api-extrator\\node_modules\\.cache\\rollup-plugin-typescript2/placeholder",
    "moduleResolution": 2,
    "allowNonTsExtensions": true
}
rpt2: parsed tsconfig: {
    "options": {
        "baseUrl": "C:/Users/ash/Desktop/tmp-rollup-api-extrator",
        "outDir": "C:\\Users\\ash\\Desktop\\tmp-rollup-api-extrator\\node_modules\\.cache\\rollup-plugin-typescript2/placeholder",
        "sourceMap": false,
        "target": 3,
        "useDefineForClassFields": false,
        "module": 99,
        "moduleResolution": 2,
        "allowJs": true,
        "strict": true,
        "noUnusedLocals": true,
        "experimentalDecorators": true,
        "resolveJsonModule": true,
        "esModuleInterop": true,
        "removeComments": false,
        "jsx": 1,
        "lib": [
            "lib.esnext.d.ts",
            "lib.dom.d.ts"
        ],
        "rootDir": "C:/Users/ash/Desktop/tmp-rollup-api-extrator",
        "declaration": true,
        "configFilePath": "C:/Users/ash/Desktop/tmp-rollup-api-extrator/tsconfig.json",
        "noEmitHelpers": false,
        "importHelpers": true,
        "noResolve": false,
        "noEmit": false,
        "inlineSourceMap": false,
        "allowNonTsExtensions": true
    },
    "fileNames": [
        "C:/Users/ash/Desktop/tmp-rollup-api-extrator/src/index.ts"
    ],
    "typeAcquisition": {
        "enable": false,
        "include": [],
        "exclude": []
    },
    "raw": {
        "compilerOptions": {
            "baseUrl": ".",
            "outDir": "dist",
            "sourceMap": false,
            "target": "es2016",
            "useDefineForClassFields": false,
            "module": "esnext",
            "moduleResolution": "node",
            "allowJs": true,
            "strict": true,
            "noUnusedLocals": true,
            "experimentalDecorators": true,
            "resolveJsonModule": true,
            "esModuleInterop": true,
            "removeComments": false,
            "jsx": "preserve",
            "lib": [
                "esnext",
                "dom"
            ],
            "rootDir": "C:\\Users\\ash\\Desktop\\tmp-rollup-api-extrator",
            "declaration": true
        },
        "include": [
            "src"
        ],
        "compileOnSave": false
    },
    "errors": [],
    "wildcardDirectories": {
        "c:/users/ash/desktop/tmp-rollup-api-extrator/src": 1
    },
    "compileOnSave": false
}
rpt2: typescript version: 4.6.4
rpt2: tslib version: 2.4.0
rpt2: rollup version: 2.73.0
rpt2: rollup-plugin-typescript2 version: 0.31.2
rpt2: plugin options:
{
    "clean": true,
    "verbosity": 3,
    "check": false,
    "tsconfig": "C:\\Users\\ash\\Desktop\\tmp-rollup-api-extrator\\tsconfig.json",
    "tsconfigOverride": {
        "compilerOptions": {
            "declaration": true,
            "rootDir": "C:\\Users\\ash\\Desktop\\tmp-rollup-api-extrator"
        }
    },
    "cacheRoot": "C:\\Users\\ash\\Desktop\\tmp-rollup-api-extrator\\node_modules\\.cache\\rollup-plugin-typescript2",
    "include": [
        "*.ts+(|x)",
        "**/*.ts+(|x)"
    ],
    "exclude": [
        "*.d.ts",
        "**/*.d.ts"
    ],
    "abortOnError": true,
    "rollupCommonJSResolveHack": false,
    "useTsconfigDeclarationDir": false,
    "transformers": [],
    "tsconfigDefaults": {},
    "objectHashIgnoreUnknownHack": false,
    "cwd": "C:\\Users\\ash\\Desktop\\tmp-rollup-api-extrator",
    "typescript": "version 4.6.4"
}
rpt2: rollup config:
{
    "external": [
        "vue"
    ],
    "input": "src/index.ts",
    "plugins": [
        {
            "name": "rpt2"
        },
        {
            "name": "stdin"
        }
    ],
    "output": [
        {
            "file": "dist/index.js",
            "format": "esm",
            "globals": {
                "vue": "Vue"
            },
            "plugins": []
        }
    ]
}
rpt2: tsconfig path: C:/Users/ash/Desktop/tmp-rollup-api-extrator/tsconfig.json
rpt2: included:
[
    "*.ts+(|x)",
    "**/*.ts+(|x)"
]
rpt2: excluded:
[
    "*.d.ts",
    "**/*.d.ts"
]
rpt2: not cleaning C:\Users\ash\Desktop\tmp-rollup-api-extrator\node_modules\.cache\rollup-plugin-typescript2/placeholder
rpt2: �[34mtranspiling�[39m 'C:\Users\ash\Desktop\tmp-rollup-api-extrator\src\index.ts'
rpt2: �[34mgenerated declarations�[39m for 'C:/Users/ash/Desktop/tmp-rollup-api-extrator/src/index.ts'
rpt2: generating target 1
rpt2: �[34mrolling caches�[39m
rpt2: �[34memitting declarations�[39m for 'C:/Users/ash/Desktop/tmp-rollup-api-extrator/src/index.ts' to 'src/index.d.ts'

@agilgur5 agilgur5 changed the title Why did the output miss the imported type? Declaration is missing imported type? May 17, 2022
@agilgur5
Copy link
Collaborator

agilgur5 commented May 17, 2022

Thanks for providing a minimal repro!

That is a strange output error... DTS generation is done entirely by the TS LanguageService too...

Does this code type-check with tsc?
(Since check: false is set, it's possible there's a type-error that's ignored)

A workaround I might suggest is to use import type for the type specifically, which may get it to work.
(Rollup doesn't see type-only imports as they don't emit any JS, so it's possible a tree-shake occurred before the DTS generation?)

@ubbcou
Copy link
Author

ubbcou commented May 17, 2022

image

check: true and use import type. The result is the same, but the error is checked in advance

@agilgur5 agilgur5 added the kind: bug Something isn't working properly label May 17, 2022
@agilgur5
Copy link
Collaborator

agilgur5 commented May 17, 2022

Is there a type-error or does it type-check fine?

I'm also curious if tsc emits the same broken DTS file, or if tsc's output is correct

@ubbcou
Copy link
Author

ubbcou commented May 17, 2022

Oh, I'm correcting my story. Exporting semantic error TS2305: Module '"vue"' has no exported member 'ref' when check: true and when i pnpm run build.

tsc's output is wrong. And I'm just using tsc without any arguments. I don't know if that's the right way to use it

@agilgur5
Copy link
Collaborator

Also seems a bit reminiscent of #274 (which has a workaround: #274 (comment)), as well as jaredpalmer/tsdx#967 (which also uses pnpm) and jaredpalmer/tsdx#796

@agilgur5 agilgur5 added the topic: monorepo / symlinks Related to monorepos and/or symlinks (Lerna, Yarn, PNPM, Rush, etc) label May 17, 2022
@ubbcou
Copy link
Author

ubbcou commented May 17, 2022

First: declare twice include is doesn't work

    typescript({
      useTsconfigDeclarationDir: true,
      clean: true,
      // verbosity: 3,
      check: true, // FIXED: https://github.com/ezolenko/rollup-plugin-typescript2/issues/234
      tsconfig: path.resolve(__dirname, 'tsconfig.json'),
      tsconfigOverride: {
        compilerOptions: {
          declaration: true,
          rootDir: path.resolve(__dirname),
        },
        include: [path.resolve(__dirname, 'src')],
      },
      include: [path.resolve(__dirname, 'src')],
    }),

image

And I don't understand the other issues clearly.. :(

@agilgur5
Copy link
Collaborator

agilgur5 commented May 26, 2022

And I'm just using tsc without any arguments. I don't know if that's the right way to use it

Should be fine without arguments given your tsconfig.json.

tsc's output is wrong

If you mean that tsc outputs the same broken DTS files with the same missing import, then there's a good chance that this is an issue upstream in TS itself.

That being said, looking at your type-errors, this might be "correct" behavior as the import can't be resolved and so TS's behavior is kind of undefined in that case -- the type-error needs to be fixed for it work properly.

Exporting semantic error TS2305: Module '"vue"' has no exported member 'ref' when check: true and when i pnpm run build.

Given this error, it sounds like either Vue or its typings couldn't be found / resolved. Which would explain why tsc has the same type-error and probably why tsc gives the same output.

Normally, the module and its typings are found in node_modules, but with pnpm (or Yarn PnP etc) it's a little bit different... so I suspect that might be the cause here.

First: declare twice include is doesn't work

Thanks for checking this!

And I don't understand the other issues clearly.. :(

No worries -- they're more a note to me and other maintainers of similar issues encountered, which could be useful for figuring out the root cause. In this case, the use of pnpm seems to be a common pattern in some of these issues.

Let me investigate this a bit more. I'd like to see how NPM vs. PNPM usage may differ, some moduleResolution tests (since Vue 3 uses Node's ESM support), and do some tracing. Your repo is a great minimal reproduction of the case, which is very helpful for diagnosing root cause!
It's very possible this is an upstream TS issue with regard to resolution and pnpm; can attempt a fix upstream if I figure out what's going on here as I've read through TS's module resolution code before (though the nodenext changes have made it a lot more complicated)

@agilgur5
Copy link
Collaborator

Ok, I did a quick look and was able to get tsc working fine with pnpm. See my fork and commit of your repo here.
I explained in the commit message the various tsconfig.json settings I changed to get that to work as expected and why rpt2 is still failing.

So now can confirm that this is not an upstream TS issue, and has to do with how pnpm's node_modules are being resolved with Rollup or rpt2.
Notably, as I wrote in the commit message, if you use npm instead, rpt2 will work correctly. I.e. rm -rf node_modules/ && npm install && npm run build will output correctly.
So pnpm resolution is the central issue here, meaning this is a duplicate of #234 basically.

I'll see if I can figure anything out in this minimal repro and will respond here if I can, but going to close this as a duplicate as such.

@agilgur5 agilgur5 changed the title Declaration is missing imported type? Declaration is missing imported type when using pnpm? May 26, 2022
@agilgur5 agilgur5 added the solution: duplicate This issue or pull request already exists label May 26, 2022
@agilgur5
Copy link
Collaborator

agilgur5 commented May 27, 2022

Worked through your reproduction (and the source code of the TS compiler) and managed to find a fix for this long-standing issue with pnpm monorepos!

See #332 . I actually tested it locally against your repro and confirmed that there was no type-error anymore (so check: false workaround is no longer necessary) and that the declaration file had correct output with import { Ref } from 'vue'.

Thanks for the very minimal repro again -- really shows the value of MCVEs! 🙂

Once that's merged and released, this should be fixed. I'll update here when it's released.

@agilgur5
Copy link
Collaborator

agilgur5 commented Jun 2, 2022

Released in 0.32.0 🎉

@ubbcou
Copy link
Author

ubbcou commented Jun 2, 2022

Thank you very much!!! 😊

@agilgur5 agilgur5 added the topic: TS Compiler API Docs Related to the severely lacking TS Compiler API Docs label Jun 28, 2022
belaczek added a commit to belaczek/nx that referenced this issue Dec 26, 2022
…n rollup bundle

This commit fixes typechecking in rollup bundle while using pnpm.
More info about the issue
ezolenko/rollup-plugin-typescript2#330
belaczek added a commit to belaczek/nx that referenced this issue Dec 26, 2022
…n rollup bundle

This commit fixes typechecking in rollup bundle while using pnpm.
More info about the issue
ezolenko/rollup-plugin-typescript2#330
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 solution: duplicate This issue or pull request already exists topic: monorepo / symlinks Related to monorepos and/or symlinks (Lerna, Yarn, PNPM, Rush, etc) topic: TS Compiler API Docs Related to the severely lacking TS Compiler API Docs
Projects
None yet
2 participants