如何在 Angular 库中添加和安装对等依赖项

How to add and install peer dependencies in Angular library

现在我正在构建 Angular 库来定义可重用组件。 我制作了一个名为 main-layout 的组件。 我需要在组件中使用 ngx-perfect-scrollbar。 我知道如何在 Angular 项目中添加依赖项。

ng add [package name]

npm install [package name]

但是我看到一篇文章说对等依赖是手动添加的。 所以我在我正在开发的库的 package.json 的 peerDependencies 中添加了 ngx-perfect-scrollbar。

之后,我尝试在项目的根目录下安装 npm 包。

npm install

然后我注意到 node_modules 中没有安装 ngx-perfect-scrollbar 包。

下面是我的 angular 库项目的完整结构。

您有 两种方法 将依赖包插入到您的 Angular 库(package.json 文件)并且两者都可以正常工作:

  1. "dependencies"(库会在你安装库的时候自带这个包)
  2. "peerDependencies"(当您将库添加到消费项目中时,系统会警告您必须自己在消费项目中安装此对等依赖项)

哪个最好?

简答

第二个.

长答案

第二个选项是最好的,Angular CLI 建议即使您在 dependencies 而不是 peerDependencies 中定义了包。 这是警告消息 Angular CLI(至少如果你有更新版本的 Angular - 我在写这篇文章时有 12.x )将在构建时显示在控制台中: "Distributing npm packages with不推荐 'dependencies'。请考虑添加到 'peerDependencies' 或从 'dependencies' 中删除它。"

但是,两者之间存在一些差异和取舍,真正由您决定哪个最适合您,但是我肯定会选择第二个选项.

方法 1 - 依赖关系

将简化消费应用程序中的设置,因为您不会看到任何关于对等依赖项的警告,也不需要手动安装依赖项。使用此方法可能遇到的问题是,如果您已经在消费应用程序中使用相同的包,则消费应用程序中可能存在版本冲突。假设您安装了另一个包,它使用相同的对等依赖但版本不同。这种方法也会带来性能问题。

方法 2 - peerDependencies

第二种方法可能是两种方法中最好的,因为您需要做的就是将包添加到 peerDependencies 中,然后当库安装到使用项目中时,您会收到一个很好的警告,提示您需要手动安装对等依赖项。随着应用程序的增长,这种方法通常感觉更好。是的,您会在库安装时收到警告,但您希望尽可能多地控制在长 运行 中使用的应用程序中安装的对等依赖项的版本。您还希望在您的消费应用程序中安装小包。这个选项绝对更安全,也是我选择的选项。

这里有一篇有用的博客也提到了这个话题 https://tomastrajan.medium.com/the-best-way-to-architect-your-angular-libraries-87959301d3d3

有趣的奖金事实

当我学习 Angular 库中的依赖项时,我还发现当您选择上面的选项 #2 (peerDependencies) 时,这并不一定意味着您不需要依赖项在库中可以访问,否则 Typescript 会抱怨找不到类型。

假设您正在以观看模式构建您的图书馆

ng build <name of library> --watch

这意味着如果您没有在 node_modules 文件夹中安装依赖包(在您的库项目文件所在的工作区中),Typescript 将报错并且构建将失败。那么,在这种情况下该怎么办?好吧,对我来说,解决方案也是在 devDependencies 中添加构建库所需的依赖项。这就是我的意思。在撰写本文时,这是我的库 package.json 文件:

"name": "@alexrebula/ngx-giselle-ui",
"version": "0.0.8",
"peerDependencies": {
    "@angular/common": "^12.2.0",
    "@angular/core": "^12.2.0",
    "bulma": "^0.9.3",
    "@fortawesome/angular-fontawesome": "^0.8.2",
    "@fortawesome/fontawesome-free": "^5.15.4",
    "@fortawesome/fontawesome-svg-core": "^1.2.34",
    "@fortawesome/free-brands-svg-icons": "^5.15.2",
    "@fortawesome/free-regular-svg-icons": "^5.15.2",
    "@fortawesome/free-solid-svg-icons": "^5.15.2",
    "@googlemaps/markerclustererplus": "^1.2.0",
    "googlemaps-ts-rich-marker": "0.0.4"
},
"dependencies": {
    "tslib": "^2.3.0"
},
"devDependencies": {
    "@types/googlemaps": "^3.43.3",
    "@fortawesome/angular-fontawesome": "^0.8.2",
    "@fortawesome/fontawesome-free": "^5.15.4",
    "@fortawesome/fontawesome-svg-core": "^1.2.34",
    "@fortawesome/free-brands-svg-icons": "^5.15.2",
    "@fortawesome/free-regular-svg-icons": "^5.15.2",
    "@fortawesome/free-solid-svg-icons": "^5.15.2",
    "@googlemaps/markerclustererplus": "^1.2.0",
    "googlemaps-ts-rich-marker": "0.0.4"
}

看看我是如何在 devDepencencies 中复制 peerDependencies 的?当然 Bulma(一个 CSS 框架)除外,因为没有 CSS 不会破坏库编译,我只需要在消费应用程序中安装 Bulma。

学分和贡献

如果您想试用此研究案例、查看代码或什至在这条学习路径上与我合作,我建议您继续 https://www.npmjs.com/package/@alexrebula/ngx-giselle-ui and https://github.com/AlexRebula/GiselleUI。任何对我在我的图书馆里写的或做的东西的评论或反馈都将不胜感激,特别是如果你认为我在我的发现路径上的某个地方犯了错误。谢谢!