-
-
Notifications
You must be signed in to change notification settings - Fork 219
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
Ensure matching declaration file exists for each output bundle format #934
Conversation
This branch is running in CodeSandbox. Use the links below to review this PR faster. |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
🎉 This PR is included in version 7.1.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Thank you @egoist! Excited about this 😄 |
{
"entry": ["src/index.ts"],
"format": ["cjs", "esm"],
"dts": true,
"clean": true
} Only needs 1 .d.ts file.. The types doesn't change from cjs to esm. {
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"build": "tsup"
},
"devDependencies": {
"@types/node": "latest",
"tsup": "<7.1.0",
"typescript": "latest",
} |
Perhaps unfortunately, this isn’t how TypeScript works. Declaration files that represent modules are understood by the compiler to be 1:1 to JS files, and have a file-level module kind that represents whether it represents an ES module or CJS module. So even if the contents of the files are the same, the compiler needs to see two separate declaration files with two different file extensions in order to accurately capture the reality of what’s going on at runtime. The example package.json you provided would work for TypeScript users in FWIW, I’ve played with ideas on how to eliminate the need for this content-level duplication within the compiler, and it’s not out of the question that a future version of TypeScript will support something to make it unnecessary for libraries who ship dual packages to do this. But as of the TypeScript that exists today, it is necessary, and the consequences of not doing it are thoroughly documented. |
The packages that these build work in both I don't have If you have an example repo where things are meant to be broken I wouldn't mind testing my packages on that.. because I am obviously not reproducing the scenarios that this change is attempting to fix correctly. At the very least, if things do start to get terrible for this.. I'll just stop buidling for .cjs and just become module only.. That will get away from the multiple .d.ts files problem completely. |
If you have a publicly published package, I can make a repro specific to your use case. (In the future, I think it would be cool to be able to auto-generate repros with https://arethetypeswrong.github.io) |
I'm curious how we go about specify that with just the |
You have to use |
Is there any way we could de-duplicate the declaration files by forcing code splitting between the two formats? When there are multiple entrypoints, the I can open this as a separate issue if that seems like a reasonable ask, since this PR has been merged. |
<!-- 👋 Hi, thanks for sending a PR to template-typescript-node-package! 💖. Please fill out all fields below and make sure each item is true and [x] checked. Otherwise we may not be able to review your PR. --> ## PR Checklist - [x] Addresses an existing open issue: fixes #632 - [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/template-typescript-node-package/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22) - [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/template-typescript-node-package/blob/main/.github/CONTRIBUTING.md) were taken ## Overview Bumps to the latest version of `tsup` to include egoist/tsup#934. Adds an `entry` for all non-`test` files in `src/` so that the existing directory structure is maintained.
👋 Hi, I work on the TypeScript team on module-related stuff. I’ve been researching problems with typings in npm packages for a long time, and made https://arethetypeswrong.github.io to help. I’ve noticed that packages generated with tsup often report the FalseCJS or FalseESM problems. If you read the explanations there, it should be clear why:
.mjs
→.d.mts
etc.);.d.ts
extension, even when multiple outputs with different extensions are generated.Solving dual emit in a type-safe way is a very hard problem. As you know, tsup doesn’t even know if it’s producing safe runtime code due to module format incompatibilities (#628, #752). With enough effort (and correct typings to rely on), TypeScript can detect these problems, but it can’t really solve them. Tsup, on the other hand, cannot detect them, but can solve them by bundling ESM-only dependencies via
noExternal
/devDependencies
. It would be nice if a tool like tsup could leverage TypeScript to verify that a given output format is going to be valid and produce a guaranteed correct declaration file for that format, but it’s not really possible with the way tsup bundles things and relies on rolling up the declaration files.This PR is not perfect, but for adding just a few lines, it should produce valid TypeScript declarations much more often. Since the declarations are not guaranteed to compile, I suggested performing additional checks with arethetypeswrong in the README. Basically, all this does is
You can read more in-depth explanation of the way TypeScript treats modules and declaration files at https://gist.github.com/andrewbranch/79f872a8b9f0507c9c5f2641cfb3efa6.
What do you think?