为了说明我的问题,我有一个具有以下结构的示例 Nx 项目:
/nx.json
/tsconfig.base.json
/apps
/my-app
/project.json (type application)
/tsconfig.json
/src
/app
/components
/comp1
comp1.component.ts
/libs
/my-lib
/tsconfig.json
/project.json (type library)
/src
/index.ts
/icons
icon1.svg
icon2.svg
/models
base-models.ts
/angular
/components
comp2
comp2.component.ts
目标是共享 my-lib 库中的资产和代码。
使用共享资产
假设我有两个组件需要使用共享库中的图标,如下所示:
组件 1:apps/my-app/src/app/components/comp1/comp1.component.ts 组件 2:libs/my-lib/src/angular/components/comp2/comp2.component.ts 在每个组件的模板中,我想包含图标,也许是这样的:
<ion-icon slot="start" src="assets/my-icons/icon1.svg"></ion-icon>
使用共享代码
我还想共享 libs/my-lib/src/models/base-models.ts 文件中的代码,该文件在 libs/my-lib/src/index.ts 中导出。例如:
从'@monkey/my-lib/models'导入{BaseModels};
问题
共享资源:我尝试使用以下命令配置 my-app 的 project.json 以从库中复制共享资源:
{
"glob": "**/*",
"input": "libs/my-lib/src/assets",
"output": "assets"
}
但是,成功构建项目后,资产并没有按预期复制。我注意到一些文件位于 dist/apps/my-app 文件夹中,但不是我尝试复制的资产。
共享代码:我似乎可以通过在项目 tsconfig.json 中包含 index.ts 的路径来包含共享代码。但我希望能够在 tsconfig.base.json 中添加它(一次且仅一次),该文件由项目级别 tsconfig 文件扩展...我在某处读到您可能需要在以下位置添加 tsconfig.json根,但这似乎是一件奇怪的事情???
我注意到 tsconfig.base.json 包括:
"rootDir": ".",
"baseUrl": ".",
"paths": { ........ }
而 my-app tsconfig.json 包含行:
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"paths": { ........ }
和project.json lincludes:
"executor": "@angular-devkit/build-angular:browser",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/apps/my-app",
这里到底发生了什么?项目中的路径是否覆盖 tsconfig.base.json,而不是“扩展”它。这可能有道理...
rootDir 和 baseUrl 有什么关系???
问题
两个示例组件应该如何使用 src="..." 路径正确访问共享图标 icon1.svg?
如何正确配置 Nx 以在库和应用程序中使用来自 base-models.ts 的共享代码?
我对 nx 方法的理解是,一切可以的东西都应该放在共享空间中。但尚不清楚 tsconfig.base.json 和各种 tsconfig.json 文件应如何构建。在我见过的一些文档中,.base 甚至不存在。很混乱...
注释
我怀疑该解决方案涉及配置各种 tsconfig 文件并确保在构建过程中正确处理资产。
任何关于为什么资产没有被正确复制的建议将不胜感激!
我想发布这个答案,因为这个话题非常令人困惑。
1。路径分辨率
在 nx monorepo 中,有一个 tsconfig.base.json。为了澄清我的观点,它包含:
"baseUrl": ".",
"paths": {
"@monkeytronics/shared": ["libs/shared/src/index.ts"],
},
如果您想遵循 nx 结构,这是您需要的唯一的 baseUrl 定义。您可以在这里定义所有路径!这样,您就可以在 typesecript 导入中使用您的路径:
从'@monkeytronics/shared'导入{monkeySchemas};
覆盖baseUrl
如果您在应用程序级别的 tsconfig.json 中覆盖 baseUrl,可能会产生意想不到的效果。如果您使用 tsconfig.base.json 中的路径,则这些路径仅相对于同样在 tsconfig.base.json 中定义的 baseUrl 起作用。所以,如果你改变它,路径就会全部中断。无济于事的是,我引入 nx 的 Angular 项目似乎都定义了 baseUrl = "./" 。这就是阻止我将我的路径推回根级别的原因。
覆盖路径
上述内容适用于覆盖 baseUrl...除非您也覆盖您的路径。但是,请注意,如果覆盖路径,则必须完全覆盖。虽然 tsconfig.json 文件使用“扩展”工作,但不要误以为可以将基本路径与 tsconfig.json 中的路径对象合并。您只能覆盖整个对象。无论如何,如果我们要“扩展”路径,就会出现应用哪个 baseUrl 的问题。因此,在某种程度上,这更干净、更稳健。
陷阱
您如何处理应用程序 tsconfig.json 中这样的路径?
"~/*": ["/*"]
它是特定于应用程序的,因此您不能将其移回到 tsconfig.base.json 中。我的想法是,您需要搜索代码并删除任何此类引用。它们与 nx 结构不兼容。
2。资产使用
这个比较容易。要使用共享资源,您可以在应用程序级别的project.json选项中执行以下操作:
"outputPath": "dist/apps/my-app",
{
"glob": "**/*.svg",
"input": "libs/shared/src/assets",
"output": "monkey-shared-svg"
}
确保正确定义输出路径。这将拉取所有 svg 文件并将它们放入 dist/apps/my-app/monkey-shared-svg 中。并且可以从模板中访问它们: src="monkey-shared-svg/**/*.svg"
希望这是有用的信息。