3

I am migrating old angular project from version 5 to version 19. I have indentified all compatible and dependent libraries and able to migrate code. However I keep getting standanlone error.

Note : I have already tried standalone:false in the component section. It is not helping, because I'm getting same error.

The project is based on NgModule and I want to have as is, and I don't need the standalone feature as now.

    ng build 
    √ Browser application bundle generation complete.

    Error: src/app/app.module.ts:7:5 - error NG6008: Component AppComponent is standalone, and cannot be declared in an NgModule. Did you mean to import it instead?

    7     AppComponent // Declare AppComponent here

To drill down the issue, I created a minimal project from actual and reproduded the issue. I added standalone:false in the angular.json, cleared cache, removed node-modules, verified all ts files for no standalone:true. However this has become a nightmare for me as from last two day I am not able to fix it.

angular.json

  {
    "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
    "version": 1,
    "newProjectRoot": "projects",
    "projects": {
      "resource-planning": {
        "projectType": "application",
        "root": "src",
        "sourceRoot": "src",
        "prefix": "app",
        "schematics": {
            "@schematics/angular:component": {
            "standalone": false
          }
        },
        "architect": {
          "build": {
            "builder": "@angular-devkit/build-angular:browser",
            "options": {
              "outputPath": "dist/resource-planning",
              "index": "src/index.html",
              "main": "src/main.ts",
              //"polyfills": "src/polyfills.ts",
              "tsConfig": "tsconfig.app.json",
              "aot": true,
              "assets": [
                "src/assets",
                "src/favicon.ico"
              ],
              "styles": [
                "src/styles.css",
                "node_modules/font-awesome/css/font-awesome.min.css",
                "node_modules/primeng/resources/themes/omega/theme.css",
                "node_modules/primeng/resources/primeng.min.css"
              ],
              "scripts": []
            }
          },
          "serve": {
            "builder": "@angular-devkit/build-angular:dev-server",
            "options": {
              "buildTarget": "resource-planning:build"
            },
            "configurations": {
              "production": {
                "buildTarget": "resource-planning:build:production"
              }
            }
          },
          "test": {
            "builder": "@angular-devkit/build-angular:karma",
            "options": {
              "main": "src/test.ts",
              //"polyfills": "src/polyfills.ts",
              "tsConfig": "tsconfig.spec.json",
              "karmaConfig": "./karma.conf.js",
              "styles": [
                "src/styles.css",
                "node_modules/font-awesome/css/font-awesome.min.css",
                "node_modules/primeng/resources/themes/omega/theme.css",
                "node_modules/primeng/resources/primeng.min.css"
              ],
              "scripts": [],
              "assets": [
                "src/assets",
                "src/favicon.ico"
              ]
            }
          },
          "lint": {
            "builder": "@angular-eslint/builder:lint",
            "options": {
              "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
            }
          }
        }
      }
    }
  }

package.json

  {
    "name": "resource-planning",
    "version": "0.0.0",
    "license": "MIT",
    "scripts": {
      "ng": "ng",
      "start": "ng serve",
      "build": "ng build --prod",
      "test": "ng test",
      "lint": "ng lint",
      "e2e": "ng e2e"
    },
    "private": true,
    "dependencies": {
      "@angular/animations": "^19.0.5",
      "@angular/common": "^19.0.5",
      "@angular/compiler": "^19.0.5",
      "@angular/core": "^19.0.5",
      "@angular/forms": "^19.0.5",
      "@angular/platform-browser": "^19.0.5",
      "@angular/platform-browser-dynamic": "^19.0.5",
      "@angular/router": "^19.0.5",
      "@fortawesome/fontawesome-free": "^6.5.0",
      "core-js": "^3.32.2",
      "ngx-bootstrap": "^19.0.1",
      "primeicons": "^7.0.0",
      "primeng": "^19.0.1",
      "rxjs": "^7.8.0",
      "xlsx": "^0.18.5",
      "zone.js": "~0.15.0"
    },
    "devDependencies": {
      "@angular-devkit/build-angular": "^19.0.6",
      "@angular/cli": "^19.0.5",
      "@angular/compiler-cli": "^19.0.5",
      "@angular/language-service": "^19.0.5",
      "@eslint/config-array": "^0.19.1",
      "@eslint/object-schema": "^2.0.3",
      "@types/jasmine": "^4.5.0",
      "@types/jasminewd2": "^2.0.10",
      "@types/node": "^20.4.0",
      "angular-eslint": "19.0.2",
      "cypress": "^13.0.0",
      "eslint": "^9.16.0",
      "glob": "^9.0.0",
      "rimraf": "^4.0.0",
      "ts-node": "~10.9.1",
      "typescript": "~5.6.0",
      "typescript-eslint": "8.18.0"
    }
  }

app.module.ts

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { AppComponent } from './app.component';

    @NgModule({
    declarations: [
      AppComponent // Declare AppComponent here
    ],
    imports: [
      BrowserModule
    ],
    providers: [],
    bootstrap: [AppComponent]
    })
    export class AppModule { }

app.component.ts

  import { Component } from '@angular/core';

  @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
  })
  export class AppComponent {
    title = 'My Angular App';
  }

app-routing.module.ts

    import { Routes,RouterModule } from '@angular/router';
    import { NgModule } from '@angular/core';

    @NgModule({
        imports: [
            
        ],
        exports: [RouterModule]
    })
    export class AppRoutingModule {}

main.ts

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

  import { AppModule } from './app/app.module';
  import { environment } from './environments/environment';

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

  /*platformBrowserDynamic().bootstrapModule(AppModule)
    .catch(err => console.log(err));
  */

  console.log('App bootstrapping...');
  platformBrowserDynamic().bootstrapModule(AppModule)
    .catch(err => console.error('Error bootstrapping module:', err));

2 Answers 2

5

Not ready for standalone and just want my code to compile with non standalone components approach:

If you are not ready to go with standalone component, all you need to do is to add standalone: false to all your components. This can be easily achieved using vsCode find and replace feature, since we just add an extra property:

enter image description here


Problem:

In Angular 19, all components are by default standalone: true. If a component is standalone, it has to have its own imports and can work individually without relying on other parts of the application. We can add them to the imports array to use them.


Code fix to solve the problem, two ways:


If you want to use standalone component, then you should have a look at the below link:

Migrate an existing Angular project to standalone

ng g @angular/core:standalone

Migration code that helps you move to standalone components.


There are two possible fixes here.

Migrate to Angular standalone Approach (Recommended):

In this approach, you leave the component as standalone and the changes are made on main.ts, where we use bootstrapApplication to bootstrap the component (defaults to standalone), apart from this, we also use the ApplicationConfig object to add providers:

  • provideHttpClient -> required for http client to be available in dependency injection.

  • provideAnimations -> required for angular animations to work.

    import { bootstrapApplication } from '@angular/platform-browser';
    import { enableProdMode } from '@angular/core';
    import { AppComponent } from './app/app.component';
    import { environment } from './environments/environment';
    import { provideHttpClient } from '@angular/common/http';
    import { provideAnimations } from '@angular/platform-browser/animations';
    
    if (environment.production) {
      enableProdMode();
    }
    
    bootstrapApplication(AppComponent, {
      providers: [
        provideHttpClient(), // <- required for http client to work
        provideAnimations(), // <- required for animations to work
      ]
    })
      .catch(err => console.error('Error bootstrapping module:', err));
    

Continue using modular approach:

This approach requires less coding effort, we can simply set the AppComponent to standalone: false, by doing this we can bootstrap it using the appModule and it will work, but other parts of your code should try to use the standalone approach wherever needed. By manually setting the standalone to false, angular considers it as a non standalone component and bootstrapping using module works.

  import { Component } from '@angular/core';

  @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
    standalone: false,
  })
  export class AppComponent {
    title = 'My Angular App';
  }
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I already tried with standalone: false in the component section It doesnt help me.
4

You can try the steps mentioned in this Medium article:

  • In angular.json, under schematics, add the below lines:

    "schematics": {
        "@schematics/angular: component": {
            "standalone": false
        },
        "@schematics/angular:directive": {
            "standalone": false
        },
        "@schematics/angular: pipe" : {
            "standalone": false
        },
     }
    
  • Remove app.config.ts, app.config.server.ts and app.routes.ts.

  • Add app.routing.module.ts and copy all the Routes from app.routes.ts to the Routes in app.routing.module.ts.

  • In main.ts, replace:

    bootstrapApplication(AppComponent, appConfig).catch((err) =>console.error(err));
    

    to:

    platformBrowserDynamic().bootstrapModule(AppModule).catch(err =>console.error(err));
    

    And in here add the required import.

  • Delete everything from main.server.ts and paste the below line:

    export { AppServerModule as default } from ‘./app/app.module.server’;
    
  • In app.module.ts, under @NgModule, inside providers array, add the below line and import the required packages:

    provideClientHydration()
    

    Inside bootstrap array, add the below line and import the required packages:

    AppComponent
    

    Inside imports array, remove CommonModule and RouterOutlet then add below this line and import the required packages:

    BrowserModule,AppRoutingModule
    
  • Create a new file called app.module.server.ts with below lines:

     import { NgModule } from '@angular/core';
     import { ServerModule } from '@angular/platform-server';
    
     import { AppModule } from './app.module';
     import { AppComponent } from '../app.component';
    
     @NgModule({
       imports: [
         AppModule,
         ServerModule,
       ],
       bootstrap: [AppComponent],
     })
     export class AppServerModule {}
    
  • And finally in the respective component files, change standalone to false and remove import array.

Once you're done, you can build your project and then run it.

I hope this answer will help you!

Please note that these steps are tailored for Angular 17, but they should be largely applicable to Angular 19. So, you may need to adjust as needed for any version-specific differences.

3 Comments

Any feedback? Did this solution help you or did you find one by your own?
this works, but watch for a typo: app.config.server.ts should be app-config.server.ts (with a dash betwwen app and config)
Actually, it's a yes and a no: Angular CLI with v17+ generates the file as app.config.server.ts (dot-separated). But you can rename it also as app-config.server.ts if you want to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.