如何在不接受 Atlassian 设计指南许可的情况下使用 npm 包的替代实现来使用 Atlaskit

How to use alternative implementation for npm packages to use Atlaskit without accepting Atlassian Design Guidelines License

大部分 Atlaskit 编辑器都使用 MIT 或 Apache 2.0 许可证。我试图弄清楚在不接受非自由(如自由)Atlassian 设计指南许可(ADG 许可)的情况下应该如何使用 Atlaskit,该许可用于软件包 @atlaskit/icon@atlaskit/icon-file-type@atlaskit/icon-object 是 Atlaskit 编辑器的深度嵌套依赖项的一部分。

我完全意识到我需要重新创建替代图标和主题,对此我没有意见。但是,当我创建 package.json 和 运行 npm install 时,我会在包含以下依赖项时获得上述 ADG 许可包:

...
"dependencies": {
    "@atlaskit/editor-core": "^120",
    "@atlaskit/media-core": "^31",
    "@atlaskit/smart-card": "^13",
    ...

如何传递我自己的实现以供使用,例如而不是 ADG 许可的默认值 @atlaskit/icon 来自 npmjs.com?

分叉整个 Atlaskit 包树只是为了修改依赖项以覆盖这 3 个包显然是可能的,但是有更好的方法吗?似乎 npm-force-resolutions 可以做这样的事情,但据我所知,它只允许替换依赖版本号所以我可以简单地 select which 官方实现例如@atlaskit/icon 我想使用,但不允许更改为完全不同的实现。 @atlaskit/icon 的所有版本都有相同的许可证,我正在尝试这样做,因为我不喜欢 ADG 许可证,我愿意重新实现所需的部分。

我更喜欢可以在主级别 package.json(或旁边的文件)中保存的内容,我需要其他 atlaskit 依赖项。我正在使用节点 v12 以防它有所作为。我不需要支持任何较低版本,但我也希望与 v14 兼容。

更新:给定以上依赖项,npm list "@atlaskit/icon" 将发出

my-atlaskit-editor@0.0.1 /local/path/to/my/editor
├─┬ @atlaskit/editor-core@120.1.2
│ ├─┬ @atlaskit/calendar@9.2.10
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/checkbox@10.1.14
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/datetime-picker@9.4.7
│ │ ├─┬ @atlaskit/field-base@14.0.5
│ │ │ └── @atlaskit/icon@20.1.2  deduped
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/droplist@10.0.8
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/editor-common@44.1.0
│ │ ├── @atlaskit/icon@20.1.2  deduped
│ │ ├─┬ @atlaskit/media-picker@54.2.3
│ │ │ ├─┬ @atlaskit/flag@12.4.5
│ │ │ │ └── @atlaskit/icon@20.1.2  deduped
│ │ │ ├── @atlaskit/icon@20.1.2  deduped
│ │ │ └─┬ @atlaskit/media-card@68.0.2
│ │ │   └── @atlaskit/icon@20.1.2  deduped
│ │ └─┬ @atlaskit/profilecard@12.4.4
│ │   ├─┬ @atlaskit/avatar@18.0.2
│ │   │ └── @atlaskit/icon@20.1.2  deduped
│ │   └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/editor-markdown-transformer@3.1.25
│ │ └─┬ @atlaskit/editor-common@46.1.1
│ │   ├── @atlaskit/icon@20.1.2  deduped
│ │   ├─┬ @atlaskit/media-card@68.0.2
│ │   │ └── @atlaskit/icon@20.1.2  deduped
│ │   └─┬ @atlaskit/media-picker@54.2.3
│ │     ├─┬ @atlaskit/flag@12.4.5
│ │     │ └── @atlaskit/icon@20.1.2  deduped
│ │     └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/emoji@62.8.4
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/form@7.4.1
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├── @atlaskit/icon@20.1.2 
│ ├─┬ @atlaskit/media-card@67.2.3
│ │ ├── @atlaskit/icon@20.1.2  deduped
│ │ └─┬ @atlaskit/media-viewer@44.4.4
│ │   └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/media-editor@37.0.12
│ │ ├── @atlaskit/icon@20.1.2  deduped
│ │ └─┬ @atlaskit/media-card@68.0.2
│ │   └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/media-filmstrip@38.0.4
│ │ ├── @atlaskit/icon@20.1.2  deduped
│ │ └─┬ @atlaskit/media-card@68.0.2
│ │   └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/media-picker@54.2.3
│ │ ├─┬ @atlaskit/flag@12.4.5
│ │ │ └── @atlaskit/icon@20.1.2  deduped
│ │ ├── @atlaskit/icon@20.1.2  deduped
│ │ └─┬ @atlaskit/media-card@68.0.2
│ │   └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/mention@18.18.3
│ │ ├─┬ @atlaskit/avatar@18.0.2
│ │ │ └── @atlaskit/icon@20.1.2  deduped
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/modal-dialog@10.6.4
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/radio@3.2.3
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/select@11.0.14
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/status@0.9.25
│ │ └── @atlaskit/icon@20.1.2  deduped
│ └─┬ @atlaskit/task-decision@16.1.2
│   └── @atlaskit/icon@20.1.2  deduped
├─┬ @atlaskit/media-picker@54.2.3
│ ├─┬ @atlaskit/dropdown-menu@9.0.6
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/flag@12.4.5
│ │ └── @atlaskit/icon@20.1.2  deduped
│ ├── @atlaskit/icon@20.1.2  deduped
│ ├─┬ @atlaskit/media-card@68.0.2
│ │ └── @atlaskit/icon@20.1.2  deduped
│ └─┬ @atlaskit/media-ui@12.5.1
│   ├─┬ @atlaskit/avatar@18.0.2
│   │ └── @atlaskit/icon@20.1.2  deduped
│   └── @atlaskit/icon@20.1.2  deduped
└─┬ @atlaskit/smart-card@13.5.1
  └── @atlaskit/icon@20.1.2  deduped

是否可以只替换 @atlaskit/icon 包而不替换 my-atlaskit-editor@atlaskit/icon 之间的树中的所有包 。在此示例中,它将是以下列表:

@atlaskit/avatar
@atlaskit/calendar
@atlaskit/checkbox
@atlaskit/datetime-picker
@atlaskit/dropdown-menu
@atlaskit/droplist
@atlaskit/editor-common
@atlaskit/editor-core
@atlaskit/editor-markdown-transformer
@atlaskit/emoji
@atlaskit/field-base
@atlaskit/flag
@atlaskit/form
@atlaskit/media-card
@atlaskit/media-editor
@atlaskit/media-filmstrip
@atlaskit/media-picker
@atlaskit/media-ui
@atlaskit/media-viewer
@atlaskit/mention
@atlaskit/modal-dialog
@atlaskit/profilecard
@atlaskit/radio
@atlaskit/select
@atlaskit/smart-card
@atlaskit/status
@atlaskit/task-decision

为了更改嵌套包中的 dependencies,需要覆盖很多包。实际上,我需要分叉所有这些包并更改每个嵌套包的 dependencies 以引用我的分叉版本,它再次只修改 dependencies 指向我分叉的另一个包。在这整个替换树的叶子将是一个 package.json,它指向 @atlaskit/icon@atlaskit/icon-file-type@atlaskit/icon-object.

的自由变体

如果不分叉和修改整个树中的依赖项,真的没有办法解决这个问题吗?

NPM natively supports package aliases since version 6.9.0

因此,对于您的情况,您可以采用以下方法:

  "dependencies": {
    "@atlaskit/editor-core": "npm:another-editor-core@^1.0",
    "@atlaskit/media-core": "npm:another-media-core@^1.0",
    "@atlaskit/smart-card": "npm:another-smart-card@^1.0"
  }

这将产生安装 another-editor-core@^1.0 而不是 @atlaskit/editor-core 的效果。然后,当您的代码尝试要求 @atlaskit/editor-core 时,将需要 another-editor-core

const editor = require("@atlaskit/editor-core") // this is actually another-editor-core

一个简单的管理方法是 create an org in npm 这样你就可以拥有像 @my-org-name/editor-core

这样的范围包

编辑:

正如评论中指出的,上面的解决方案不支持传递依赖,只支持直接依赖。

似乎 npm 目前不支持,即使使用 npm-force-resolutions。经过一番研究后,我找不到任何其他可以与 npm 一起使用的工具。

然而,使用 selective dependency resolutions 的纱线支持此功能:

  "resolutions": {
    "@atlaskit/editor-core": "npm:another-editor-core@^1.0",
    "@atlaskit/media-core": "npm:another-media-core@^1.0",
    "@atlaskit/smart-card": "npm:another-smart-card@^1.0"
  }

所以我看到 3 个选项供您继续前进:

  1. 迁移到 yarn(如果您的项目允许)
  2. 编写一个脚本来解析 package-lock.json 以覆盖已解析的包。这实际上不应该那么难。该脚本可以 运行 作为预安装步骤,与 npm-force-resolutions
  3. 完全一样
  4. npm-force-resolutions repo 上请求此功能,如果熟悉 clojure 且时间允许,可能会自己为回购做出贡献。

祝你好运!

另一种方法是使用@atlaskit 包作为基础创建一个私有 NPM 包,然后用您自己的包替换依赖项。 请参阅 https://docs.npmjs.com/files/package.json for details on creating a package description and https://docs.npmjs.com/creating-and-publishing-private-packages 以发布私有包。 您可能需要考虑使用一种工具来自动执行更新过程,以提取最新的@atlaskit 包并创建和发布您的替代方案。