Reputation: 1402
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"
]
}
}
}
Upvotes: 1
Views: 1981
Reputation: 1092
You can use this GitHub repository for reference which demonstrates the setup and integration of the custom libraries using npm link
.
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.
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.
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
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';
...
Upvotes: 1
Reputation: 57971
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}
Upvotes: 2