我正在将旧的 Angular 项目从版本 5 迁移到版本 19。我已经识别了所有兼容和依赖的库,并且能够迁移代码。但是我不断收到独立错误。
该项目基于 NgModule,我想按原样使用,而不需要像现在这样的独立功能。
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
为了深入研究该问题,我根据实际创建了最小的项目并重现了该问题。我在 angular.json 中添加了独立的 false,清除缓存,删除了节点模块,验证了 ts 是否没有独立文件。然而,这对我来说已经成为噩梦,因为从过去两天开始我无法修复它。
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));
在 Angular 19 中,所有组件都是默认的
standalone: true
。如果一个组件是独立的,它必须有自己的导入,并且可以单独工作而不依赖于应用程序的其他部分。我们可以将它们添加到导入数组中来使用它们。
了解更多:
这里有两个可能的修复方法。
在这种方法中,您将组件保留为独立组件,并在
main.ts
上进行更改,其中我们使用 bootstrapApplication
来引导组件(默认为独立组件),除此之外,我们还使用 ApplicationConfig
对象来添加提供商:
provideHttpClient
-> 需要 http 客户端才能在依赖注入中可用。
provideAnimations
-> 需要角度动画才能工作。
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));
这种方法需要较少的编码工作,我们可以简单地将
AppComponent
设置为 standalone: false
,通过这样做,我们可以使用 appModule 引导它并且它会工作,但是代码的其他部分应该尝试在任何地方使用独立方法需要。如果手动将 standalone
设置为 false
,Angular 将其视为非独立组件,并且可以使用模块进行引导。
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';
}