How to declare AppComponent in two different modules

Viewed 232

I am running Angular 7 project which contains two different applications:

  1. BasicTools
  2. AdvancedTools

BasicTools project points to basic-main.ts and AdvancedTools project points to advanced-main.ts. From basic-main.ts file, BasicAppModule is bootstraped and from advanced-main.ts AdvancedAppModule is bootstraped.

I have common AppComponent which is being used in both BasicAppModule and AdvancedAppModule but while building the application, I am getting error as AppComponent is declared as part of two module.

I tried exporting AppComponent in basic-app.module.ts and also removed the declaration of AppComponent from advanced-app.module.ts but getting error as: AppComponent should be declared as part of ngModule.

Is there any way to fix this as I need AppComponent in both the modules.??

Below is my angular.json file:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "BasicTools": {
      "root": "",
      "sourceRoot": "Client",
      "projectType": "application",
      "prefix": "app",
      "schematics": {
        "@schematics/angular:component": {
          "styleext": "scss"
        }
      },
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "wwwroot",
            "index": "Client/index.html",
            "main": "Client/app/basic/basic-main.ts",
            "polyfills": "Client/polyfills.ts",
            "tsConfig": "Client/tsconfig.app.json",
            "assets": [
              "Client/assets"
            ],
            "styles": [
              "Client/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "Client/environments/environment.ts",
                  "with": "Client/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "none",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "BasicTools:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "BasicTools:build:production"
            }
          }
        }
    },
    "AdvancedTools": {
      "root": "",
      "sourceRoot": "Client",
      "projectType": "application",
      "prefix": "app",
      "schematics": {
        "@schematics/angular:component": {
          "styleext": "scss"
        }
      },
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "wwwroot",
            "index": "Client/index.html",
            "main": "Client/app/advanced/advanced-main.ts",
            "polyfills": "Client/polyfills.ts",
            "tsConfig": "Client/tsconfig.app.json",
            "assets": [
              "Client/assets"
            ],
            "styles": [
              "Client/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "Client/environments/environment.ts",
                  "with": "Client/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "none",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "AdvancedTools:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "AdvancedTools:build:production"
            }
          }
        }
    },

advanced-main.ts

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { environment } from '../../environments/environment';
import { AdvancedAppModule } from '../advanced-app.module';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AdvancedAppModule);

basic-main.ts

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { environment } from '../../environments/environment';
import { BasicAppModule } from '../basic-app.module';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(BasicAppModule);

advanced-app.module.ts

@NgModule({
  declarations: [ AppComponent ],
  imports: [
    BrowserModule,
    CoreModule,
    SharedModule,
    BasicModule,
    AdvancedModule,
    applicationRoutingInformation
  ],
  providers: [
    { provide: LocationStrategy, useClass: MiPathLocationStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AdvancedAppModule { }

basic-app.module.ts

@NgModule({
  declarations: [ AppComponent ],
  imports: [
    BrowserModule,
    BasicModule,
    CoreModule,
    SharedModule,
    applicationRoutingInformation
  ],
  providers: [
    { provide: LocationStrategy, useClass: MiPathLocationStrategy }
  ],
  bootstrap: [AppComponent]
})
export class BasicAppModule { }
2 Answers

Create AppModule that exports AppComponent and import it in both of your root module configurations:

app.module.ts

@NgModule({
  declarations: [AppComponent],
  exports: [AppComponent]
})
export AppModule {}

basic-app.module.ts

@NgModule({
  imports: [AppModule, ...],
  bootstrap: [AppComponent],
  ...
})
export class BasicAppModule{}

advanced-app.module.ts

@NgModule({
  imports: [AppModule, ...],
  bootstrap: [AppComponent],
  ...
})
export class AdvancedAppModule {}

Even further if you have some common dependencies for you AppComponent shared between those two entry modules you can add providers for them in AppModule configuration.

We can't declare same component in two different and in this case we create a common module and imports it to both of modules.

common-module.ts

import { NgModule } from '@angular/core';
//import your component


@NgModule({
  declarations:[yourComponent],
  exports: [yourComponent]
})

export class CommonModule { }

Related