NodeJS 中的“子路径模式”是什么

alt*_*3en 6 javascript module node.js node-modules angular

在阅读有关 Angular 13 新增功能的博客时,我遇到了以下声明:

由于 Angular 包使用具有子路径模式的 Node.js 包导出功能,因此不再支持 v12.20 之前的 Node.js 版本。

那么,我想知道“子路径模式”是什么意思?这里的例子将非常受欢迎。

Mah*_*rei 9

我引用了nodejs.org

子路径模式

添加于:v14.13.0、v12.20.0

对于具有少量导出或导入的包,我们建议显式列出每个导出子路径条目。但对于具有大量子路径的包,这可能会导致package.json膨胀和维护问题。

对于这些用例,可以使用子路径导出模式:

// ./node_modules/es-module-package/package.json
{
  "exports": {
    "./features/*": "./src/features/*.js"
  },
  "imports": {
    "#internal/*": "./src/internal/*.js"
  }
}
Run Code Online (Sandbox Code Playgroud)

*映射公开嵌套子路径,因为它只是字符串替换语法。

*右侧的所有实例都将替换为该值,包括它是否包含任何 / 分隔符。

import featureX from 'es-module-package/features/x';
// Loads ./node_modules/es-module-package/src/features/x.js

import featureY from 'es-module-package/features/y/y';
// Loads ./node_modules/es-module-package/src/features/y/y.js

import internalZ from '#internal/z';
// Loads ./node_modules/es-module-package/src/internal/z.js
Run Code Online (Sandbox Code Playgroud)

这是直接静态替换,无需对文件扩展名进行任何特殊处理。在前面的示例中,将在映射中pkg/features/x.json解析。./src/features/x.json.js

导出的静态可枚举属性由导出模式维护,因为可以通过将右侧目标模式视为包内**文件列表的全局来确定包的各个导出。由于node_modules导出目标中禁止使用路径,因此这种扩展仅依赖于包本身的文件。

要从模式中排除私有子文件夹,null可以使用目标:

// ./node_modules/es-module-package/package.json
{
  "exports": {
    "./features/*": "./src/features/*.js",
    "./features/private-internal/*": null
  }
}
Run Code Online (Sandbox Code Playgroud)
import featureInternal from 'es-module-package/features/private-internal/m';
// Throws: ERR_PACKAGE_PATH_NOT_EXPORTED

import featureX from 'es-module-package/features/x';
// Loads ./node_modules/es-module-package/src/features/x.js
Run Code Online (Sandbox Code Playgroud)

更新(2023 年 8 月 15 日)

对cmcdragonkai评论的回应,引用自Medium (Maksim Zemskov):

package.json要配置路径别名,您可以按照文档中的说明添加几行。例如,如果您想允许相对于src目录导入,请将以下导入字段添加到package.json

{
    "name": "my-awesome-project",
    "imports": {
        "#*": "./src/*"
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用配置的别名,导入可以这样写:

import { apiClient } from '#shared/api';
import { ProductView } from '#entities/product/components/ProductView';
import { addProductToCart } from '#features/add-to-cart/actions';
Run Code Online (Sandbox Code Playgroud)