Skip to content

@ngtools/webpack AOT build mode fails to inject value when it's actually an object property when using forRoot #8600

@xaralis

Description

@xaralis

Versions

Node: 8.1.4
Angular CLI: 1.8.3
Angular: 5.0.2
TypeScript: 2.4.2

@ngtools/webpack: 1.8.3
@webpack: 3.8.1

Webpack config quite basic:

...
rules: [{
                test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                loader: '@ngtools/webpack',
}],
plugins: [
        new AngularCompilerPlugin({
            tsConfigPath: helpers.root(`tsconfig.cs.json`),
            sourcemap: true,
        }),
],
...

tsconfig.cs.json:

{
    "compileOnSave": false,
    "compilerOptions": {
        "outDir": "./aot/cs/out-tsc",
        "baseUrl": "src",
        "sourceMap": true,
        "declaration": false,
        "moduleResolution": "node",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": true,
        "target": "es5",
        "paths": {
            "@angular/*": ["../node_modules/@angular/*"]
        },
        "typeRoots": [
            "node_modules/@types"
        ],
        "lib": [
            "es2017",
            "dom"
        ],
        "strict": true
    },
    "exclude": [
        "aot/**/*",
        "!aot/cs/",
        "node_modules",
        "dist",
        "src/**/*.spec.ts",
        "src/**/*.e2e.ts"
    ],
    "angularCompilerOptions": {
        "genDir": "./aot/cs/",
        "skipMetadataEmit": true,
        "entryModule": "src/app/app.module#AppModule",
        "i18nInFormat": "xlf",
        "i18nInLocale": "cs",
        "i18nInFile": "src/assets/i18n/cs/d21-web-platform.xlf",
        "i18nInMissingTranslations": "ignore"
    }
}

Repro steps

  • Create following module:
import { NgModule, Inject, Injectable, InjectionToken, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';

export interface Config {
    someProperty: string;
    otherProperty: string;
}

export const ConfigToken = new InjectionToken<Config>('ConfigToken');

@Injectable()
export class Service {
    constructor(@Inject(ConfigToken) config: Config) {
        console.log(config);
    }
}

@NgModule({
    imports: [
        CommonModule,
    ]
})
export class TestModule {
    static forRoot(config: Partial<Config> = {}): ModuleWithProviders {
        return {
            ngModule: TestModule,
            providers: [
                {provide: ConfigToken, useValue: config},
                {provide: Service, useClass: Service, deps: [ConfigToken]},
            ]
        }
    }
}
  • Use this module in your app, providing configuration using forRoot, supplying property of an object
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

const configDeep = {
    deepProp: 'value'
};

@NgModule({
    imports: [
        TestModule.forRoot({
            someProperty: configDeep.deepProp,
        }),
    ]
})
export class AppModule {}

Observed behavior

When importing Service, it should report {someProperty: 'value'}.

Desired behavior

When importing Service, it reports {someProperty: null}.

Mention any other details that might be useful (optional)

I'm using @ngtools/webpack angular plugin, not angular-cli as a whole.

This only happens when using forRoot. If the ConfigToken value is provided from AppModule providers property, it works as it should.

When using immediate value (e.g. not a property of an object), everything is OK too.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions