使用库的组件从库的辅助入口点使用绝对路径延迟导入组件

问题描述 投票:0回答:1

更新: 链接到 回购

阅读了大量文档和检查示例,但不幸的是我的组合是有史以来最糟糕的。延迟加载、动态导入、带变量的绝对路径:

我有 Angular 15 应用程序,其中有 2 个项目、库和应用程序,它们应该使用绝对路径引用库的组件(因为我需要以与另一个 Angular 应用程序相同的方式使用库)。 库具有独立的组件 - 辅助入口点。其中一个组件很棘手。 它正在根据 REST API 响应在 ViewContainerRef 容器中创建组件。我在存储库中对其进行了简化,因此它可以与提供的示例数据一起使用。

当我尝试相对路径时效果很好

const module = await import(`../../${item.path}/src/${item.path}.component`);

但是我需要一个绝对路径,以便从其他项目中使用。

我尝试了数千种方法来解决它,编辑 tsconfig 以包含项目,编辑包以导出项目。总是有错误。最常见的是:

./projects/mycompany/sdk/dynamic-container/src/dynamic-container.component.ts:21:31-95 - Error: Module not found: Error: Can't resolve '@mycompany/sdk' in 'C:\Users\yekat\apps\new\our-library\projects\mycompany\sdk\dynamic-container\src'

如果您有任何解决办法,请提供帮助。我花了几天几夜都没有答案...

我无法在没有延迟加载的情况下导入所有组件,因为可能有很多或几个组件,而且我不需要加载整个库。

下面的长消息就是我开始的内容。现在我有一个存储库,您可以复制。

提前谢谢您!!!

老问题 我有 2 个 Angular 15 应用程序,我尝试让它们一起工作。 第一个是具有独立组件的库 - 辅助入口点。其中一个组件很棘手。 它正在根据 API 响应在 ViewContainerRef 容器中创建组件。

component.module = await import(`../../../${itemPath}/src/${componentName}.component`);
...
this.componentRef = this.containerRef?.createComponent(component.module[component.moduleName]);

在这个应用程序中,我有一个沙箱,它的模块相对导入我棘手的动态组件。

import { DynamicContainerComponent } from '../../../mycompany/sdk/base-components/dynamic-container/src/dynamic-container.component';

然后它以 html 形式显示。它在图书馆应用程序中运行得非常好。延迟加载按预期工作,构建过程创建文件夹 dist

esm2020/...
fesm2015/...
fesm2020/...
....

服务过程看起来不错,显示了已创建的块:

Initial Chunk Files                                                                                     | Names         |   Raw Size
vendor.js    
                                                                                           .....
| Initial Total |    2.69 MB
.....
Lazy Chunk Files                                                                                        | Names         |   Raw Size
....
projects_mycompany_sdk_base-components_drop-down-list_src_drop-down-list_component_ts.js              | -             |  867.52 kB |
....
projects_mycompany_sdk_base-components_plain-html_src_plain-html_component_ts.js                      | -             |    2.26 kB |

它没有我的动态组件,因为它是通过沙箱导入并包含在初始块文件中的。

tsconfig.json 
{
  "compileOnSave": false,
  "compilerOptions": {
    "resolveJsonModule": true,
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "strictPropertyInitialization": false,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "typeRoots": [
      "node_modules/@types"
    ],
    "paths": {
      "@mycompany/sdk/*": [
        "projects/mycompany/sdk/*"
      ],
      "@mycompany/sdk": [
        "projects/mycompany/sdk"
      ]
    },
    "target": "ES2022",
    "module": "ES2022",
    "useDefineForClassFields": false,
    "lib": [
      "ES2022",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

角度.json:

    "projects": {
        "@mycompany/sdk": {
            "projectType": "library",
            "root": "projects/mycompany/sdk",
            "sourceRoot": "projects/mycompany/sdk",
            "prefix": "lib",
            "schematics": {
                "@schematics/angular:component": {
                "standalone": true,
                "style": "scss"
                },
                "@schematics/angular:directive": {
                "standalone": true
                },
                "@schematics/angular:pipe": {
                "standalone": true
                }
            },
            "architect": {
                "build": {
                "builder": "@angular-devkit/build-angular:ng-packagr",
                "options": {
                    "project": "projects/mycompany/sdk/ng-package.json"
                },
                "configurations": {
                    "production": {
                    "tsConfig": "projects/mycompany/sdk/tsconfig.lib.prod.json"
                    },
                    "development": {
                    "tsConfig": "projects/mycompany/sdk/tsconfig.lib.json"
                    }
                },
                "defaultConfiguration": "production"
                },
                "test": {
                "builder": "@angular-devkit/build-angular:karma",
                "options": {
                    "tsConfig": "projects/mycompany/sdk/tsconfig.spec.json",
                    "polyfills": ["zone.js", "zone.js/testing"]
                }
                }
            }
        },
...

我使用 Verdaccio 来发布这个库,效果很好。当我将简单组件从这个库导入另一个应用程序时,它们运行良好。但是当涉及到我的动态容器时,我产生了一个错误。 但让我先介绍一下应用程序 2 是如何工作的。 应用程序组件与应用程序 1 中的沙箱类似,但从包导入:

import { DynamicContainerComponent } from '@mycompany/sdk/base-components/dynamic-container';

(当我导入其他组件时,它们可以工作。但它们没有从相对路径进行这种惰性导入。) 因此 DynamicContainerComponent 的值是来自 API 调用的 Observable 响应。 DynamicContainerComponent 本身决定它应该加载什么组件。

我尝试在 tsconfig 中使用不同的路径:

"paths": {
  "../../../base-components/*" : [
     "node_modules/@mycompany/sdk/base-components/*"
  ],
  "../../../base-components" : [
    "node_modules/@mycompany/sdk/base-components"
  ],
  "base-components": [
    "node_modules/@mycompany/sdk/base-components"
  ],
  "@mycompany/sdk/*": [
    "node_modules/@mycompany/sdk/*"
  ],
  "./base-components": [
    "node_modules/@mycompany/sdk/base-components"
  ]
}

角度.json:

...
  "projects": {
    "test-lib": {
      "projectType": "application",
      "schematics": {},
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/test-lib",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": [
              "zone.js"
            ],
            "tsConfig": "tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "budgets": [
                .......
              ],
              "outputHashing": "all"
            },
            "development": {
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            }
          },
          "defaultConfiguration": "production"
        },
....

构建此应用程序时,dist 文件夹会获取许多奇怪的文件: dist

(很多这些文件,它们确实包含最小化的库组件。) 当服务时我可以看到它也在创建块:

Initial Chunk Files                                                                                     | Names         |   Raw Size
vendor.js                                                                                               | vendor        |    2.40 MB |
....

| Initial Total |    2.96 MB

Lazy Chunk Files                                                                                        | Names         |   Raw Size
...
        
node_modules_mycompany_sdk_esm2020_base-components_plain-html_src_plain-html_component_mjs.js         | -             |    2.83 kB |
...

在浏览器中运行时,我看到错误: error

我想我在 App 2 配置中遗漏了一些东西。

如果建议替换相对路径

../../../${itemPath}/src/${componentName}.component

@mycompany/sdk/${itemPath}/src/${componentName}.component
) 我尝试过,在这种情况下,我在服务库时出现错误

./projects/mycompany/sdk/base-components/dynamic-container/src/dynamic-container.component.ts:39:31-105 - Error: Module not found: Error: Can't resolve '@mycompany/sdk' in 'C:\Users\yekat\mw10-front-end-components\projects\mycompany\sdk\base-components\dynamic-container\src'

在App2中

./node_modules/@mycompany/sdk/fesm2020/mycompany-sdk-base-components-dynamic-container.mjs:38:31-105 - Error: Module not found: Error: Can't resolve '@mycompany/sdk' in 'C:\Users\yekat\apps\new\test-lib\node_modules\@mycompany\sdk\fesm2020'
angular command-line-interface lazy-loading angular-library angular-dynamic-components
1个回答
0
投票

通过在单独的服务中指定所有导入来解决这个问题。在这种情况下,webpack 很高兴并且延迟加载仍然有效。我希望我可以一起使用动态路径和延迟加载,而不需要为所有对象指定导入。但好像不可能

© www.soinside.com 2019 - 2024. All rights reserved.