I’m using Angular 18 and trying to import a component(app1/reusable.component.ts
) from one project into another one(app2
).
And then, I want the component to import its dependencies from the project folder where it itself has been imported into (app2/node_modules
) instead of the folder where it is located.
My folder structure looks something like the following:
root
├──app1
│ ├──...
│ ├──node_modules
│ ├──src
│ │ ├──...
│ │ ├──app
│ │ │ ├──...
│ │ │ ├──reusable.component.ts
│
├──app2
│ ├──...
│ ├──node_modules
│ ├──src
│ │ ├──...
│ │ ├──app
│ │ │ ├──...
│ │ │ ├──app.component.ts
Where the relevant component files are:
// app1/src/app/reusable.component.ts
import { Component } from '@angular/core'; // this is an example of dependency that needs to be imported of app2/node_modu;es
@Component({
selector: 'reusable-component',
standalone: true,
template: 'Reusable Component',
})
export class ReusableAppComponent {
title = 'ReusableAppComponent';
}
and
// app2/src/app/app.component.ts
import { Component } from '@angular/core';
import { ReusableAppComponent } from '../../../app1/src/app/reusable.app.component'
@Component({
selector: 'app-root',
standalone: true,
imports: [ReusableAppComponent],
template: '<reusable-component></reusable-component>',
})
export class AppComponent {
title = 'app2';
}
What I have tried so far. And steps to reproduce.
Setup: initialized app1
and app2
with ng new
and removed app1/node_modules
.
Then, assuming I could pull this off with paths
option in tsconfig
,
I’ve Modified the compilerOptions
in app2/tsconfig.json
by adding
"baseUrl": "./",
"paths": {
"@angular/core": ["node_modules/@angular/core"],
"tslib": ["node_modules/tslib"]
}
As a result at runtime I see both ReusableComponent
and Component
from @angular/core
get imported, however an error in the console appears:
ERROR RuntimeError: NG0203: inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`. Find more at https://angular.dev/errors/NG0203
at injectInjectorOnly (main.js:650:11)
at ɵɵinject (main.js:660:59)
at Object.factory (main.js:14888:45)
at chunk-IMMNNYUP.js?v=a145dfc3:1965:35
at runInInjectorProfilerContext (chunk-IMMNNYUP.js?v=a145dfc3:567:5)
at R3Injector.hydrate (chunk-IMMNNYUP.js?v=a145dfc3:1964:11)
at R3Injector.get (chunk-IMMNNYUP.js?v=a145dfc3:1854:23)
at definition.getStandaloneInjector (main.js:14895:27)
at ComponentFactory.create (chunk-IMMNNYUP.js?v=a145dfc3:9692:53)
at _ApplicationRef.bootstrap (chunk-IMMNNYUP.js?v=a145dfc3:18388:38)
2
Answers
Maybe you should have a look at this section in the official Angular documentation about multiple projects.
It allows you to have a repository with one common
node_modules
folder and severalprojects
where you can even import in between projects. In the documentation they also explain that one of the projects could serve as a library with common pipes, components, etc. So you could move common components to the library and use them in different projects.There is an additional section in the documentation that deals with creating libraries here.
In your example the folder tree would look something like that:
There is a common
tsconfig.json
and specific configs for the apps where you can define app specific aliases for namespaces.If necessary you could even make an alias from one to another project:
for example in the
tsconfig.app.json
for app1:"@app2/*": ["../../app2/src/app/*"],
and in the
tsconfig.app.json
for app2:"@app1/*": ["../../app1/src/app/*"],
Now you can import as follows:
Hope this will help you otherwise please leave a comment.
Make sure you have
"preserveSymlinks": true
set in angular.json, for all the projects that use linking.This tutorial is good for working with linked packages.
How to Develop Angular Libraries Locally?
I think pointing to the dist folder is causing the
NG0203
which basically means, the service you have, is not considered as an angular service but a javascript class.