'How can I use "exports" in package.json today for nested submodules and typescript
Latest Update (2022-04-10): TS 4.7@beta supports "exports"
tl;dr
// package.json
"type": "module"
// tsconfig.json
"module": "node12" // or "nodenext"
Update: TS 4.5 does not support "exports" (also see this issue):
... support for Node.js 12 has been deferred to a future release, and is now only available as an experimental flag in nightly releases. This was not an easy decision, but our team had a combination of concerns around ecosystem readiness and general guidance for how/when to use the feature.
[2022-04-01] The feature is still not available in TS 4.6.
Original question:
I am wanting to take advantage of the new-ish "exports" feature of NodeJS/package.json so that I can do the following:
"exports": {
".": "./dist/index.js",
"./foo": "./dist/path/to/foo.js"
}
And users can do the following:
import { foo } from 'my-package/foo';
Typescript 4.5 should support the "exports" field, yet it does not seem to work. I am building a simple package using TS 4.5.2, and I am consuming that package in a project using TS 4.5.2. I have looked at other SO questions and this github thread and this bug report but can't seem to find a consensus on the issue and whether it should work today.
Note 1: I am still able to import using the more verbose syntax:
import { foo } from 'my-package/dist/path/to/foo.js';
Note 2: I have also tried the object notation for exports, to no avail:
"exports": { ".": { "require": "./dist/index.js", "import": "./dist/index.js" }, "./foo": { "require": "./dist/path/to/foo.js", "import": "./dist/path/to/foo.js" } }
Question(s):
- Is this feature ready to be used with typescript projects today? If not, I just want to know.
- If yes to #1, what am I missing? Specifics about tsconfig would be useful for both the source project and consuming project. The TS compiler complains about
node12/nodenextbeing used for either themoduleormoduleResolutionfields (I am definitely using TS 4.5.2).
Solution 1:[1]
Without knowing what error you are getting, or in what other way TypeScript doesn't seem to be working for you (not sure why you would not want to share such crucial information), I can tell that your exports section appears to be missing types information. Typically, if your .d.ts files were located next to their respective .js files, your exports section would look like this:
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./foo": {
"types": "./dist/path/to/foo.d.ts",
"default": "./dist/path/to/foo.js"
}
}
Solution 2:[2]
I've been looking to use nested folders for a design system package we created at Pipefy, and after deep research, I found how to do it.
The package exports React components, and we use to import them like this import { Button } from '@mypackage/design-system;
Later on, we've added tokens to our design system library, like Colors, Spacing, and Fonts, but we don't want to import everything from the index, it isn't productive.
After some exhaustive research, I found how to export nested folders using TypeScript. My purpose is to use tokens like this import { Colors } from '@mypackage/design-system/tokens;
To use your TypeScript lib like this you should use the typesVersions inside the package.json file.
Here I use it like this
"typesVersions": {
"*": {
"index": [
"lib/components/index.d.ts"
],
"tokens": [
"lib/tokens/index.d.ts"
]
}
},
It worked like a charm for me, it would work for you too!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | GOTO 0 |
| Solution 2 | Daniel Nass |
