【问题标题】:Angular Dependency Injection does not work with WebpackAngular 依赖注入不适用于 Webpack
【发布时间】:2021-12-29 11:58:37
【问题描述】:

我遇到一个问题,当我使用 Webpack 构建项目时,Angular Dependency Injection 不起作用。

我使用 Angular 13Webpack 5,我使用 @Injectable 装饰器来标记服务类并将其传递给组件构造函数:

@Injectable({  providedIn: 'root'})
export class DITestService {
  
  constructor() { }
  
  getTitle(){
    return "DI testing";
  }
}

@Component({
  selector: 'app-root',
  template: '<div>Title: {{ title }}</div>'
})
export class AppComponent {  
  public title: string = this.diTestService.getTitle();  
  
  constructor(private diTestService: DITestService)  
  {  }
}

运行项目时出现以下错误:

错误:此构造函数与 Angular 依赖注入不兼容,因为它在参数列表索引 0 处的依赖无效。 如果依赖类型是像字符串这样的原始类型,或者此类的祖先缺少 Angular 装饰器,则可能会发生这种情况。

请检查 1) 索引 0 处的参数类型是否正确,以及 2) 为此类及其祖先定义了正确的 Angular 装饰器。

当我通过 Angular CLI 运行同一个项目时,没有 Webpack,它工作正常。

当我在组件构造函数中使用 @Inject 装饰器并使用 Webpack 构建项目时,它也可以正常工作。

constructor(@Inject(DITestService) private diTestService: DITestService)

是否可以在没有 @Inject 装饰器的情况下将 Webpack 配置为使用依赖注入?

我的测试项目详情如下:

app.component.ts

import { Component } from '@angular/core';
import { DITestService } from './ditest-service.service';

@Component({
  selector: 'app-root',
  template: '<div>Title: {{ title }}</div>'
})
export class AppComponent {  
  public title: string = this.diTestService.getTitle();  
  
  constructor(private diTestService: DITestService)  
  {  }
}

ditest-service.service.ts

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

@Injectable({  providedIn: 'root'})
export class DITestService {
  
  constructor() { }
  
  getTitle(){
    return "DI testing";
  }
}

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

import { DITestService } from './ditest-service.service';

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

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AngularTest1</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <app-root></app-root>
</body>
</html>

ma​​in.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.error(err));

polyfills.ts

import 'zone.js'; 

package.json

{
  "name": "angular-test1",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "webpack_serve": "webpack serve --mode development",
    "webpack_build": "webpack --mode production"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~13.0.0",
    "@angular/common": "~13.0.0",
    "@angular/compiler": "~13.0.0",
    "@angular/core": "~13.0.0",
    "@angular/forms": "~13.0.0",
    "@angular/platform-browser": "~13.0.0",
    "@angular/platform-browser-dynamic": "~13.0.0",
    "@angular/router": "~13.0.0",
    "rxjs": "~7.4.0",
    "tslib": "^2.3.0",    
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~13.0.4",
    "@angular/cli": "~13.0.4",
    "@angular/compiler-cli": "~13.0.0",
    "@types/jasmine": "~3.10.0",
    "@types/node": "^12.11.1",
    "angular2-template-loader": "^0.6.2",
    "html-webpack-plugin": "^5.5.0",
    "jasmine-core": "~3.10.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "~1.7.0",
    "ts-loader": "^9.2.6",
    "typescript": "~4.4.3",
    "webpack": "^5.65.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.7.1"
  }
}

tsconfig.json

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist",
    "forceConsistentCasingInFileNames": true,
    "strict": false,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2020",
    "module": "es2020",
    "lib": [
      "es2020",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": false,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        'polyfills': './src/polyfills.ts',
        'app': './src/main.ts'
    },
    output:{
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/',
        filename: '[name].[fullhash].js'
    },
    devServer: {
        historyApiFallback: true,
        port: 40042,
        open: false
    },
    resolve: {
        extensions: ['.ts', '.js']
    },
    module:{
        rules:[
            {
                test: /\.ts$/,
                use: [
                    'ts-loader',
                    'angular2-template-loader'
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'src/index.html'
        })
    ]
}

【问题讨论】:

  • 使用 AngularCompilerPlugin 是可能的(它转换 Angular 模板并且一些转换也在 ts 类上完成)。但我相信在 99.9% 的情况下,这不是正确的方法。您能否描述一下您需要直接应用 webpack 的原因,以便社区可以就如何解决您的问题给您更好的建议?
  • 非常感谢!有用。至于你的问题:我有一个基于 Angular 6 构建的旧项目,现在我正试图在 Angular 的最新版本上重建它。
  • ng cli 在大多数情况下都能构建您的项目

标签: angular webpack dependency-injection


【解决方案1】:

正如 cmets 中所建议的那样:

使用 AngularCompilerPlugin 是可能的(它转换角度模板,并且一些转换也在 ts 类上完成)。

npmjs.com/package/@ngtools/webpack

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 2012-12-31
    • 2017-06-16
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-07
    相关资源
    最近更新 更多