Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/wooorm/package-exports
Get the exports of a package
https://github.com/wooorm/package-exports
api conditions exports node npm package
Last synced: 11 days ago
JSON representation
Get the exports of a package
- Host: GitHub
- URL: https://github.com/wooorm/package-exports
- Owner: wooorm
- License: mit
- Created: 2023-11-21T13:51:57.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-04-23T14:00:48.000Z (8 months ago)
- Last Synced: 2024-12-12T00:37:47.726Z (16 days ago)
- Topics: api, conditions, exports, node, npm, package
- Language: JavaScript
- Homepage:
- Size: 42 KB
- Stars: 17
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- Funding: funding.yml
- License: license
Awesome Lists containing this project
README
# package-exports
[![Build][badge-build-image]][badge-build-url]
[![Coverage][badge-coverage-image]][badge-coverage-url]
[![Downloads][badge-downloads-image]][badge-downloads-url]Get the exports of a package.
## Contents
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`packageExports(folder)`](#packageexportsfolder)
* [`Export`](#export)
* [`Result`](#result)
* [Errors](#errors)
* [`exports-alternatives`](#exports-alternatives)
* [`exports-alternatives-empty`](#exports-alternatives-empty)
* [`exports-conditions-default-misplaced`](#exports-conditions-default-misplaced)
* [`exports-conditions-default-missing`](#exports-conditions-default-missing)
* [`exports-conditions-mutually-exclusive`](#exports-conditions-mutually-exclusive)
* [`exports-conditions-verbose`](#exports-conditions-verbose)
* [`exports-main-missing`](#exports-main-missing)
* [`exports-negated-missing`](#exports-negated-missing)
* [`exports-object-empty`](#exports-object-empty)
* [`exports-object-mixed`](#exports-object-mixed)
* [`exports-path-not-found`](#exports-path-not-found)
* [`exports-path-unprefixed`](#exports-path-unprefixed)
* [`exports-path-wildcard-not-found`](#exports-path-wildcard-not-found)
* [`exports-specifier-extension`](#exports-specifier-extension)
* [`exports-specifier-nested`](#exports-specifier-nested)
* [`exports-specifier-wildcard-invalid`](#exports-specifier-wildcard-invalid)
* [`exports-specifier-wildcard-useless`](#exports-specifier-wildcard-useless)
* [`exports-specifiers-verbose`](#exports-specifiers-verbose)
* [`exports-types-verbose`](#exports-types-verbose)
* [`exports-value-invalid`](#exports-value-invalid)
* [`files-missing`](#files-missing)
* [`main`](#main)
* [`main-extra`](#main-extra)
* [`main-inferred`](#main-inferred)
* [`main-invalid`](#main-invalid)
* [`main-missing`](#main-missing)
* [`main-not-found`](#main-not-found)
* [`main-resolve-commonjs`](#main-resolve-commonjs)
* [`main-resolve-module`](#main-resolve-module)
* [`name-missing`](#name-missing)
* [`npm-ignored`](#npm-ignored)
* [`type-invalid`](#type-invalid)
* [`type-missing`](#type-missing)
* [Compatibility](#compatibility)
* [Security](#security)
* [Contribute](#contribute)
* [License](#license)## What is this?
This package finds 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][github-gist-esm].
In Node.js (version 18+), install with [npm][npm-install]:```sh
npm install package-exports
```## Use
```js
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:
```js
{
exports: [
{
conditions: undefined,
exists: true,
jsonPath: [ 'exports' ],
specifier: '.',
url: 'file:///Users/…/package-exports/index.js'
}
],
file: VFile { … },
name: 'package-exports'
}
``````txt
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
```## API
This package exports the identifier
[`packageExports`][api-package-exports].
It exports the [TypeScript][] types
[`Export`][api-export] and
[`Result`][api-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`][api-result]).
### `Export`
Export (TypeScript type).
###### Fields
* `conditions` (`Array`)
— conditions
* `exists` (`boolean`)
— whether this file exists
* `jsonPath` (`Array`)
— path in `package.json`
* `specifier` (`string`)
— specifier that exposes this
* `url` (`URL`)
— resolved URL to file### `Result`
Result of finding exports (TypeScript type).
###### Fields
* `exports` ([`Array`][api-export])
— exports
* `file` ([`VFile`][github-vfile])
– file
* `name` (`string` or `undefined`)
– package name## Errors
This package lints for many problems in npm packages and adds each message to
the [vfile][github-vfile].
Messages will have a `source` field set to `package-exports` and a `ruleId`
to one of the following values.### `exports-alternatives`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"./other": [
"./other.js"
]
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
4:16-6:6: Unexpected alternatives list at `exports['./other']`, several tools don’t support this and pick the first item
```Fix:
```diff
@@ -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`:
```json
{
"exports": {
".": "./index.js",
"./other": []
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
4:16-4:18: Unexpected empty array at `exports['./other']` doing nothing, expected a single item
```Fix:
```diff
@@ -1,7 +1,6 @@
{
"exports": {
- ".": "./index.js",
- "./other": []
+ ".": "./index.js"
},
"files": ["index.js"],
"name": "x",
```### `exports-conditions-default-misplaced`
`package.json`:
```json
{
"exports": {
"default": "./index.js",
"production": "./other.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
4:19-4:31: Unexpected non-last `default` conditions at `exports` ignoring everything after it, move the `default` condition to the end
```Fix:
```diff
@@ -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`:
```json
{
"exports": {
"production": "./index.js"
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
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:
```diff
@@ -1,6 +1,7 @@
{
"exports": {
- "production": "./index.js"
+ "production": "./index.js",
+ "default": "./other.js"
},
"files": [
"index.js"
```### `exports-conditions-mutually-exclusive`
`package.json`:
```json
{
"exports": {
"import": {
"require": "./other.js",
"default": "./index.js"
},
"default": "./index.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
4:18-4:30: Unexpected condition `require` mutually exclusive with `import` at `exports.import` which never matches, use only one of these conditions
```Fix:
```diff
@@ -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`:
```json
{
"exports": {
"default": "./index.js"
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
2:14-4:4: Unexpected verbose conditions object with sole key `default` at `exports`, replace the object with the value at `default`
```Fix:
```diff
@@ -1,7 +1,5 @@
{
- "exports": {
- "default": "./index.js"
- },
+ "exports": "./index.js",
"files": [
"index.js"
],
```### `exports-main-missing`
`package.json`:
```json
{
"exports": {
"./x": "./index.js"
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
1:1-10:2: Unexpected missing main specifier `.`, expected an export to the main module
```Fix:
```diff
@@ -1,5 +1,6 @@
{
"exports": {
+ ".": "./index.js",
"./x": "./index.js"
},
"files": [
```### `exports-negated-missing`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"./*": null
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
4:12-4:16: Unexpected negation specifier `./*` at `exports['./*']` with nothing to negate
```Fix:
```diff
@@ -1,6 +1,7 @@
{
"exports": {
".": "./index.js",
+ "./x": "./index.js",
"./*": null
},
"files": [
```### `exports-object-empty`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"./other": {}
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
4:16-4:18: Unexpected empty object at `exports['./other']` doing nothing, expected fields
```Fix:
```diff
@@ -1,7 +1,6 @@
{
"exports": {
- ".": "./index.js",
- "./other": {}
+ ".": "./index.js"
},
"files": [
"index.js"
```### `exports-object-mixed`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"default": "./other.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
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:
```diff
@@ -1,6 +1,6 @@
{
"exports": {
- ".": "./index.js",
+ "other": "./index.js",
"default": "./other.js"
},
"files": [
```### `exports-path-not-found`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"./x": "./missing.js"
},
"files": [
"index.js",
"missing.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
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`:
```json
{
"exports": "index.js",
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
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:
```diff
@@ -1,5 +1,5 @@
{
- "exports": "index.js",
+ "exports": "./index.js",
"files": [
"index.js"
],
```### `exports-path-wildcard-not-found`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"./*": "./lib/*"
},
"files": [
"lib/",
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
4:12-4:21: Unexpected dynamic file glob `./lib/*` at `exports['./*']` pointing to nothing, expected files
```Fix: make sure files exist.
### `exports-specifier-extension`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"./other.js": "./other.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
2:14-5:4: Unexpected extension `.js` in specifier `./other.js` at `exports`, extensions have no meaning in specifiers, expected `./other`
```Fix:
```diff
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./other.js": "./other.js"
+ "./other": "./other.js"
},
"files": [
"index.js",
```### `exports-specifier-nested`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"./other": {
"./more": "./other.js"
}
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
4:16-6:6: Unexpected nested specifier `./more` at `exports['./other']`, expected conditions
```Fix:
```diff
@@ -1,9 +1,7 @@
{
"exports": {
".": "./index.js",
- "./other": {
- "./more": "./other.js"
- }
+ "./other/more": "./other.js"
},
"files": [
"index.js",
```### `exports-specifier-wildcard-invalid`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"./x/*/y/*": "./other.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
4:18-4:30: Unexpected extra wildcard in dynamic specifier `./x/*/y/*` at `exports['./x/*/y/*']`, one wildcard is allowed
```Fix:
```diff
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./x/*/y/*": "./other.js"
+ "./x/*/y": "./other.js"
},
"files": [
"index.js",
```### `exports-specifier-wildcard-useless`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"./*": "./other.js"
},
"files": [
"index.js",
"other.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
4:12-4:24: Unexpected dynamic specifier `./*` pointing to static file `./other.js` at `exports['./*']`, use dynamic specifiers with dynamic file globs
```Fix:
```diff
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./*": "./other.js"
+ "./other": "./other.js"
},
"files": [
"index.js",
```### `exports-specifiers-verbose`
`package.json`:
```json
{
"exports": {
".": "./index.js"
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
2:14-4:4: Unexpected verbose specifier object with sole key `.` at `exports`, replace the object with the value at `.`
```Fix:
```diff
@@ -1,7 +1,5 @@
{
- "exports": {
- ".": "./index.js"
- },
+ "exports": "./index.js",
"files": [
"index.js"
],
```### `exports-types-verbose`
`package.json`:
```json
{
"exports": {
"types": "./index.d.ts",
"default": "./index.js"
},
"files": [
"index.d.ts",
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
3:14-3:28: Unexpected verbose `types` condition at `exports` matching what TypeScript would load for `default` without it, remove it
```Fix:
```diff
@@ -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`:
```json
{
"exports": {
".": "./index.js",
"./other": 1
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
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:
```diff
+++ b/example/package.json
@@ -1,7 +1,7 @@
{
"exports": {
".": "./index.js",
- "./other": 1
+ "./other": "./other.js"
},
"files": [
"index.js"
```### `files-missing`
`package.json`:
```json
{
"exports": "./index.js",
"name": "x",
"type": "module",
}
```Yields:
```txt
1:1-5:2: Unexpected missing `files` field, expected array of allowed files to include
```Fix:
```diff
@@ -1,5 +1,8 @@
{
"exports": "./index.js",
+ "files": [
+ "index.js"
+ ],
"name": "x",
"type": "module"
}
```### `main`
`package.json`:
```json
{
"files": [
"index.js",
"other.js"
],
"main": "index.js",
"name": "x",
"type": "module"
}
```Yields:
```txt
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:
```diff
@@ -1,9 +1,9 @@
{
+ "exports": "./index.js",
"files": [
"index.js",
"other.js"
],
- "main": "index.js",
"name": "x",
"type": "module"
}
```### `main-extra`
`package.json`:
```json
{
"exports": "./index.js",
"files": [
"index.js"
],
"main": "index.js",
"name": "x",
"type": "module"
}
```Yields:
```txt
6:11-6:21: Unexpected unused legacy `main` field with modern `exports`, remove it
```Fix:
```diff
@@ -3,7 +3,6 @@
"files": [
"index.js"
],
- "main": "index.js",
"name": "x",
"type": "module"
}
```### `main-inferred`
`package.json`:
```json
{
"files": [
"index.js"
],
"name": "x",
"type": "commonjs"
}
```Yields:
```txt
1:1-7:2: Unexpected inferred main export `./index.js`, it’s recommended to use an export map such as `"exports": "./index.js"`
```Fix:
```diff
@@ -1,4 +1,5 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
```### `main-invalid`
`package.json`:
```json
{
"files": [
"index.js"
],
"main": 1,
"name": "x",
"type": "commonjs"
}
```Yields:
```txt
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:
```diff
@@ -1,8 +1,8 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
- "main": 1,
"name": "x",
"type": "commonjs"
}
```### `main-missing`
`package.json`:
```json
{
"files": [
"default.js"
],
"name": "x",
"type": "commonjs"
}
```Yields:
```txt
1:1-7:2: Unexpected missing main module, it’s recommended to use an export map such as `"exports": "./index.js"`
```Fix:
```diff
@@ -1,4 +1,5 @@
{
+ "exports": "./default.js",
"files": [
"default.js"
],
```### `main-not-found`
`package.json`:
```json
{
"files": [
"index.js"
],
"main": "./missing.js",
"name": "x",
"type": "commonjs"
}
```Yields:
```txt
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:
```diff
@@ -1,8 +1,8 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
- "main": "./missing.js",
"name": "x",
"type": "commonjs"
}
```### `main-resolve-commonjs`
`package.json`:
```json
{
"files": [
"index.js"
],
"main": "index",
"name": "x",
"type": "commonjs"
}
```Yields:
```txt
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:
```diff
@@ -1,8 +1,8 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
- "main": "index",
"name": "x",
"type": "commonjs"
}
```### `main-resolve-module`
`package.json`:
```json
{
"files": [
"index.js"
],
"main": "index",
"name": "x",
"type": "module"
}
```Yields:
```txt
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:
```diff
@@ -1,8 +1,8 @@
{
+ "exports": "./index.js",
"files": [
"index.js"
],
- "main": "index",
"name": "x",
"type": "module"
}
```### `name-missing`
`package.json`:
```json
{
"exports": "./index.js",
"files": [
"index.js"
],
"type": "module"
}
```Yields:
```txt
1:1-7:2: Unexpected missing `name` field, expected a package name
```Fix:
```diff
@@ -3,5 +3,6 @@
"files": [
"index.js"
],
+ "name": "x",
"type": "module"
}
```### `npm-ignored`
`package.json`:
```json
{
"exports": {
".": "./index.js",
"./other": "./other.js"
},
"files": [
"index.js"
],
"name": "x",
"type": "module"
}
```Yields:
```txt
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:
```diff
@@ -4,7 +4,8 @@
"./other": "./other.js"
},
"files": [
- "index.js"
+ "index.js",
+ "other.js"
],
"name": "x",
"type": "module"
```### `type-invalid`
`package.json`:
```json
{
"exports": "./index.js",
"files": [
"index.js"
],
"name": "x",
"type": "umd",
}
```Yields:
```txt
7:11-7:16: Unexpected invalid `type` value `umd`, expected `commonjs` or `module`
```Fix:
```diff
@@ -4,5 +4,5 @@
"index.js"
],
"name": "x",
- "type": "umd"
+ "type": "module"
}
```### `type-missing`
`package.json`:
```json
{
"exports": "./index.js",
"files": [
"index.js"
],
"name": "x"
}
```Yields:
```txt
1:1-7:2: Unexpected missing `type` field, expected `type: 'commonjs'` or `'module'`
```Fix:
```diff
@@ -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][open-source-guide-contribute].## License
[MIT][file-license] © [Titus Wormer][wooorm]
[api-package-exports]: #packageexportsfolder
[api-export]: #export
[api-result]: #result
[badge-build-image]: https://github.com/wooorm/package-exports/actions/workflows/main.yml/badge.svg
[badge-build-url]: https://github.com/wooorm/package-exports/actions
[badge-coverage-image]: https://img.shields.io/codecov/c/github/wooorm/package-exports.svg
[badge-coverage-url]: https://codecov.io/github/wooorm/package-exports
[badge-downloads-image]: https://img.shields.io/npm/dm/package-exports.svg
[badge-downloads-url]: https://www.npmjs.com/package/package-exports
[file-license]: license
[github-gist-esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[github-vfile]: https://github.com/vfile/vfile
[npm-install]: https://docs.npmjs.com/cli/install
[open-source-guide-contribute]: https://opensource.guide/how-to-contribute/
[typescript]: https://www.typescriptlang.org
[wooorm]: https://wooorm.com