2

TL;DR 如何为本地纱线工作区依赖项创建别名?

我之前尝试过纱线工作区,但从未成功,我正在再试一次。

我已经入驻"workspaces": ["packages/*"]package.json

对于每个包,我决定使用命名约定@-/package-name来防止命名冲突,而不用担心内部包的命名空间。

在将包添加为依赖项时,我一直遵循一种使用接口名称进行解析的风格,但将其指向具体的实现。这是我在使用纱线工作区之前所做的:

"dependencies": {
  "my-interface-name": "file:some/path/to/packages/some-concrete-implementation"
}

这基本上是为了允许我喜欢称之为编译时静态依赖注入。这也意味着每个包都可以根据需要单独命名其接口依赖项,并防止命名冲突。

但是,我不知道如何使用纱线工作区来实现这一点。如何为@-/some-concrete-implementation名为的纱线工作区包创建别名my-interface-name

我已经尝试过但没有成功:

  • 像定义依赖一样"my-interface-name": "@-/some-concrete-implementation"}- 由于某种原因,这会导致纱线@-/some-concrete-implementation在 npm 注册表而不是本地工作区中查找
  • 我也尝试过使用工作区协议:"my-interface-name": "workspace:@-/some-concrete-implementation"}但它仍然在 npm 注册表中查找包!

我还没有尝试过并且可以工作但首先消除了使用纱线工作区的好处:

  • "dependencies": {"my-interface-name": "file:../../node_modules/@-/some-concrete-implementation"}"
4

2 回答 2

4

你见过resolutionspackage.json 键吗?这是你需要的吗?

我已将它用于别名/覆盖外部包,但文档中的示例显示它与本地包一起使用。

决议

允许您覆盖特定嵌套依赖项的版本。有关完整规范,请参阅Selective Versions Resolutions RFC

{
  "resolutions": {
    "transitive-package-1": "0.0.29",
    "transitive-package-2": "file:./local-forks/transitive-package-2",
    "dependencies-package-1/transitive-package-3": "^2.1.1"
  }
}

来自 RFC:

“**/a”表示项目的所有嵌套依赖a。

"a" 是 **/a 的别名(为了追溯兼容性,请参见下文,因为如果它不是这样的别名,则它没有任何意义,因为它代表了非嵌套项目依赖项之一,它不能被覆盖,如下所述)。

所以,我相信你需要的规则是:

"**/my-interface-name": "file:some/path/to/packages/some-concrete-implementation"

// OR equivalent

"my-interface-name": "file:some/path/to/packages/some-concrete-implementation"

我相信它在包的 package.json 中有效。在最坏的情况下,您可以将其提升到工作区根目录,并使规则特定于工作区,例如“a/b”。

于 2020-05-12T12:01:00.210 回答
2

工作区:别名协议 (也可以在 pnpm 中使用)似乎是要采取的方向。

我也尝试使用工作区协议:“my-interface-name”:“workspace:@-/some-concrete-implementation”},但它仍然在 npm 注册表中查找包!

一定要安装 yarn 3,否则你会遇到奇怪的问题。

请注意,"my-interface-name": "workspace:@-/some-concrete-implementation"看起来的语法不正确。

它应该"@xxx/some-concrete-implementation": "workspace:*",假设链接包的名称是"name": "@xxx/some-concrete-implementation".

考虑到这一点,您甚至不需要创建特定的@-/name. 使用工作空间协议,yarn 将确保它永远不会从 npm 下载。它成为内部工作区依赖项。

PS:


纱线 3 安装

通常一个简单的yarn set version 3.0.2 && yarn plugin import workspace-tools) 会起作用。

为避免 pnp 电流限制,请检查生成的配置.yarnrc.yml并确保 nmLinker 设置为“node-modules”

# Yarn 2+ supports pnp or regular node_modules installs. Use node-modules one.
nodeLinker: node-modules
plugins:
  - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
    spec: "@yarnpkg/plugin-workspace-tools"
yarnPath: .yarn/releases/yarn-3.0.2.cjs

.gitignorePS:您可能也想将其添加到

.yarn/*
!.yarn/patches
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
.pnp.*

之后运行一个yarn install

关于 package.json 的

像您一样,根package.json将定义工作区路径:

{
  "name": "monorepo",
  "workspaces": [
    "packages/*"  // Enable package discovery in packages/* directory.
  ],
  // ... 
  "devDependencies": {
    "husky": "7.0.2", // Only what's needed for monorepo management
  }

在您的应用中packages/app/package.json

{
  "name": "my-app",
  "devDependencies": {
    "@types/node": "16.10.1",
    //...
  },
  "dependencies": {
    // Assuming the name of packages/shared is "@your-org/some-concrete-implementation",
    // we explicitly declare the dependency on it through
    // workspace: alias (package-manager perspective)
    "@your-org/some-concrete-implementation": "workspace:*",
  }
}

您使用的包应该声明相同的名称

{
  "name": "@your-org/some-concrete-implementation",
}


奖励:打字稿别名

如果你的项目是用 ts 编写的,你甚至可以通过 typescript path mapping复制你的路径。它将允许按原样包含文件(无需事先编译)。

按照您的示例,只需./packages/xxx/tsconfig.json以这种方式编辑 a

{
  "compilerOptions": {
    // here baseUrl is set at ./src (good practice), can
    // be set to '.'  
    "baseUrl": "./src",
    "paths": {
      // Declare deps here (keep them in sync with what
      // you defined in the package.json)
      // PS: path are relative to baseUrl
      "@your-org/some-concrete-implementation/*": ["../../some-concrete-implementation/src/*"],
      // if you have a barrel in ui-lib 
      "@your-org/some-concrete-implementation": ["../../some-concrete-implementation/src/index"],
    }
  },
}

PS:对于非 typescript:babel/plugin-module-resolver可以类似的方式使用。

于 2021-10-13T21:42:50.340 回答