package-exports v1.0.0
package-exports
Get the exports of a package.
Contents
- What is this?
- When should I use this?
- Install
- Use
- API
- Errors
exports-alternativesexports-alternatives-emptyexports-conditions-default-misplacedexports-conditions-default-missingexports-conditions-mutually-exclusiveexports-conditions-verboseexports-main-missingexports-negated-missingexports-object-emptyexports-object-mixedexports-path-not-foundexports-path-unprefixedexports-path-wildcard-not-foundexports-specifier-extensionexports-specifier-nestedexports-specifier-wildcard-invalidexports-specifier-wildcard-uselessexports-specifiers-verboseexports-types-verboseexports-value-invalidfiles-missingmainmain-extramain-inferredmain-invalidmain-missingmain-not-foundmain-resolve-commonjsmain-resolve-modulename-missingnpm-ignoredtype-invalidtype-missing
- Compatibility
- Security
- Contribute
- License
What is this?
This package find out what is exposed from a package. It also emits many possible warnings about potential problems.
When should I use this?
You can use this to programatically figure out what can be used from a package. You can also use this to lint packages.
Install
This package is ESM only. In Node.js (version 18+), install with npm:
npm install package-exportsUse
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 warningsAPI
This package exports the identifier
packageExports.
It exports the TypeScript types
Export and
Result.
There is no default export.
packageExports(folder)
Get the exports of a package.
Parameters
folder(URL, required) — file URL to folder of a package
Returns
Result (Promise<Result>).
Export
Export (TypeScript type).
Fields
conditions(Array<string>) — conditionsexists(boolean) — whether this file existsjsonPath(Array<number | string>) — path inpackage.jsonspecifier(string) — specifier that exposes thisurl(URL) — resolved URL to file
Result
Result of finding exports (TypeScript type).
Fields
exports(Array<Exports>) — exportsfile(VFile) – filename(stringorundefined) – package name
Errors
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.
exports-alternatives
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 itemFix:
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./other": ["./other.js"]
+ "./other": "./other.js"
},
"files": ["index.js", "other.js"],
"name": "x",exports-alternatives-empty
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 itemFix:
@@ -1,7 +1,6 @@
{
"exports": {
- ".": "./index.js",
- "./other": []
+ ".": "./index.js"
},
"files": ["index.js"],
"name": "x",exports-conditions-default-misplaced
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 endFix:
@@ -1,7 +1,7 @@
{
"exports": {
- "default": "./index.js",
- "production": "./other.js"
+ "production": "./other.js",
+ "default": "./index.js"
},
"files": ["index.js", "other.js"],
"name": "x",exports-conditions-default-missing
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 fieldFix:
@@ -1,6 +1,7 @@
{
"exports": {
- "production": "./index.js"
+ "production": "./index.js",
+ "default": "./other.js"
},
"files": [
"index.js"exports-conditions-mutually-exclusive
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 conditionsFix:
@@ -1,10 +1,7 @@
{
"exports": {
- "import": {
- "require": "./other.js",
- "default": "./index.js"
- },
- "default": "./index.js"
+ "require": "./other.js",
+ "import": "./index.js"
},
"files": [
"index.js",exports-conditions-verbose
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"
],exports-main-missing
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 moduleFix:
@@ -1,5 +1,6 @@
{
"exports": {
+ ".": "./index.js",
"./x": "./index.js"
},
"files": [exports-negated-missing
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 negateFix:
@@ -1,6 +1,7 @@
{
"exports": {
".": "./index.js",
+ "./x": "./index.js",
"./*": null
},
"files": [exports-object-empty
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 fieldsFix:
@@ -1,7 +1,6 @@
{
"exports": {
- ".": "./index.js",
- "./other": {}
+ ".": "./index.js"
},
"files": [
"index.js"exports-object-mixed
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 conditionsFix:
@@ -1,6 +1,6 @@
{
"exports": {
- ".": "./index.js",
+ "other": "./index.js",
"default": "./other.js"
},
"files": [exports-path-not-found
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.
exports-path-unprefixed
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"
],exports-path-wildcard-not-found
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 filesFix: make sure files exist.
exports-specifier-extension
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",exports-specifier-nested
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 conditionsFix:
@@ -1,9 +1,7 @@
{
"exports": {
".": "./index.js",
- "./other": {
- "./more": "./other.js"
- }
+ "./other/more": "./other.js"
},
"files": [
"index.js",exports-specifier-wildcard-invalid
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 allowedFix:
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./x/*/y/*": "./other.js"
+ "./x/*/y": "./other.js"
},
"files": [
"index.js",exports-specifier-wildcard-useless
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 globsFix:
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./*": "./other.js"
+ "./other": "./other.js"
},
"files": [
"index.js",exports-specifiers-verbose
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"
],exports-types-verbose
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 itFix:
@@ -1,8 +1,5 @@
{
- "exports": {
- "types": "./index.d.ts",
- "default": "./index.js"
- },
+ "exports": "./index.js",
"files": [
"index.d.ts",
"index.js"exports-value-invalid
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"files-missing
package.json:
{
"exports": "./index.js",
"name": "x",
"type": "module",
}Yields:
1:1-5:2: Unexpected missing `files` field, expected array of allowed files to includeFix:
@@ -1,5 +1,8 @@
{
"exports": "./index.js",
+ "files": [
+ "index.js"
+ ],
"name": "x",
"type": "module"
}main
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"
}main-extra
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 itFix:
@@ -3,7 +3,6 @@
"files": [
"index.js"
],
- "main": "index.js",
"name": "x",
"type": "module"
}main-inferred
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"
],main-invalid
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"
}main-missing
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"
],main-not-found
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"
}main-resolve-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 explicitlyFix:
@@ -1,8 +1,8 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
- "main": "index",
"name": "x",
"type": "commonjs"
}main-resolve-module
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"
}name-missing
package.json:
{
"exports": "./index.js",
"files": [
"index.js"
],
"type": "module"
}Yields:
1:1-7:2: Unexpected missing `name` field, expected a package nameFix:
@@ -3,5 +3,6 @@
"files": [
"index.js"
],
+ "name": "x",
"type": "module"
}npm-ignored
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"type-invalid
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"
}type-missing
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"
}Compatibility
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.
Security
This package is safe.
Contribute
Yes please! See How to Contribute to Open Source.
License
2 years ago