Class is not an Angular module for external library

我是研究僧i 提交于 2021-01-07 03:53:04

问题


I have created a simple Angular app and added a custom library (same project):

ng new my-library ng generate library my-library-lib

Then to test this simple library in a different project, I built the lib: ng build my-library-lib

I linked the lib in dist folder and linked it to a different project and imported the MyLibraryLibModule in my SharedModule

{ MyLibraryLibModule } from 'my-library-lib

imports: [..., MyLibraryLibModule] --> throws error: class is not an Angular Module

This is a simple project I did to redo everything from scratch, did not change anything in tsconfig files etc. Looked online but couldn't find any solution.

To test it: Library repo: https://github.com/GCour/ui-library

Simple project repo: https://github.com/GCour/ui-test

tsconfig.lib.json:

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "../../out-tsc/lib",
    "target": "es2015",
    "declaration": true,
    "declarationMap": true,
    "inlineSources": true,
    "types": [],
    "lib": [
      "dom",
      "es2018"
    ]
  },
  "angularCompilerOptions": {
    "skipTemplateCodegen": true,
    "strictMetadataEmit": true,
    "enableResourceInlining": true
  },
  "exclude": [
    "src/test.ts",
    "**/*.spec.ts"
  ]
}

tsconfing.lib.prod.json

{
  "extends": "./tsconfig.lib.json",
  "compilerOptions": {
    "declarationMap": false
  },
  "angularCompilerOptions": {
    "enableIvy": false
  }
}

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": [
      "es2018",
      "dom"
    ],
    "paths": {
      "my-library-lib": [
        "dist/my-library-lib/my-library-lib",
        "dist/my-library-lib"
      ]
    }
  }
}

回答1:


If you are asking about use in developer a local library you should create your library in production

ng build my-lib --prod

then use npm link to create locally your library

cd dist
cd my-lib
npm link

If all is ok, you can import in another project of your computer, you can check if the lib is added to your local npm in

C:\Users\[your-user]\AppData\Roaming\npm\node_modules\my-lib

Now the only thing you need to use in another project of your computer using npm link my-library

cd c:\my-another-app\src
npm link my-library

And use as usually, in your app.module

   import {myLibModule} from 'my-lib'
   //or import {MyLibService} from 'my-lib/public-api' 

   ...
   imports: [myLibModule}



回答2:


You can use this GitHub repository for reference which demonstrates the setup and integration of the custom libraries using npm link.

Angular CLI build command uses a different builder and invokes a different build tool for libraries than it does for applications.


  • Angular CLI has a different mechanism for building libraries, based on ng-packagr unlike for building applications, which uses @angular-devkit/build-angular and is based on webpack.

  • The build system for libraries is only added to your dependencies when you add a library using ng generate library my-lib. If you've been manually setting up the infrastructure, you might wanna make sure of this by verifying your config files.

Be careful with TypeScript path mappings..


  • Since there is a difference in the build mechanism, the TypeScript source gets converted to a totally different JavaScript code in the built library than it would in a built application.

  • For this reason, an app that depends on a library should only use TypeScript path mappings that point to the built library. TypeScript path mappings should not point to the library source .ts files.

As stated in the official docs -

.. When you build your own library, it has to find the mapping in your tsconfig paths.

NOTE: Generating a library with the Angular CLI automatically adds its path to the tsconfig file. The Angular CLI uses the tsconfig paths to tell the build system where to find the library.

Is your application using code from an old library build!


  • Every time a file within the source code is changed, a partial build is performed that emits the new changes from the source code.

  • If you believe your changes in the library code are not reflected in your app, your app is probably using an old build of the library.

  • You can rebuild your library whenever you make changes to it, but this extra step takes time. We can make use of Angular built-in Incremental build feature. Incremental builds can be run as a background process in your dev environment.

  • Add the --watch flag to the build command: $ ng build my-lib --watch

Need to share your library code outside the application's scope?


  • Publish your library on npm for global users.
  • Create a local link for sharing within a private network.

since the op has been edited and is looking for creating a local link, the following explains only the second bit. To publish your library on npm-registry, you can refer to the official angular docs on publishing libraries on npm registry. If you're new to the npm registry, and this is the first time you're publishing a library, you might wanna check out the various grounds to cover when publishing your libraries on npm registry


While working with npm link ...

  • Once you build your library, in order to verify if it's done correctly, go to the dist/ folder of your library workspace and verify the package.json file. The package.json, should have an attribute main. Make sure it is linked with a file extension of .js and not a .ts

  • Now you can use npm link within your library workspace. It creates a reference pointer - a symlink - within the local node environment directing towards your library.

  • Once the local reference is created, go to your project workspace, and use npm link <library-name>. Make sure, it's the library name and not the library-workspace name.

  • In the project workspace, within the node_modules you should be able to see your library with an '@' appended to it. Now you can easily import relevant components and services from your library into your projects app.module.ts.. or lazy-load them if you prefer that approach.

Likewise..

import { FooModule } from 'foo-library';
...


来源:https://stackoverflow.com/questions/64930778/class-is-not-an-angular-module-for-external-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!