“自定义库”组件不是已知元素,但应用会编译并运行

时间:2020-02-06 19:21:17

标签: html angular typescript npm visual-studio-code

问题

我的html文件警告我的自定义组件/管道“不是已知元素”。但是,构建和运行应用程序可按预期运行,并且自定义组件/管道可以正常运行。正常工作但显示为错误的组件二分法令人讨厌,并且可能很难使用。我知道这是一件小事,但是当没有错误时,我真的想在我的html文件中看不到错误。

摘要

我有两个不同的角度项目;我在我的角度应用程序中使用的角度库。该库导出应用程序使用的几个自定义组件,管道和服务。我没有通过npm发布该库,而是使用npm-link来使应用程序访问该库。这似乎可以正常工作,因为我的应用程序组件中定义的任何服务/组件都可以正常工作,并且不会抱怨。尽管从我的库中将任何东西放入模板文件的那一刻起,该选择器就会带有下划线并显示警告。

文件

/*Library Module*/
@NgModule({
  declarations: [
    ThemeToggleComponent,
    // Other custom components/pipes
  ],
  exports: [
    ThemeToggleComponent,
    // Other components needed in templates files
  ]
})
export class MyCommonModule {}

/*
 * Public API Surface of my-common library
 */

export * from './lib/my-common.module';
/*
 * Many other components, services, pipes, etc etc
 */
export * from './lib/theme-toggle/theme-toggle.component';

/* Consuming Application module */
import { MyCommonModule } from 'my-common';

@NgModule({
  imports: [
    MyCommonModule,
  ],
  declarations: [
    MyComponent,
  ],
})
export class MyModule {}
/* Template of MyComponent, my.component.html */
<div>
  <my-theme-toggle (darkThemeSelected)="toggleTheme($event)"></my-theme-toggle>
</div>

上面的文件将包含引用我的自定义组件的所有行,并用红色下划线显示错误消息'my-theme-toggle'不是已知元素:...如果是,请确认是否与模块

尝试修复

我已经尝试过一件事,但无济于事

  • 不使用NPM链接,仅将ng-packagr创建的库复制到应用程序的节点模块中
  • 重建并重新链接/重新启动所有内容
  • 搜索其他S.O问题:多数问题与构建失败有关,因为导入/导出实际上不正确。

我的预感

我认为这是使用应用程序tsconfig.json中 paths 编译器选项的问题。在我所有的研究中,这件事比其他任何事情都弹出。我目前没有设置路径,因为一切正常。除了这个问题外,我的公共库的外观和行为与其他任何node_module库一样。

我的另一种想法是,因为一切都能正常运行,所以问题可能出在vs代码不了解导入或类似性质的问题上。尽管我认为这不太可能。

背景

两个角度项目都在版本9,rc7上。我使用ng-packagr构建我的库。我使用Visual Studio代码,在撰写本文时,我使用的是最新版本。

7 个答案:

答案 0 :(得分:5)

要解决此问题,当前必须使用生产标志--prod进行构建,因为在当前状态下,Angular Language Server doesn't work with Ivy会进行构建。默认情况下,有角度的产品构建没有Ivy。因此,在构建它时,它将创建一个lib.metadata.json文件。这是语言服务器用来使插件正常工作的文件。

  1. 在您的库中,创建一个内部版本ng build <lib> --prod
    • 添加--watch标志以查看更改
  2. 在您的书架中,先创建链接cd dist,然后创建npm link
    • 我在package.json文件夹中创建了一个dist,并在其中创建了链接,因为我的库中有多个模块。这将使您能够
      • import { ModuleAComponent } from '<lib>/moduleA'
      • import { ModuleADirective } from '<lib>/moduleA'
    • 注意::您链接的文件夹必须具有package.json,否则它将使用项目的根目录,因为它是最接近的package.json
    • 如果您执行相同的操作,则以下路径的格式正确,否则可能不正确,您可以尝试:"lib": ["./node_modules/lib", "./node_modules/lib/*"]
  3. 在您的应用程序中,链接到软件包npm link <lib>
  4. 在您的应用程序中,在path中创建一个tsconfig.base.json(路径可能会有所不同,具体取决于创建链接的方式)
  5. 在您的应用程序中,重新启动Angular Language Server
{
  "compilerOptions": {
    "paths": {
      "lib/*": [
        "./node_modules/lib/*"
      ]
    }
  }
}

答案 1 :(得分:2)

直到最近我才描述过错误。

卸载了我最近安装的Angular Language Service扩展后,错误消失了。

答案 2 :(得分:1)

我将项目从Angular 8切换到了9,并且在VS Code中遇到了相同的问题。适用于我的解决方案:

  • 使用配置生产版本构建库:ng build my-lib --prod =>这将迫使编译器使用较旧的View Engine而不是Ivy(Angular docs libraries
  • 转到文件夹“ ./dist/my-lib/”,然后使用npm pack代替npm link =>,这将创建一个tgz文件,您可以将其安装在使用的应用中。
  • 在使用的应用中安装该库:npm install "D:/mypath/dist/my-lib/my-lib-2.1.0.tgz"

这解决了我的环境中Angular 9 VS Code的问题。

答案 3 :(得分:1)

您可以尝试以下方法。 https://github.com/angular/vscode-ng-language-service/issues/645#issuecomment-648283157 简而言之:

  • 使用--prod标志构建您的lib。
  • 然后转到dist/YourLibName并运行npm link
  • 转到将要使用lib的项目,然后从lib package.json中运行npm link YourLibName名称
  • 在项目tsconfig.json中,将路径属性添加到editorOptions。
    {  
      "compilerOptions": {
       .
       .
       .
        "paths": {
          "YourLibName from lib package.json": ["node_modules/YourLibPath"]
        },

然后,您将可以像使用任何库一样使用它。材料。

答案 4 :(得分:1)

99.99% 的情况下是导入问题!

我在 Stack Overflow 内外的不同网站上看到这个问题的发布方式略有不同。我可以告诉你,这可能不是 Angular 语言服务的问题。

发生这种情况的三个原因

  1. 您如何从库中导出丢失的组件,例如检查您是否:

    • 已将 export * from <your-component> 添加到您的 public-api.ts 文件
    • 将您的组件添加到导出它的库模块的 exports
  2. 您如何导入库组件,例如检查您是否:

    • 链接图书馆? cd /path/to/<your-library> && npm link
    • 链接了应用程序?:cd /path/to/app && npm link <your-library>
    • 将库 NgModuleYourLibraryModule 添加到您的应用程序主 NgModule 的 imports:[]
  3. 你可能忘记在你的 App NgModule 中声明父组件了!!

    • 这个是巨大的,不常被提及。在 Angular 10、11 中,您可以忘记将引用缺少的库组件的应用程序组件添加到 declarations 中,语言服务/编译器会抱怨缺少库组件,但不会提及应用程序组件不正确出口!

为什么要重启 Angular 语言服务?

有时一旦您重新启动语言服务(例如重新启动 VSCode),错误可能会改变。对于我上面提到的场景 3,错误变为:

Error: Cannot determine the module for class YourAppComponent in YourApp/src/app/components/your-app-component/your-app-component.component.ts! Add YourAppComponent to the NgModule to fix it

瞧!!你看到了真正的问题,解决它很容易!

答案 5 :(得分:0)

您好,我在开发自定义库时遇到了同样的问题。我正在使用应用程序和库之间的链接。

我修复了在 tsconfig.json 中的 compilerOptions 下添加 preserveSymlinks。

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "preserveSymlinks": true,
    ...

查看here了解更多详情。

答案 6 :(得分:-2)

我有完全相同的问题。这是一个解决方法,

添加

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

schemas: [
  CUSTOM_ELEMENTS_SCHEMA
],

到您的模块


完整的app.module.ts供您参考

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NgNiceSelectModule } from 'ng-nice-select';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    NgNiceSelectModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [
    CUSTOM_ELEMENTS_SCHEMA
  ]
})
export class AppModule { }