microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.69k stars 12.44k forks source link

Evaluate popular packages that have `exports` fields set but may not be Node ESM-ready for TypeScript #47792

Open DanielRosenwasser opened 2 years ago

DanielRosenwasser commented 2 years ago

The exports field in package.json - nobody knows how to configure it, which probably means that a negative number of people know how to configure it for TypeScript.

Anyway, a very good way to ensure that 99% of users have no issues with consuming a Node ESM package is to do a sweep of the npm registry to find the most popular packages that have an exports field and a types field set and validate that they have correctly configured their types.

The steps include

Last time I tried to do this with all-the-package-names, people told me the list might be too outdated, but the list might serve as a decent guide anyway:

Click here to see the list. Self-Typed: 18 Package Name | Exports Value | Assesment -------------|---------------|---------- postcss | Object | ? babel-jest | Object | ? rxjs | Object | ? typedoc | String | ? ts-node | Object | ? projectz | Object | ? postcss-custom-properties | Object | ? postcss-scss | Object | ? uid | Object | ? emailjs | Object | ? ngrok | Object | ? pob-babel | Object | ? preact | Object | ? assert-helpers | Object | ? getmac | Object | ? simple-statistics | Object | ? discord.js | Object | ? editions | Object | ? Packages with `@types` ====================== At-Typed: 121 Package Name | Exports Value | Assesment -------------|---------------|---------- chai | Object | ? eslint | Object | ? tape | Object | ? underscore | Object | ? yargs | Object | ? socket.io | Object | ? js-yaml | Object | ? expect | Object | ? uuid | Object | ? ws | Object | ? rollup | Object | ? koa | Object | ? socket.io-client | Object | ? meow | String | ? npm | Object | ? jest-cli | Object | ? highlight.js | Object | ? mustache | Object | ? dotenv | Object | ? d3 | Object | ? deep-equal | Object | ? jest | Object | ? gulp-imagemin | String | ? diff | Object | ? unique-random-array | String | ? globby | String | ? ora | String | ? acorn | Object | ? path-exists | String | ? firebase | Object | ? vinyl-paths | String | ? strip-ansi | String | ? strip-json-comments | String | ? systemjs | Object | ? log-symbols | Object | ? escape-string-regexp | String | ? get-stdin | String | ? stack-trace | Object | ? is-promise | Object | ? slash | String | ? es6-promisify | Object | ? imagemin | String | ? configstore | String | ? figures | String | ? strip-bom | String | ? mathjs | Object | ? baconjs | Object | ? engine.io | Object | ? is-plain-object | Object | ? tempfile | String | ? arrify | String | ? supports-color | Object | ? tildify | String | ? is-stream | String | ? normalize-url | String | ? d3-scale | Object | ? temp-write | String | ? indent-string | String | ? d3-selection | Object | ? d3-array | Object | ? read-chunk | String | ? is-plain-obj | String | ? yaml | Object | ? engine.io-client | Object | ? js-cookie | Object | ? ansi-styles | String | ? npm-name | String | ? pako | Object | ? detect-indent | String | ? decamelize | String | ? stringify-object | String | ? ansi-regex | String | ? sass | Object | ? string-length | String | ? get-port | String | ? lowdb | String | ? js-base64 | Object | ? find-up | String | ? dargs | String | ? array-uniq | String | ? humanize-url | String | ? repeating | String | ? d3-shape | Object | ? read-pkg-up | String | ? strip-indent | String | ? hashids | Object | ? junk | String | ? istextorbinary | Object | ? ansi-escapes | String | ? geolib | Object | ? yargs-parser | Object | ? commonmark | Object | ? username | String | ? jssha | Object | ? latest-version | String | ? github-username | String | ? string-width | String | ? is-root | String | ? d3-transition | Object | ? trash | String | ? js-combinatorics | Object | ? socket.io-parser | Object | ? d3-dsv | Object | ? form-urlencoded | Object | ? semver-regex | String | ? cli-cursor | String | ? internal-ip | Object | ? linq | String | ? d3-color | Object | ? node-hue-api | Object | ? d3-interpolate | Object | ? elegant-spinner | String | ? read-pkg | String | ? has-ansi | String | ? node-ipc | Object | ? leven | String | ? d3-axis | Object | ? d3-format | Object | ? is-obj | String | ? boxen | String | ? d3-dispatch | Object | ?
andrewbranch commented 2 years ago

all-the-package-names seems to be updated daily. Not sure why we thought the list was outdated before?

jaydenseric commented 2 years ago

I've been using TypeScript v4.6-dev.x and the node12 mode extensively for some time now. One of the things that makes it really confusing to work with the new node12 mode is that often VS Code lies and is able to display types for imports ok within the editor (yes, with the local TypeScript installation selected in VS Code), when really tsc via the CLI can't resolve the types. You will see "has no exported member" type errors for the same imports, when the imported package doesn't support TypeScript v4.6 node12 mode properly with correct package exports, .d.mts files, etc.

It makes it harder to evaluate as you are working what packages are ESM ready and to experiment with possible fixes for a PR by hacking them in node_modules, since you have to ignore what the editor is saying and keep running the tsc CLI for feedback.

An example of a package this happens with is playwright@1.18.1...

With this .vscode/settings.json:

{
  "typescript.disableAutomaticTypeAcquisition": true,
  "typescript.enablePromptUseWorkspaceTsdk": true,
  "typescript.tsdk": "node_modules/typescript/lib"
}

And this jsconfig.json:

{
  "compilerOptions": {
    "module": "node12",
    "noEmit": true,
    "strict": true
  },
  "typeAcquisition": {
    "enable": false
  }
}

And this package devDependency:

{
  "typescript": "^4.6.0-dev.20220207"
}

And this package scripts:

{
  "types": "tsc -p jsconfig.json",
}

If you run:

npm run types

In a.mjs:

// @ts-check

/** @typedef {import("playwright").chromium} A */
/** @typedef {import("playwright").Page} B */

In b.mts:

import { chromium } from "playwright";
import type { Page } from "playwright";

In the VS Code editor the imported Page type resolves for intellisense:

Screen Shot 2022-02-08 at 11 12 30 am Screen Shot 2022-02-08 at 11 12 01 am

But via tsc:

Screen Shot 2022-02-08 at 11 13 01 am

The playwright package doesn't appear to be in the list of "popular" packages for this issue, but given it's pretty popular and also a Microsoft project that aims to support TypeScript it would really make sense for it to be fully compatible with TypeScript v4.6.

weyert commented 2 years ago

@DanielRosenwasser Would you be so kind and help me find the correct way to do? Would the snippet below be correct?

"exports": {
    ".": {
      "import": "./index.mjs",
      "require": "./index.js",
      "types": "./index.d.ts"
    },
    "./cli": "./cli.js",
    "./package.json": "./package.json",
  },

Assuming there is a index.d.ts in the root of the package directory

andrewbranch commented 2 years ago

That is right, assuming a single index.d.ts can accurately describe the ESM and CJS interfaces simultaneously.

sandersn commented 2 years ago

all-the-package-names seems to be updated daily. Not sure why we thought the list was outdated before?

It wasn't published for two years, then the first publish was 10 hours before your comment. Coincidence?

..Probably.

Edit: looking at https://github.com/nice-registry/all-the-package-names/pull/26, I see that it now depends on all-the-package-repos, which now, surprisingly, includes all packages, even ones without repos. But it's not sorted by dependent count anymore.

Edit 2 (from May): all-the-package-names stopped updating from mid-March to May. Check to see if it's current before using it.

lizthegrey commented 2 years ago

This appears to be impacting Jose and Terser where types export is not configured, but types are available and listed in package.json

DanielRosenwasser commented 2 years ago

Thank you for sending those PRs!

lizthegrey commented 2 years ago

This just bit vue-router.