Get the exports of a package.
- What is this?
- When should I use this?
- Install
- Use
- API
- Errors
exports-alternatives
exports-alternatives-empty
exports-conditions-default-misplaced
exports-conditions-default-missing
exports-conditions-mutually-exclusive
exports-conditions-verbose
exports-main-missing
exports-negated-missing
exports-object-empty
exports-object-mixed
exports-path-not-found
exports-path-unprefixed
exports-path-wildcard-not-found
exports-specifier-extension
exports-specifier-nested
exports-specifier-wildcard-invalid
exports-specifier-wildcard-useless
exports-specifiers-verbose
exports-types-verbose
exports-value-invalid
files-missing
main
main-extra
main-inferred
main-invalid
main-missing
main-not-found
main-resolve-commonjs
main-resolve-module
name-missing
npm-ignored
type-invalid
type-missing
- Compatibility
- Security
- Contribute
- License
This package finds out what is exposed from a package. It also emits many possible warnings about potential problems.
You can use this to programatically figure out what can be used from a package. You can also use this to lint packages.
This package is ESM only. In Node.js (version 18+), install with npm:
npm install package-exports
import {packageExports} from 'package-exports'
import {reporter} from 'vfile-reporter'
const thisPackage = await packageExports(new URL('.', import.meta.url))
console.dir(thisPackage, {depth: undefined})
const tar = await packageExports(new URL('node_modules/tar/', import.meta.url))
console.error(reporter(tar.file))
Yields:
{
exports: [
{
conditions: undefined,
exists: true,
jsonPath: [ 'exports' ],
specifier: '.',
url: 'file:///Users/…/package-exports/index.js'
}
],
file: VFile { … },
name: 'package-exports'
}
node_modules/tar/package.json
1:1-70:2 warning Unexpected inferred main export `./index.js`, it’s recommended to use an export map such as `"exports": "./index.js"` main-inferred package-exports
1:1-70:2 warning Unexpected missing `type` field, expected `type: 'commonjs'` or `'module'` type-missing package-exports
⚠ 2 warnings
This package exports the identifier
packageExports
.
It exports the TypeScript types
Export
and
Result
.
There is no default export.
Get the exports of a package.
folder
(URL
, required) — file URL to folder of a package
Result (Promise<Result>
).
Export (TypeScript type).
conditions
(Array<string>
) — conditionsexists
(boolean
) — whether this file existsjsonPath
(Array<number | string>
) — path inpackage.json
specifier
(string
) — specifier that exposes thisurl
(URL
) — resolved URL to file
Result of finding exports (TypeScript type).
exports
(Array<Exports>
) — exportsfile
(VFile
) – filename
(string
orundefined
) – package name
This package lints for many problems in npm packages and adds each message to
the vfile.
Messages will have a source
field set to package-exports
and a ruleId
to one of the following values.
package.json
:
{
"exports": {
".": "./index.js",
"./other": [
"./other.js"
]
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
Yields:
4:16-6:6: Unexpected alternatives list at `exports['./other']`, several tools don’t support this and pick the first item
Fix:
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./other": ["./other.js"]
+ "./other": "./other.js"
},
"files": ["index.js", "other.js"],
"name": "x",
package.json
:
{
"exports": {
".": "./index.js",
"./other": []
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
4:16-4:18: Unexpected empty array at `exports['./other']` doing nothing, expected a single item
Fix:
@@ -1,7 +1,6 @@
{
"exports": {
- ".": "./index.js",
- "./other": []
+ ".": "./index.js"
},
"files": ["index.js"],
"name": "x",
package.json
:
{
"exports": {
"default": "./index.js",
"production": "./other.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
Yields:
4:19-4:31: Unexpected non-last `default` conditions at `exports` ignoring everything after it, move the `default` condition to the end
Fix:
@@ -1,7 +1,7 @@
{
"exports": {
- "default": "./index.js",
- "production": "./other.js"
+ "production": "./other.js",
+ "default": "./index.js"
},
"files": ["index.js", "other.js"],
"name": "x",
package.json
:
{
"exports": {
"production": "./index.js"
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
2:14-4:4: Unexpected conditions without a `default` entry at `exports` making specifier `.` unusable by default, expected `'default'` condition as the last field
Fix:
@@ -1,6 +1,7 @@
{
"exports": {
- "production": "./index.js"
+ "production": "./index.js",
+ "default": "./other.js"
},
"files": [
"index.js"
package.json
:
{
"exports": {
"import": {
"require": "./other.js",
"default": "./index.js"
},
"default": "./index.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
Yields:
4:18-4:30: Unexpected condition `require` mutually exclusive with `import` at `exports.import` which never matches, use only one of these conditions
Fix:
@@ -1,10 +1,7 @@
{
"exports": {
- "import": {
- "require": "./other.js",
- "default": "./index.js"
- },
- "default": "./index.js"
+ "require": "./other.js",
+ "import": "./index.js"
},
"files": [
"index.js",
package.json
:
{
"exports": {
"default": "./index.js"
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
2:14-4:4: Unexpected verbose conditions object with sole key `default` at `exports`, replace the object with the value at `default`
Fix:
@@ -1,7 +1,5 @@
{
- "exports": {
- "default": "./index.js"
- },
+ "exports": "./index.js",
"files": [
"index.js"
],
package.json
:
{
"exports": {
"./x": "./index.js"
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
1:1-10:2: Unexpected missing main specifier `.`, expected an export to the main module
Fix:
@@ -1,5 +1,6 @@
{
"exports": {
+ ".": "./index.js",
"./x": "./index.js"
},
"files": [
package.json
:
{
"exports": {
".": "./index.js",
"./*": null
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
4:12-4:16: Unexpected negation specifier `./*` at `exports['./*']` with nothing to negate
Fix:
@@ -1,6 +1,7 @@
{
"exports": {
".": "./index.js",
+ "./x": "./index.js",
"./*": null
},
"files": [
package.json
:
{
"exports": {
".": "./index.js",
"./other": {}
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
4:16-4:18: Unexpected empty object at `exports['./other']` doing nothing, expected fields
Fix:
@@ -1,7 +1,6 @@
{
"exports": {
- ".": "./index.js",
- "./other": {}
+ ".": "./index.js"
},
"files": [
"index.js"
package.json
:
{
"exports": {
".": "./index.js",
"default": "./other.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
Yields:
1:1-12:2: Unexpected missing main specifier `.`, expected an export to the main module
2:14-5:4: Unexpected mixed specifiers (starting with `.`) and conditions (without `.`) at `exports`, expected either specifiers or conditions
Fix:
@@ -1,6 +1,6 @@
{
"exports": {
- ".": "./index.js",
+ "other": "./index.js",
"default": "./other.js"
},
"files": [
package.json
:
{
"exports": {
".": "./index.js",
"./x": "./missing.js"
},
"files": [
"index.js",
"missing.js"
],
"name": "x",
"type": "module"
}
Yields:
4:12-4:26: Unexpected missing file `./missing.js` for specifier `./x` at `exports['./x']`
Fix: make sure files exist.
package.json
:
{
"exports": "index.js",
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
1:1-8:2: Unexpected missing main specifier `.`, expected an export to the main module
2:14-2:24: Unexpected unprefixed value `'index.js'` at `exports` which is not importable, did you mean `'./index.js'`
Fix:
@@ -1,5 +1,5 @@
{
- "exports": "index.js",
+ "exports": "./index.js",
"files": [
"index.js"
],
package.json
:
{
"exports": {
".": "./index.js",
"./*": "./lib/*"
},
"files": [
"lib/",
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
4:12-4:21: Unexpected dynamic file glob `./lib/*` at `exports['./*']` pointing to nothing, expected files
Fix: make sure files exist.
package.json
:
{
"exports": {
".": "./index.js",
"./other.js": "./other.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
Yields:
2:14-5:4: Unexpected extension `.js` in specifier `./other.js` at `exports`, extensions have no meaning in specifiers, expected `./other`
Fix:
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./other.js": "./other.js"
+ "./other": "./other.js"
},
"files": [
"index.js",
package.json
:
{
"exports": {
".": "./index.js",
"./other": {
"./more": "./other.js"
}
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
Yields:
4:16-6:6: Unexpected nested specifier `./more` at `exports['./other']`, expected conditions
Fix:
@@ -1,9 +1,7 @@
{
"exports": {
".": "./index.js",
- "./other": {
- "./more": "./other.js"
- }
+ "./other/more": "./other.js"
},
"files": [
"index.js",
package.json
:
{
"exports": {
".": "./index.js",
"./x/*/y/*": "./other.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
Yields:
4:18-4:30: Unexpected extra wildcard in dynamic specifier `./x/*/y/*` at `exports['./x/*/y/*']`, one wildcard is allowed
Fix:
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./x/*/y/*": "./other.js"
+ "./x/*/y": "./other.js"
},
"files": [
"index.js",
package.json
:
{
"exports": {
".": "./index.js",
"./*": "./other.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
Yields:
4:12-4:24: Unexpected dynamic specifier `./*` pointing to static file `./other.js` at `exports['./*']`, use dynamic specifiers with dynamic file globs
Fix:
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./*": "./other.js"
+ "./other": "./other.js"
},
"files": [
"index.js",
package.json
:
{
"exports": {
".": "./index.js"
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
2:14-4:4: Unexpected verbose specifier object with sole key `.` at `exports`, replace the object with the value at `.`
Fix:
@@ -1,7 +1,5 @@
{
- "exports": {
- ".": "./index.js"
- },
+ "exports": "./index.js",
"files": [
"index.js"
],
package.json
:
{
"exports": {
"types": "./index.d.ts",
"default": "./index.js"
},
"files": [
"index.d.ts",
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
3:14-3:28: Unexpected verbose `types` condition at `exports` matching what TypeScript would load for `default` without it, remove it
Fix:
@@ -1,8 +1,5 @@
{
- "exports": {
- "types": "./index.d.ts",
- "default": "./index.js"
- },
+ "exports": "./index.js",
"files": [
"index.d.ts",
"index.js"
package.json
:
{
"exports": {
".": "./index.js",
"./other": 1
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
4:16-4:17: Unexpected invalid value `1` at `exports['./other']` which is not importable, expected conditions object, `string` (path to file), or `null` (negated)
Fix:
+++ b/example/package.json
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./other": 1
+ "./other": "./other.js"
},
"files": [
"index.js"
package.json
:
{
"exports": "./index.js",
"name": "x",
"type": "module",
}
Yields:
1:1-5:2: Unexpected missing `files` field, expected array of allowed files to include
Fix:
@@ -1,5 +1,8 @@
{
"exports": "./index.js",
+ "files": [
+ "index.js"
+ ],
"name": "x",
"type": "module"
}
package.json
:
{
"files": [
"index.js",
"other.js"
],
"main": "index.js",
"name": "x",
"type": "module"
}
Yields:
6:11-6:21: Unexpected legacy `main` field that does not encapsulate the package, it’s recommended to use an export map such as `"exports": "./index.js"`
Fix:
@@ -1,9 +1,9 @@
{
+ "exports": "./index.js",
"files": [
"index.js",
"other.js"
],
- "main": "index.js",
"name": "x",
"type": "module"
}
package.json
:
{
"exports": "./index.js",
"files": [
"index.js"
],
"main": "index.js",
"name": "x",
"type": "module"
}
Yields:
6:11-6:21: Unexpected unused legacy `main` field with modern `exports`, remove it
Fix:
@@ -3,7 +3,6 @@
"files": [
"index.js"
],
- "main": "index.js",
"name": "x",
"type": "module"
}
package.json
:
{
"files": [
"index.js"
],
"name": "x",
"type": "commonjs"
}
Yields:
1:1-7:2: Unexpected inferred main export `./index.js`, it’s recommended to use an export map such as `"exports": "./index.js"`
Fix:
@@ -1,4 +1,5 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
package.json
:
{
"files": [
"index.js"
],
"main": 1,
"name": "x",
"type": "commonjs"
}
Yields:
1:1-8:2: Unexpected inferred main export `./index.js`, it’s recommended to use an export map such as `"exports": "./index.js"`
5:11-5:12: Unexpected non-string `main` field `1`
Fix:
@@ -1,8 +1,8 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
- "main": 1,
"name": "x",
"type": "commonjs"
}
package.json
:
{
"files": [
"default.js"
],
"name": "x",
"type": "commonjs"
}
Yields:
1:1-7:2: Unexpected missing main module, it’s recommended to use an export map such as `"exports": "./index.js"`
Fix:
@@ -1,4 +1,5 @@
{
+ "exports": "./default.js",
"files": [
"default.js"
],
package.json
:
{
"files": [
"index.js"
],
"main": "./missing.js",
"name": "x",
"type": "commonjs"
}
Yields:
1:1-8:2: Unexpected inferred main export `./index.js`, it’s recommended to use an export map such as `"exports": "./index.js"`
5:11-5:25: Unexpected missing file for `main` field `./missing.js`
Fix:
@@ -1,8 +1,8 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
- "main": "./missing.js",
"name": "x",
"type": "commonjs"
}
package.json
:
{
"files": [
"index.js"
],
"main": "index",
"name": "x",
"type": "commonjs"
}
Yields:
5:11-5:18: Unexpected `main` field `index` that resolves to `./index.js` in CJS, this works but is slow and doesn’t work with `type: 'module', use the resolved value explicitly
Fix:
@@ -1,8 +1,8 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
- "main": "index",
"name": "x",
"type": "commonjs"
}
package.json
:
{
"files": [
"index.js"
],
"main": "index",
"name": "x",
"type": "module"
}
Yields:
1:1-9:2: Unexpected inferred main export `./index.js`, it’s recommended to use an export map such as `"exports": "./index.js"`
6:11-6:18: Unexpected `main` field `index` that does not resolve with `type: 'module'`, use an export map such as `"exports": "./index.js"`
Fix:
@@ -1,8 +1,8 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
- "main": "index",
"name": "x",
"type": "module"
}
package.json
:
{
"exports": "./index.js",
"files": [
"index.js"
],
"type": "module"
}
Yields:
1:1-7:2: Unexpected missing `name` field, expected a package name
Fix:
@@ -3,5 +3,6 @@
"files": [
"index.js"
],
+ "name": "x",
"type": "module"
}
package.json
:
{
"exports": {
".": "./index.js",
"./other": "./other.js"
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
Yields:
4:16-4:28: Unexpected file `./other.js` at `exports['./other']` which is excluded from the npm package, add it to `files` in `package.json`
Fix:
@@ -4,7 +4,8 @@
"./other": "./other.js"
},
"files": [
- "index.js"
+ "index.js",
+ "other.js"
],
"name": "x",
"type": "module"
package.json
:
{
"exports": "./index.js",
"files": [
"index.js"
],
"name": "x",
"type": "umd",
}
Yields:
7:11-7:16: Unexpected invalid `type` value `umd`, expected `commonjs` or `module`
Fix:
@@ -4,5 +4,5 @@
"index.js"
],
"name": "x",
- "type": "umd"
+ "type": "module"
}
package.json
:
{
"exports": "./index.js",
"files": [
"index.js"
],
"name": "x"
}
Yields:
1:1-7:2: Unexpected missing `type` field, expected `type: 'commonjs'` or `'module'`
Fix:
@@ -3,5 +3,6 @@
"files": [
"index.js"
],
- "name": "x"
+ "name": "x",
+ "type": "commonjs"
}
This projects is compatible with maintained versions of Node.js.
When we cut a new major release, we drop support for unmaintained versions of
Node.
This means we try to keep the current release line, package-exports@1
,
compatible with Node.js 18.
This package is safe.
Yes please! See How to Contribute to Open Source.