@es-joy/resolve.exports

中文文档
1.2.0发布于 2025/10/29MITTypeScriptESM + CJS零依赖近 30 天下载 1637.9万

微小(952b),正确,通用,可配置的"出口"和"进口"解析器,不依赖文件系统

中文使用文档
文档目录10 节
  1. 安装
  2. 使用量
  3. API 密码
  4. 解析( pkg, 条目?, 选项 ?)
  5. 导出( pkg, 条目, 选项 )
  6. 进口(pkg、目标、选项? )
  7. 选项
  8. 遗产解决器
  9. 遗留( pkg, 选项)
  10. 许可证

@es-joy/resolve.exports (中文(简体) ) CI licenses codecov

微小(952b),正确、通用和可配置 "exports" 财务报告和审定财务报表 "imports" 没有文件系统依赖的解析器

为什么?

希望这一模块可作为参照点(和/或直接使用),使生态系统内的各种工具和捆绑器能够相互分享共同办法 以及 与本地节点.js的执行.

随着对无害环境管理的推动,我们必须 非常喜欢 注意并避免分裂。 如果我们作为一个社区 开始宣传不同的 方言 解析算法,然后我们走向深渊。 它将提供支持(和使用) "exports" 几乎不可能,这可能会迫使它放弃, 伴随着它,它的好处.

让我们有美好的事物.

安装

$ npm install @es-joy/resolve.exports

使用量

请看 /test/ 用于实例.

import * as resolve from '@es-joy/resolve.exports';

// package.json contents
const pkg = {
  "name": "foobar",
  "module": "dist/module.mjs",
  "main": "dist/require.js",
  "imports": {
    "#hash": {
      "import": {
        "browser": "./hash/web.mjs",
        "node": "./hash/node.mjs",
      },
      "default": "./hash/detect.js"
    }
  },
  "exports": {
    ".": {
      "import": "./dist/module.mjs",
      "require": "./dist/require.js"
    },
    "./lite": {
      "worker": {
        "browser": "./lite/worker.browser.js",
        "node": "./lite/worker.node.js"
      },
      "import": "./lite/module.mjs",
      "require": "./lite/require.js"
    }
  }
};

// ---
// Exports
// ---

// entry: "foobar" === "." === default
// conditions: ["default", "import", "node"]
resolve.exports(pkg);
resolve.exports(pkg, '.');
resolve.exports(pkg, 'foobar');
//=> ["./dist/module.mjs"]

// entry: "foobar/lite" === "./lite"
// conditions: ["default", "import", "node"]
resolve.exports(pkg, 'foobar/lite');
resolve.exports(pkg, './lite');
//=> ["./lite/module.mjs"]

// Enable `require` condition
// conditions: ["default", "require", "node"]
resolve.exports(pkg, 'foobar', { require: true }); //=> ["./dist/require.js"]
resolve.exports(pkg, './lite', { require: true }); //=> ["./lite/require.js"]

// Throws "Missing <entry> specifier in <name> package" Error
resolve.exports(pkg, 'foobar/hello');
resolve.exports(pkg, './hello/world');

// Add custom condition(s)
// conditions: ["default", "worker", "import", "node"]
resolve.exports(pkg, 'foobar/lite', {
  conditions: ['worker']
}); //=> ["./lite/worker.node.js"]

// Toggle "browser" condition
// conditions: ["default", "worker", "import", "browser"]
resolve.exports(pkg, 'foobar/lite', {
  conditions: ['worker'],
  browser: true
}); //=> ["./lite/worker.browser.js"]

// ---
// Types-only resolution
// ---

// Find only `types` entries (or its synonym `typings`), even when nested under
//   conditions like `import`/`require`
// Defaults to following the active branch (`import` by default, `require` when set)
resolve.types({
  name: 'pkg',
  exports: {
    '.': {
      import: { types: './index.d.ts', default: './index.mjs' },
      require: { types: './index.cjs.d.ts', default: './index.cjs' }
    }
  }
});
//=> ["./index.d.ts"]

resolve.types({
  name: 'pkg',
  exports: {
    '.': {
      import: { types: './index.d.ts', default: './index.mjs' },
      require: { types: './index.cjs.d.ts', default: './index.cjs' }
    }
  }
}, '.', { require: true });
//=> ["./index.cjs.d.ts"]

// Disable non-"default" condition activate
// NOTE: breaks from Node.js default behavior
// conditions: ["default", "custom"]
resolve.exports(pkg, 'foobar/lite', {
  conditions: ['custom'],
  unsafe: true,
});
//=> Error: No known conditions for "./lite" specifier in "foobar" package

// ---
// Imports
// ---

// conditions: ["default", "import", "node"]
resolve.imports(pkg, '#hash');
resolve.imports(pkg, 'foobar/#hash');
//=> ["./hash/node.mjs"]

// conditions: ["default", "import", "browser"]
resolve.imports(pkg, '#hash', { browser: true });
resolve.imports(pkg, 'foobar/#hash');
//=> ["./hash/web.mjs"]

// conditions: ["default"]
resolve.imports(pkg, '#hash', { unsafe: true });
resolve.imports(pkg, 'foobar/#hash');
//=> ["./hash/detect.mjs"]

resolve.imports(pkg, '#hello/world');
resolve.imports(pkg, 'foobar/#hello/world');
//=> Error: Missing "#hello/world" specifier in "foobar" package

// ---
// Legacy
// ---

// prefer "module" > "main" (default)
resolve.legacy(pkg); //=> "dist/module.mjs"

// customize fields order
resolve.legacy(pkg, {
  fields: ['main', 'module']
}); //=> "dist/require.js"

API 密码

这个 resolve(), (中文(简体) ), exports(),以及 imports() 函数共享类似的 API 签名 :

export function resolve(pkg: Package, entry?: string, options?: Options): string[] | undefined;
export function exports(pkg: Package, entry?: string, options?: Options): string[] | undefined;
export function imports(pkg: Package, target: string, options?: Options): string[] | undefined;
export function types(pkg: Package, entry?: string, options?: Options): string[] | undefined;
//                                         ^ not optional!

所有三个:

  • 接受一个 package.json 文件内容为 JSON 对象
  • 接受目标/条目标识符
  • 可能接受 选项 对象
  • 返回时 string[], (中文(简体) ), string,或 undefined

唯一的区别是 imports() 必须接受目标标识符,因为无法推断出默认值.

API的进一步说明见下文.

说明: 还有一个 遗产解析器 API


解析( pkg, 条目?, 选项 ?)

回返情况: string[] 或者说 undefined

自动改道的便利助手 exports() 或者说 imports() 取决于 entry 数值.

当未说明时, entry 默认为 "." 标识符,这意味着 exports() 将被援引.

import * as r from '@es-joy/resolve.exports';

let pkg = {
  name: 'foobar',
  // ...
};

r.resolve(pkg);
//~> r.exports(pkg, '.');

r.resolve(pkg, 'foobar');
//~> r.exports(pkg, '.');

r.resolve(pkg, 'foobar/subpath');
//~> r.exports(pkg, './subpath');

r.resolve(pkg, '#hash/md5');
//~> r.imports(pkg, '#hash/md5');

r.resolve(pkg, 'foobar/#hash/md5');
//~> r.imports(pkg, '#hash/md5');

导出( pkg, 条目, 选项 )

回返情况: string[] 或者说 undefined

翻转 "exports" 内容 package.json 文档.
如果内容 没有 包含一个 "exports" 地图,然后 undefined 将返回.

成功的决议将永远导致 string 或者说 string[] 数值。 这将是已解析的映射本身的价值 — 这意味着输出是一个相对文件路径 .

3⁄4 ̄ ̧漯B

  • 请求 entry 无法解决(aka, 未在 "exports" 地图)
  • a 一个 entry 实值 定义,但没有匹配已知条件(见 options.conditions(中文(简体) )

pkg (英语)

类型 : object
要求 : true

这个 package.json 目录.

条目

类型 : string
要求 : false
默认 : . (aka,根也

想要的目标条目,或原条目 import 路径.

何时 entry 没有 相对路径( aka, 不从 '.',则 entry 给出 './' 前缀.

何时 entry 开始于软件包名称(通过 pkg.name 值),则 entry 被截断和相对.

何时 entry 已经是相对的,它已被接受.

实例

假设我们有一个名为"foobar"的模块 pkg 包含 "name": "foobar"。 。 。 .

entry 价值被视为原因
null 编号 : undefined'.'默认
'.''.'值是相对的
'foobar''.'数值为 pkg.name
'foobar/lite''./lite'数值 pkg.name 前缀
'./lite''./lite'值是相对的
'lite''./lite'值不是相对的( d) pkg.name 前缀

进口(pkg、目标、选项? )

回返情况: string[] 或者说 undefined

翻转 "imports" 内容 package.json 文档.
如果内容 没有 包含一个 "imports" 地图,然后 undefined 将返回.

成功的决议将永远导致 string 或者说 string[] 数值。 这将是已解析的映射本身的价值 — 这意味着输出是一个相对文件路径 .

3⁄4 ̄ ̧漯B

  • 请求 target 无法解决(aka, 未在 "imports" 地图)
  • a 一个 target 实值 定义,但没有匹配已知条件(见 options.conditions(中文(简体) )

pkg (英语)

类型 : object
要求 : true

这个 package.json 目录.

目标

类型 : string
要求 : true

目标导入标识符;例如, #hash 或者说 #hash/md5。 。 。 .

导入规格 必须 从 # 字符,根据决议规格的要求。 然而,如果 target 软件包名称(由 pkg.name 值),则 resolve.exports 会修剪它从 target 标识符。 譬如说, "foobar/#hash/md5" 将被视为 "#hash/md5" 联 合 国 "foobar" 软件包.

选项

这个 resolve(), (中文(简体) ), imports(),以及 exports() 函数共享这些选项。 所有属性都是可选的,不需要通过 options 参数.

集体而言 options 用于组装列表 条件 ,应在解决目标时激活.

说明: 尽管Node.js文档主要展现了同时存在的条件 "exports" 使用,它们也适用于: "imports" 还有地图. (单位:千美元)实例(中文(简体) )

选项。要求

类型 : boolean
默认 : false

当真理 "require" 字段将添加到允许/已知条件列表中.
否则 "import" 字段改为添加字段.

选项。浏览器

类型 : boolean
默认 : false

当真理 "browser" 字段将添加到允许/已知条件列表中.
否则 "node" 字段改为添加字段.

选项。条件

类型 : string[]
默认 : []

列出在看到时应予接受的额外/海关条件.

重要内容: 所指定的顺序 options.conditions 没关系.
匹配顺序/优先级为 永远 由《公约》缔约方会议 "exports" 地图的关键顺序 .

例如,您可以选择接受 "production" 在某些环境中的状况。 鉴于以下各点: pkg 内容 :

const pkg = {
  // package.json ...
  "exports": {
    "worker": "./$worker.js",
    "require": "./$require.js",
    "production": "./$production.js",
    "import": "./$import.mjs",
  }
};

resolve.exports(pkg, '.');
// Conditions: ["default", "import", "node"]
//=> ["./$import.mjs"]

resolve.exports(pkg, '.', {
  conditions: ['production']
});
// Conditions: ["default", "production", "import", "node"]
//=> ["./$production.js"]

resolve.exports(pkg, '.', {
  conditions: ['production'],
  require: true,
});
// Conditions: ["default", "production", "require", "node"]
//=> ["./$require.js"]

resolve.exports(pkg, '.', {
  conditions: ['production', 'worker'],
  require: true,
});
// Conditions: ["default", "production", "worker", "require", "node"]
//=> ["./$worker.js"]

resolve.exports(pkg, '.', {
  conditions: ['production', 'worker']
});
// Conditions: ["default", "production", "worker", "import", "node"]
//=> ["./$worker.js"]

如果你想删除一个条件,你可以使用 ! 前缀。 比如说,你只需要 "types"数字 :

resolve.exports(pkg, '.', {
  conditions: ['!default', '!import', '!node', 'types']
});
// Conditions: ["types"]

选项。不安全

类型 : boolean
默认 : false

重要内容: 你可能不想要这个选项!
它会突破出节点的默认解析条件.

启用时, 此选项将忽略 所有其他选项 除外 options.conditions。这是因为,当启用时, options.unsafe 没有 假设或提供任何默认条件,但 "default" 条件.

resolve.exports(pkg, '.');
//=> Conditions: ["default", "import", "node"]

resolve.exports(pkg, '.', { unsafe: true });
//=> Conditions: ["default"]

resolve.exports(pkg, '.', { unsafe: true, require: true, browser: true });
//=> Conditions: ["default"]

换句话说,这意味着试图使用 options.require 或者说 options.browser 并行 options.unsafe 没有效果。 为了提供这些条件,您必须手动提供这些条件 options.conditions 列表 :

resolve.exports(pkg, '.', {
  unsafe: true,
  conditions: ["require"]
});
//=> Conditions: ["default", "require"]

resolve.exports(pkg, '.', {
  unsafe: true,
  conditions: ["browser", "require", "custom123"]
});
//=> Conditions: ["default", "browser", "require", "custom123"]

遗产解决器

还包括一种“遗产”方法来解决非"exports" 软件包字段。 当无时,可将其作为后退方法 "exports" 绘图是定义的。 换句话说,它是完全可选的(和可被树震动的).

遗留( pkg, 选项)

回返情况: string 或者说 undefined

您可以通过 options.fields。 。 。 .

当找到字段时, 返回其值 已写入。 。 。 .
当找不到地时, undefined 已返回。 如果你想模仿Node.js的行为 你可以假设这意味着 'index.js' - 但是这个模块并没有给你这个假设.

选项。浏览器

类型 : boolean 或者说 string
默认 : false

当真相发生时,确保 'browser' 字段是可接受 fields 列表中选择一个选项.

重要内容: 如果你的习惯 options.fields 值包括 'browser',则  秩序受到尊重.
否则,当真理, options.browser 将移动 'browser' 将它作为首要任务.

何时 true 财务报告和审定财务报表 "browser" 是一个对象,然后 legacy() {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}会把全部还回来 "browser" 对象.

您也可以通过字符串值,该值将作为导入/文件路径处理。 如果是这样 "browser" 是一个对象,然后 legacy() 可返回 :

  • false - 如果软件包作者决定忽略文件;或
  •  options.browser 字符串值 - 但已相对, 如果还没有

见 “浏览器”字段规格 更多信息.

选项。 字段

类型 : string[]
默认 : ['module', 'main']

要接受的字段列表 。 数组的顺序决定了每个字段的优先顺序/重要性,列表开头有最重要的字段.

默认情况下 legacy() 方法将接受任何 "module" 和/或“主”字段,如果它们被定义。 然而,如果两个字段都有定义,则会返回"模块".

import { legacy } from '@es-joy/resolve.exports';

// package.json
const pkg = {
  "name": "...",
  "worker": "worker.js",
  "module": "module.mjs",
  "browser": "browser.js",
  "main": "main.js",
};

legacy(pkg);
// fields = [module, main]
//=> "module.mjs"

legacy(pkg, { browser: true });
// fields = [browser, module, main]
//=> "browser.mjs"

legacy(pkg, {
  fields: ['missing', 'worker', 'module', 'main']
});
// fields = [missing, worker, module, main]
//=> "worker.js"

legacy(pkg, {
  fields: ['missing', 'worker', 'module', 'main'],
  browser: true,
});
// fields = [browser, missing, worker, module, main]
//=> "browser.js"

legacy(pkg, {
  fields: ['module', 'browser', 'main'],
  browser: true,
});
// fields = [module, browser, main]
//=> "module.mjs"

许可证

麻省理工学院

版本与发布记录

@es-joy/resolve.exports 共发布 3 个版本,首次发布于 2025/10/24;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.2.0latest2025/10/291 年前
1.1.02025/10/291 年前
1.0.02025/10/241.1 年前

关于 @es-joy/resolve.exports 的常见问题

@es-joy/resolve.exports 是什么?

微小(952b),正确,通用,可配置的"出口"和"进口"解析器,不依赖文件系统

如何安装 @es-joy/resolve.exports?

在项目目录运行 npm install @es-joy/resolve.exports,或使用 pnpm add / yarn add / bun add。

@es-joy/resolve.exports 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@es-joy/resolve.exports 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@es-joy/resolve.exports 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=10。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@es-joy/resolve.exports 可以商用吗?

@es-joy/resolve.exports 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@es-joy/resolve.exports 的下载量有多少?

根据 npm 官方下载统计,@es-joy/resolve.exports 在 2026/10/14 – 2026/11/12 这 30 天内被下载 16,378,509 次,日均约 545,950 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@es-joy/resolve.exports 还在维护吗?

最新版本 1.2.0 发布于 2025/10/29(1 年前);至今共发布 3 个版本,其中过去 12 个月发布了 0 个;首次发布于 2025/10/24。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。