关于 Spartacus 开源项目的 peerDependencies
ng new app 生成的 Angular 应用,自带11个依赖:
使用 Schematics 安装了 library 之后的客户 Storefront:
本地新建一个空的文件夹,在里面执行命令行:npm i @spartacus/storefront
里面只有一个 node_modules 文件夹,里面包含了很多 js 文件和 TypeScript 的 .d.ts 文件:
这个 @Spartacus/storefront 的 package.json 里,仍旧只有一个 tslib 的 dependencies:
但是 peerDependencies
里,包含了不少在 Spartacus 项目源代码 package.json 里定义的 dependencies
:
"peerDependencies": {
"@angular/common": "^12.0.5",
"@angular/core": "^12.0.5",
"@angular/forms": "^12.0.5",
"@angular/platform-browser": "^12.0.5",
"@angular/router": "^12.0.5",
"@angular/service-worker": "^12.0.5",
"@ng-bootstrap/ng-bootstrap": "^10.0.0",
"@ng-select/ng-select": "^7.0.1",
"@ngrx/effects": "^12.1.0",
"@ngrx/router-store": "^12.1.0",
"@ngrx/store": "^12.1.0",
"@spartacus/core": "4.3.1",
"ngx-infinite-scroll": "^8.0.0",
"rxjs": "^6.6.0"
},
npm 很好地处理了子依赖关系:如果我的包依赖于 request 版本 2 和其他库,但其他库依赖于 request 版本 1,则生成的依赖关系图如下所示:
这通常很棒:现在 some-other-library 拥有自己的请求 v1 副本,它可以使用它,同时不会干扰我的包的 v2 副本。
但是,有一个用例会失败:插件(plugin)。 插件包旨在与另一个 host 包一起使用,即使它并不总是直接使用 host 包。 Node.js 包生态系统中已经有很多这种模式的例子:
- Grunt plugins
- Chai plugins
- LevelUP plugins
- Express middleware
- Winston transports
从本质上讲,插件旨在与主机包一起使用。 但更重要的是,它们旨在与特定版本的主机包一起使用。 例如,我的 chai-as-promised 插件的 1.x 和 2.x 版本适用于 chai 0.5 版,而 3.x 版适用于 chai 1.x。 另一个例子是 grunt. 0.3.1 版的 grunt-contrib-stylus 可以与 grunt 0.4.0rc4 一起使用,但由于删除了 API,在与 grunt 0.4.0rc5 一起使用时会中断。
假设 plugin 显式声明了 host package 的版本号,即使对于确实具有这种直接依赖关系的插件,可能是由于主机包提供了实用程序 API,在插件的 package.json 中指定依赖项也会导致依赖关系树包含主机包的多个副本。例如,假设 winston-mail 0.2.3 在其 dependencies 中指定了 winston: 0.5.x,因为这是对其进行测试的最新版本。
作为应用程序开发人员,使用了 winston 的最新版本 0.6, 将它们放在 package.json 中:
一旦运行 npm install
后,产生 winston 的两份不同的版本:
这种问题的解决方案就是 peerDependencies
.
peerDependencies 使用起来非常简单。 在编写 plugin 时,请确定 peerDependencies 的 host package 的版本,并将其添加到 package.json 中:
{
"name": "chai-as-promised",
"peerDependencies": {
"chai": "1.x"
}
}
现在,当安装 chai-as-promised 时,chai 包将随之被安装。
如果稍后尝试安装另一个仅适用于 0.x 版本的 Chai 的 Chai 插件,将收到错误消息。
相关文章
- BroadLeaf项目集成SolrCloud
- 开源项目使用及选型
- 关于个人开源项目(vue app)的一些总结
- N-Tier Entity Framework开源项目介绍
- Laravel 中使用 swoole 项目实战开发案例二 (后端主动分场景给界面推送消息)
- 开源夜聊栏目开播:聊聊新晋 CNCF 项目 sealer 背后的故事
- 一不小心,它成为了 GitHub Alibaba Group 下 Star 最多的开源项目
- 如何参与一个GitHub开源项目
- Linux 命令多到记不住?这个开源项目帮你一网打尽!
- 开源:Angularjs示例--Sonar中项目使用语言分布图(CoffeeScript版)
- Git项目使用总结
- SAP Spartacus 开源项目里 activeCartId$ 的实现
- .NET平台开源项目速览(13)机器学习组件Accord.NET框架功能介绍
- atitit 面试问题表 侧重于项目和业务描述方面.v2 良好的标准:: 1.回答问题比较流畅,较少出现停顿现象,较少犹豫 2.回答有条理清晰 不杂乱 3.回答较为丰富内容 4.精神状态紧张
- 参加 Spartacus 开源项目开发时需要注意的一些编程规范
- 有哪些优秀的Android开源项目最值得阅读?这里Android中近百个优秀开源库,包你提高效率
- 【项目实战】使用Maven插件(jacoco-maven-plugin),实现生成代码覆盖率报告
- Python编程:pipenv管理项目虚拟环境
- 开源服务发现项目Zookeeper,Doozer,Etcd
- kurento + nodejs 开源项目 webRTC 转成 RTMP输出
- OpenMLDB 获评 CSDN IT 技术影响力之星 “年度开源项目”奖项
- Android 开源项目android-open-project解析之(三) ScrollView,TimeView,TipView,FlipView
- 【Android开发经验】移动设备的“声波通信/验证”的实现——SinVoice开源项目介绍(一)
- 如何建立一个完美的 Python 项目 | 干货
- 腾讯两大开源项目Tars、TSeer
- Django(2)-创建项目及默认项目目录结构介绍
- 【项目实战】SQL入门知识 - DML 和 DDL
- 【项目实战】Redis使用场景之待支付订单自动取消、订单自动收货
- Code blocks创建项目