Gathering detailed insights and metrics for package-exports-resolver-kernel
Gathering detailed insights and metrics for package-exports-resolver-kernel
Gathering detailed insights and metrics for package-exports-resolver-kernel
Gathering detailed insights and metrics for package-exports-resolver-kernel
jest-pnp-resolver
plug'n'play resolver for Webpack
pnp-webpack-plugin
plug'n'play resolver for Webpack
@aws-sdk/region-config-resolver
[![NPM version](https://img.shields.io/npm/v/@aws-sdk/region-config-resolver/latest.svg)](https://www.npmjs.com/package/@aws-sdk/region-config-resolver) [![NPM downloads](https://img.shields.io/npm/dm/@aws-sdk/region-config-resolver.svg)](https://www.npmj
@stoplight/spectral-ref-resolver
This package provides Spectral-compatible bindings for [@stoplight/json-ref-resolver](https://github.com/stoplightio/json-ref-resolver) and [@stoplight/json-ref-readers](https://github.com/stoplightio/json-ref-readers).
A general-purpose package.json "exports" resolver without file-system reliance.
npm install package-exports-resolver-kernel
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
13 Commits
2 Watching
2 Branches
1 Contributors
Updated on 23 Dec 2022
Minified
Minified + Gzipped
TypeScript (99.83%)
Shell (0.17%)
Cumulative downloads
Total Downloads
Last day
300%
4
Compared to previous day
Last week
200%
30
Compared to previous week
Last month
227.3%
72
Compared to previous month
Last year
-7.1%
639
Compared to previous year
21
A tiny (737b), correct, general-purpose, and configurable
"exports"
resolver without file-system reliance
Why?
Hopefully, this module may serve as a reference point (and/or be used directly) so that the varying tools and bundlers within the ecosystem can share a common approach with one another as well as with the native Node.js implementation.
With the push for ESM, we must be very careful and avoid fragmentation. If we, as a community, begin propagating different dialects of "exports"
resolution, then we're headed for deep trouble. It will make supporting (and using) "exports"
nearly impossible, which may force its abandonment and along with it, its benefits.
Let's have nice things.
TODO
./foobar/
=> /foobar/
)./foobar/*
=> ./other/*.js
)main
vs module
vs ...)1$ npm install package-exports-resolver-kernel
Please see
/test/
for examples.
1import { resolve, legacy } from 'resolve.exports'; 2 3const contents = { 4 "name": "foobar", 5 "module": "dist/module.mjs", 6 "main": "dist/require.js", 7 "exports": { 8 ".": { 9 "import": "./dist/module.mjs", 10 "require": "./dist/require.js" 11 }, 12 "./lite": { 13 "worker": { 14 "browser": "./lite/worker.brower.js", 15 "node": "./lite/worker.node.js" 16 }, 17 "import": "./lite/module.mjs", 18 "require": "./lite/require.js" 19 } 20 } 21}; 22 23// Assumes `.` as default entry 24// Assumes `import` as default condition 25resolve(contents); //=> "./dist/module.mjs" 26 27// entry: nullish === "foobar" === "." 28resolve(contents, 'foobar'); //=> "./dist/module.mjs" 29resolve(contents, '.'); //=> "./dist/module.mjs" 30 31// entry: "foobar/lite" === "./lite" 32resolve(contents, 'foobar/lite'); //=> "./lite/module.mjs" 33resolve(contents, './lite'); //=> "./lite/module.mjs" 34 35// Assume `require` usage 36resolve(contents, 'foobar', { require: true }); //=> "./dist/require.js" 37resolve(contents, './lite', { require: true }); //=> "./lite/require.js" 38 39// Throws "Missing <entry> export in <name> package" Error 40resolve(contents, 'foobar/hello'); 41resolve(contents, './hello/world'); 42 43// Add custom condition(s) 44resolve(contents, 'foobar/lite', { 45 conditions: ['worker'] 46}); // => "./lite/worker.node.js" 47 48// Toggle "browser" condition 49resolve(contents, 'foobar/lite', { 50 conditions: ['worker'], 51 browser: true 52}); // => "./lite/worker.browser.js" 53 54// --- 55// Legacy 56// --- 57 58// prefer "module" > "main" (default) 59legacy(contents); //=> "dist/module.mjs" 60 61// customize fields order 62legacy(contents, { 63 fields: ['main', 'module'] 64}); //=> "dist/require.js"
Returns: string
or undefined
Traverse the "exports"
within the contents of a package.json
file.
If the contents does not contain an "exports"
map, then undefined
will be returned.
Successful resolutions will always result in a string value. This will be the value of the resolved mapping itself – which means that the output is a relative file path.
This function may throw an Error if:
entry
cannot be resolved (aka, not defined in the "exports"
map)entry
was resolved but no known conditions were found (see options.conditions
)Type: object
Required: true
The package.json
contents.
Type: string
Required: false
Default: .
(aka, root)
The desired target entry, or the original import
path.
When entry
is not a relative path (aka, does not start with '.'
), then entry
is given the './'
prefix.
When entry
begins with the package name (determined via the pkg.name
value), then entry
is truncated and made relative.
When entry
is already relative, it is accepted as is.
Examples
Assume we have a module named "foobar" and whose pkg
contains "name": "foobar"
.
entry value | treated as | reason |
---|---|---|
null / undefined | '.' | default |
'.' | '.' | value was relative |
'foobar' | '.' | value was pkg.name |
'foobar/lite' | './lite' | value had pkg.name prefix |
'./lite' | './lite' | value was relative |
'lite' | './lite' | value was not relative & did not have pkg.name prefix |
Type: boolean
Default: false
When truthy, the "require"
field is added to the list of allowed/known conditions.
When falsey, the "import"
field is added to the list of allowed/known conditions instead.
Type: boolean
Default: false
When truthy, the "browser"
field is added to the list of allowed/known conditions.
Type: string[]
Default: []
Provide a list of additional/custom conditions that should be accepted when seen.
Important: The order specified within
options.conditions
does not matter.
The matching order/priority is always determined by the"exports"
map's key order.
For example, you may choose to accept a "production"
condition in certain environments. Given the following pkg
content:
1const contents = { 2 // ... 3 "exports": { 4 "worker": "./index.worker.js", 5 "require": "./index.require.js", 6 "production": "./index.prod.js", 7 "import": "./index.import.mjs", 8 } 9}; 10 11resolve(contents, '.'); 12//=> "./index.import.mjs" 13 14resolve(contents, '.', { 15 conditions: ['production'] 16}); //=> "./index.prod.js" 17 18resolve(contents, '.', { 19 conditions: ['production'], 20 require: true, 21}); //=> "./index.require.js" 22 23resolve(contents, '.', { 24 conditions: ['production', 'worker'], 25 require: true, 26}); //=> "./index.worker.js" 27 28resolve(contents, '.', { 29 conditions: ['production', 'worker'] 30}); //=> "./index.worker.js"
Type: boolean
Default: false
Important: You probably do not want this option!
It will break out of Node's default resolution conditions.
When enabled, this option will ignore all other options except options.conditions
. This is because, when enabled, options.unsafe
does not assume or provide any default conditions except the "default"
condition.
1resolve(contents); 2//=> Conditions: ["default", "import", "node"] 3 4resolve(contents, { unsafe: true }); 5//=> Conditions: ["default"] 6 7resolve(contents, { unsafe: true, require: true, browser: true }); 8//=> Conditions: ["default"]
In other words, this means that trying to use options.require
or options.browser
alongside options.unsafe
will have no effect. In order to enable these conditions, you must provide them manually into the options.conditions
list:
1resolve(contents, { 2 unsafe: true, 3 conditions: ["require"] 4}); 5//=> Conditions: ["default", "require"] 6 7resolve(contents, { 8 unsafe: true, 9 conditions: ["browser", "require", "custom123"] 10}); 11//=> Conditions: ["default", "browser", "require", "custom123"]
Returns: string
or undefined
Also included is a "legacy" method for resolving non-"exports"
package fields. This may be used as a fallback method when for when no "exports"
mapping is defined. In other words, it's completely optional (and tree-shakeable).
You may customize the field priority via options.fields
.
When a field is found, its value is returned as written.
When no fields were found, undefined
is returned. If you wish to mimic Node.js behavior, you can assume this means 'index.js'
– but this module does not make that assumption for you.
Type: boolean
or string
Default: false
When truthy, ensures that the 'browser'
field is part of the acceptable fields
list.
Important: If your custom
options.fields
value includes'browser'
, then your order is respected.
Otherwise, when truthy,options.browser
will move'browser'
to the front of the list, making it the top priority.
When true
and "browser"
is an object, then legacy()
will return the the entire "browser"
object.
You may also pass a string value, which will be treated as an import/file path. When this is the case and "browser"
is an object, then legacy()
may return:
false
– if the package author decided a file should be ignored; oroptions.browser
string value – but made relative, if not alreadySee the `"browser" field specification for more information.
Type: string[]
Default: ['module', 'main']
A list of fields to accept. The order of the array determines the priority/importance of each field, with the most important fields at the beginning of the list.
By default, the legacy()
method will accept any "module"
and/or "main" fields if they are defined. However, if both fields are defined, then "module" will be returned.
1const contents = { 2 "name": "...", 3 "worker": "worker.js", 4 "module": "module.mjs", 5 "browser": "browser.js", 6 "main": "main.js", 7} 8 9legacy(contents); 10// fields = [module, main] 11//=> "module.mjs" 12 13legacy(contents, { browser: true }); 14// fields = [browser, module, main] 15//=> "browser.mjs" 16 17legacy(contents, { 18 fields: ['missing', 'worker', 'module', 'main'] 19}); 20// fields = [missing, worker, module, main] 21//=> "worker.js" 22 23legacy(contents, { 24 fields: ['missing', 'worker', 'module', 'main'], 25 browser: true, 26}); 27// fields = [browser, missing, worker, module, main] 28//=> "browser.js" 29 30legacy(contents, { 31 fields: ['module', 'browser', 'main'], 32 browser: true, 33}); 34// fields = [module, browser, main] 35//=> "module.mjs"
MIT © David Geo Holmes MIT © Luke Edwards
No vulnerabilities found.
No security vulnerabilities found.