如何在本地开发相互依赖的Angular 7库? (npm链接问题)

时间:2019-07-10 14:42:50

标签: angular npm angular7 angular-library npm-link

我有两个角度库NPM软件包:

  • A 具有基本组成部分
  • A-BC 具有以 A 中的组件为基础的组件,并具有与 BC 库集成的附加功能

A-BC中的某些组件是从A导入的,例如import { MyThing } from 'A';

A-BC的package.json是:

"peerDependencies": {
   "A": 1.0.0,
   "BC": 4.0.0
},
"devDependencies": {
   "A": 1.0.0,
   "BC": 4.0.0
}

我尝试的开发步骤是:

    npm link --only=production的内置版本中的
  1. A
  2. npm link --only=production的内置版本中的
  3. A-BC
  4. my-app中,运行npm link A
  5. my-app中,运行npm link A-BC
  6. 运行my-app

my-app找不到在任何地方安装的A-BC时,A的编译将失败。它们都正确地在node_modules中以符号链接文件夹的形式正确列出。我已经在preserveSymlinkstsconfig.json中启用了angular.json的情况下进行了尝试,但这没有帮助。

A可能是A-BC的直接依赖项,但是:

  • AA-BC都有一个名为forRoot()的调用,该软件包才能正常运行,以使其安装的应用程序正常运行。我不知道一种传递方法forRoot()参数从A-BC forRoot()动态到A forRoot()
  • my-app需要使用A中的组件和A-BC中的组件。
  • 如果A是直接依赖项,我不知道如何在本地开发A-BC,这可能涉及更改A-BC和偶尔更改{{1} }。

目前我的创可贴解决方案是:

  1. A发布为测试版
  2. AA-BC中安装测试版
  3. 通过my-appA-BC链接到my-app
  4. 如果需要进行更改,请发布npm link的新测试版,然后将其安装在Amy-app

通过NPM对本地文件的支持,安装A-BC可能会有替代的工作流程,但是我不确定。

2 个答案:

答案 0 :(得分:2)

我假设您正在谈论的这两个软件包是使用ngCli v6创建的,或者是您从已经存在的ng工作区中合并它们,无论哪种方式,让我们尝试解决您的问题。

我将假设您具有ng工作区结构,如下所示:

...
projects >
  A
  B
  host
...

A是一个库,B是一个依赖于A的库,主机是一个使用B的应用程序。

在ng工作区中本地工作/开发ng软件包时,应将其别名添加到root tsconfig.json文件中,例如:

{
 ...
"compilerOptions": {
    ...
    "paths": {
      "a": [
        "dist/a"
      ],
      "a/*": [
        "dist/a/*"
      ],
      "b": [
        "dist/b"
      ],
      "b/*": [
        "dist/b/*"
      ]
    }
  }
}

使用ng new lib {yourLibName}命令生成库时,将在CLI v7中自动为您完成此操作。

在确保具有此配置之后,我建议向package.json中添加一些脚本,以便构建库并以更直接的方式为开发应用程序提供服务(host该示例)

"build:a": "ng build A --watch=true",
"build:b": "ng build B --watch=true",
"serve:host": "ng serve host"

此后,通过依次运行这三个脚本并从libModules中的lib B导入适当的Host App,并从libModules导入适当的lib ALib B内部,您将能够使用lib B的组件,这些组件取决于lib A内部的Host APP的组件。

请记住,您不得在工作空间中安装这两个库,因为这会破坏项目中的导入,而且这些库也不应成为工作空间package.json的一部分。

如果您已完成上述步骤,但问题仍未解决,请向我们提供git repo的链接,或共享您的tsconfig.jsonpackage.jsonangular.json文件,这样我们才能继续进行调查。

回答评论

因此,如果我能解决您的问题,您希望能够开发这些packages并将其安装在一个ng工作区中。

据我所知,如果是这种情况,则没有直接的方法可以做到,您可以通过调整tsconfig.json来实现此行为(如您在注释中所建议的)文件。

但是我认为,如果您想在同一工作空间中使用此ng packages,则不一定要推送它们,因为最终它们只是另一组{{1 }}将成为您推荐他们的应用程序中的“一等公民”。因此,在进行生产时,它们会摇摇欲坠,最小化,优化等等。在这种情况下,您应该只在ngModules中扩展部署脚本,以这种方式,在开始构建主应用程序之前,您将依赖于package.json来构建程序包。

npm/ng/packages

同时,那些相同的"deploy": "ng build A && ng build B && ng build MainApp --production" 仍将是npm/ng/packages可发布的,您将能够在其他工作空间中使用它们。 请记住,它们不应该属于相同的(正在开发它们的工作空间)工作空间的npm依赖性。

答案 1 :(得分:0)

起初我想做的事情有很多问题,因为这种情况一开始是错误的。

我在这里学到的主要两件事是:

  1. 不应仅将内部角度项目中使用的软件包 发布到npm
  2. 如果库相互依赖,它们应该直接从您的打字稿/角源导入

如果您要使我所描述的方案奏效,那么它将给您带来无尽的头痛,因为这是一种根本上不可行的方法。

现在,共享这些库的所有相关项目都在一个nx monorepo中。通过直接导入库,一切都可以自动进行实时重载,摇树等,如此处建议的其他答案/评论所述。迁移并不是一件麻烦事,monorepo安装程序的工具也很好。

在设置您的monorepo以使此方案起作用时,库将通过tsconfig路径导入到每个项目,如下所示。这使得npm软件包的旧import语句能够保持不变,因为您的路径只能引用先前npm软件包的名称(例如上述问题中的A或A-BC)。

每个项目现在也共享相同的json包,并且通过将这些工具脚本集中在monorepo根目录中,而不是在每个仓库中单独使用工具,大大改善了用于服务,构建等的npm脚本。

@angular/*的路径解决了一些库冲突的问题。

/apps/example-project/tsconfig.json中的示例路径

   "paths": {
      "@angular/*": ["../node_modules/@angular/*"],
      "@exampleNPMOrg/A": [
        "../../libs/A/src/index"
      ],
      "@exampleNPMOrg/A-BC": [
        "../../libs/A-BC/src/index"
      ],
    }

/tsconfig.json中的示例路径

   "paths": {
      "@exampleNPMOrg/A": [
        "libs/A/src/index"
      ],
      "@exampleNPMOrg/A-BC": [
        "libs/A-BC/src/index"
      ],
    }