arethetypeswrong / arethetypeswrong.github.io

Tool for analyzing TypeScript types of npm packages

Home Page:https://arethetypeswrong.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

confusing resolution failure

ljharb opened this issue · comments

In https://github.com/ljharb/eslint-plugin-import/tree/types, cd into utils/, run npm install, and then run npx @arethetypeswrong/cli -P.

It gives resolution failed, but I'm not sure why.

If you use --format json, you’ll see additional details not shown in the CLI UI. Exposing these details is a top priority for future work.

Thanks! It prints unformatted (enhancement request!), but when i pipe it through jq it's still not clear:

{
  "analysis": {
    "packageName": "eslint-module-utils",
    "packageVersion": "2.8.0",
    "types": {
      "kind": "included"
    },
    "buildTools": {
      "typescript": "next"
    },
    "entrypoints": {
      ".": {
        "subpath": ".",
        "resolutions": {
          "node10": {
            "name": ".",
            "resolutionKind": "node10",
            "visibleProblems": [
              0
            ]
          },
          "node16-cjs": {
            "name": ".",
            "resolutionKind": "node16-cjs",
            "visibleProblems": [
              1
            ]
          },
          "node16-esm": {
            "name": ".",
            "resolutionKind": "node16-esm",
            "visibleProblems": [
              2
            ]
          },
          "bundler": {
            "name": ".",
            "resolutionKind": "bundler",
            "visibleProblems": [
              3
            ]
          }
        },
        "hasTypes": false,
        "isWildcard": false
      }
    },
    "programInfo": {
      "node10": {},
      "node16": {
        "moduleKinds": {}
      },
      "bundler": {}
    },
    "problems": [
      {
        "kind": "NoResolution",
        "entrypoint": ".",
        "resolutionKind": "node10"
      },
      {
        "kind": "NoResolution",
        "entrypoint": ".",
        "resolutionKind": "node16-cjs"
      },
      {
        "kind": "NoResolution",
        "entrypoint": ".",
        "resolutionKind": "node16-esm"
      },
      {
        "kind": "NoResolution",
        "entrypoint": ".",
        "resolutionKind": "bundler"
      }
    ]
  },
  "problems": {
    "NoResolution": [
      {
        "kind": "NoResolution",
        "entrypoint": ".",
        "resolutionKind": "node10"
      },
      {
        "kind": "NoResolution",
        "entrypoint": ".",
        "resolutionKind": "node16-cjs"
      },
      {
        "kind": "NoResolution",
        "entrypoint": ".",
        "resolutionKind": "node16-esm"
      },
      {
        "kind": "NoResolution",
        "entrypoint": ".",
        "resolutionKind": "bundler"
      }
    ]
  }
}

this package has no exports field or main, and so the entry points are just "the files that are present in the package".

Oh, I assumed you meant InternalResolutionError, which contains more details. If entrypoints can’t be detected, the tool only checks an import of the package name with no subpath. If you’d like to override that, you can specify --entrypoints

❯ attw -p react --entrypoints "./foo" "./bar" 

react v18.2.0
@types/react v18.2.59

💀 Import failed to resolve to type declarations or JavaScript files. https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/NoResolution.md


┌───────────────────┬──────────────────────┬──────────────────────┐
│                   │ "react/foo"          │ "react/bar"          │
├───────────────────┼──────────────────────┼──────────────────────┤
│ node10            │ 💀 Resolution failed │ 💀 Resolution failed │
├───────────────────┼──────────────────────┼──────────────────────┤
│ node16 (from CJS) │ 💀 Resolution failed │ 💀 Resolution failed │
├───────────────────┼──────────────────────┼──────────────────────┤
│ node16 (from ESM) │ 💀 Resolution failed │ 💀 Resolution failed │
├───────────────────┼──────────────────────┼──────────────────────┤
│ bundler           │ 💀 Resolution failed │ 💀 Resolution failed │
└───────────────────┴──────────────────────┴──────────────────────┘

ah, that's unfortunate, since that's not how node packages work :-/ basically every file that shows up in npm-packlist's output is an entry point in a package without exports. Is that something you'd be willing to support? (if so, i can try my hand at a PR)

I understand that any file can be accessible as an entrypoint, but before exports existed, it would have been pretty reasonable for a package author to say that "pkg/dist/internal/foo.js" doesn’t have TypeScript types because it wasn’t intended to be a public entrypoint. It would be counterproductive for this tool to make a lot of noise about older packages like that, which are functioning as intended. I might be open to adding a flag to enable that behavior, but it seems like --entrypoints with a little bash-fu would suffice.

Reasonable, but irrelevant in terms of what's actually in their public API :-)

What about a flag that enables the npm-packlist detection i mentioned? that way i wouldn't need the bash-fu.

I’m open to it.

I've almost got the PR ready, and it worked great on my linked project! However, in what I suspect is a separate issue, it complained that the packages were using exports.default = and exports.__esModule = true, and not setting module.exports, but when i made that change, now it wants me to use export = which seems like it contradicts the intended transpiled ESM usage.

The tool considers

exports.__esModule = true;
exports.default = Whatever;

to be harmful, since the importing code

import Whatever from "pkg";
Whatever.default();

works in Node.js, Webpack1, and esbuild1, but crashes in every other major runtime/bundler. Since runtimes and tools failed to agree on how that interop should work, the tool recommends avoiding that pattern.

Footnotes

  1. when package.json "type": "module" is set, or the importing file extension is .mjs 2

Hmm - what other runtimes and bundlers qualify as "major"?

Is there any option on the tool to suppress that warning?

Given that this project won't work in a browser anyways, and thus bundlers aren't relevant - it's node-only, for eslint - is there any ambient way to indicate that to this tool, so i don't have to remember to supply the option?

You can make an attw.json

ok, i filed #156 but the snapshots aren't reflecting the passed option, if you have any time to take a look :-)