angularwebpack-4

No for InjectionToken Config in Angular Application after upgrading to webpack 4


I recently upgraded from Webpack 2 to 4. Webpack compiles, and most of the application works fine. It seems to of broken part of the application. I receive the error

NullInjectorError: No provider for InjectionToken config!

My module.ts file is as follows

import { enableProdMode, Inject, Injector, ErrorHandler } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
import { WsBootstrapService } from '../services/bootstrap';
import { WsBrandTypesService } from '../services/brandTypes';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule, UrlHandlingStrategy, UrlTree } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { HashLocationStrategy, LocationStrategy } from '@angular/common';
import { UpgradeModule, downgradeComponent, downgradeInjectable } from '@angular/upgrade/static';
import { HttpModule } from '@angular/http';
import {HttpClientModule} from '@angular/common/http';
import { BopisTabModule } from './bopis-tab/bopis-tab.module';
import { BopisContainerComponent } from './bopis-tab/bopis-container/bopis-container.component';
import { RewardsModule } from './rewards/rewards.module';
import { RewardsComponent } from './rewards/rewards.component';
import { TransactionHistoryComponent } from './rewards/transaction-history/transaction-history.component';
import { wsdebugProvider, wsbackendProvider, $rootScopeProvider } from './upgrade/injectables';
import { Ng1CcuiDirective } from './upgrade/components';

import './downgrade/downgrade.injectables';
import './downgrade/downgrade.components';
import './rxjs-operators';
import { UserService } from './services/user.service';
import { StoreService } from './services/store.service';
import { WindowRefService } from './services/window-ref.service';
import { FeatureToggleService } from './services/feature-toggle.service';
import { DateService } from './services/date.service';
import { SpinnerService } from './services/spinner.service';
import { AlertService } from './services/alert.service';
import { ExceptionOverlayComponent } from './exception-overlay/exception-overlay.component';
import { ExceptionOverlayService } from './services/exception-overlay.service';
import { ObjToArrayPipe } from './pipes/obj-to-array.pipe';
import { NgTwoErrorHandlerService } from './services/ng-two-error-handler.service';
import { BopisCriticalCountService } from './bopis-tab/services/bopis-critical-count.service';

class HybridUrlHandlingStrategy implements UrlHandlingStrategy {
    // use only process the `/hero` url
    shouldProcessUrl(url: UrlTree) { return true }
    extract(url: UrlTree) { return url; }
    merge(url: UrlTree, whole: UrlTree) { return url; }
}

@NgModule({
    declarations: [
        AppComponent,
        Ng1CcuiDirective,
        ExceptionOverlayComponent,
        ObjToArrayPipe
    ],
    entryComponents: [
        AppComponent,
        RewardsComponent,
        TransactionHistoryComponent
    ],
    imports: [
        BrowserModule,
        FormsModule,
        UpgradeModule,
        RouterModule.forRoot([]),
        HttpModule,
        BopisTabModule,
        RewardsModule,
        HttpClientModule
    ],
    providers: [
        { provide: ErrorHandler, useClass: NgTwoErrorHandlerService },
        wsdebugProvider,
        wsbackendProvider,
        $rootScopeProvider,
        { provide: 'WsBootstrapService', useClass: WsBootstrapService },
        { provide: 'WsBrandTypeService', useClass: WsBrandTypesService },
        UserService,
        StoreService,
        WindowRefService,
        FeatureToggleService,
        DateService,
        SpinnerService,
        AlertService,
        ExceptionOverlayService,
        NgTwoErrorHandlerService,
        BopisCriticalCountService
    ]
})

export class AppModule {
    constructor( @Inject(UpgradeModule) private upgrade: UpgradeModule) {
    }

    ngDoBootstrap() {
        this.upgrade.bootstrap(document.body, ['wsframework']);
    }

}

The full error message is

VM28381:4697 Error: StaticInjectorError(AppModule)[MaskService -> InjectionToken config]: 
  StaticInjectorError(Platform: core)[MaskService -> InjectionToken config]: 
    NullInjectorError: No provider for InjectionToken config!
    at _NullInjector.get (core.js:1224)
    at resolveToken (core.js:1522)
    at tryResolveToken (core.js:1464)
    at StaticInjector.get (core.js:1332)
    at resolveToken (core.js:1522)
    at tryResolveToken (core.js:1464)
    at StaticInjector.get (core.js:1332)
    at resolveNgModuleDep (core.js:11117)
    at NgModuleRef_.get (core.js:12350)
    at resolveDep (core.js:12840)

My package.json file is as follows

{
    "name": "ccui",
    "version": "1.0.0",
    "private": true,
    "description": "Care center UI.",
    "scripts": {
        "postinstall": "npm rebuild node-sass",
        "test:ng:ci": "npm run jest:ng --  --coverage --ci",
        "test:ng:dev": "npm run jest:ng --  --watch",
        "test:wc:ci": "npm run jest:wc --  --coverage --ci",
        "test:wc:dev": "npm run jest:wc --  --watch",
        "test:ci": "npm-run-all test:wc:ci test:ng:ci",
        "jest:ng": "jest --config ./jest/config.json ",
        "jest:wc": "jest --config ./jest/config.wc.json ",
        "prejest:ng": "npm run templatecache",
        "test": "npm-run-all --parallel test:wc:dev test:ng:dev ",
        "test:mvn": "npm run test:ci",
        "lint:ng2": "ng lint",
        "lint:ng1": "eslint ng1",
        "lint": "npm-run-all lint:ng2 lint:ng1",
        "build-ccui": "npm run build:prod",
        "rm:dist": "rimraf dist",
        "prebuild:dev": "npm-run-all rm:dist concat",
        "build:dev": "webpack --env.build=dev --progress --profile --colors",
        "rm:index": "rimraf ./index.html",
        "predev": "npm-run-all rm:index concat",
        "dev": "npm-run-all --parallel concat:watch  dev:server ",
        "dev:server": "webpack-dev-server --env.build=dev  --port=4200 ",
        "prebuild:prod": "npm-run-all rm:dist concat",
        "build:prod": "webpack --env.build=prod --progress --profile --colors",
        "concat": "gulp concat",
        "concat:watch": "gulp concat:watch",
        "templatecache": "gulp templatecache",
        "precommit": "npm run jest:ng -- -o && npm run jest:wc -- -o"
    },
    "engines": {
        "node": "8.1.0"
    },
    "keywords": [],
    "author": "WSI",
    "dependencies": {
        "@angular-devkit/core": "0.5.5",
        "@angular/animations": "5.2.9",
        "@angular/common": "5.2.9",
        "@angular/compiler": "5.2.9",
        "@angular/core": "5.2.10",
        "@angular/forms": "5.2.9",
        "@angular/http": "5.2.10",
        "@angular/platform-browser": "5.2.9",
        "@angular/platform-browser-dynamic": "5.2.9",
        "@angular/router": "5.2.9",
        "@angular/upgrade": "4.3.0",
        "@ngtools/webpack": "6.0.0-beta.8",
        "@webcomponents/webcomponentsjs": "1.0.22",
        "angular": "1.6.4",
        "angular-cookies": "1.6.4",
        "angular-i18n": "1.6.4",
        "angular-mocks": "1.6.4",
        "angular-route": "1.6.4",
        "angular-sanitize": "1.6.4",
        "angular-ui-mask": "1.8.7",
        "browser-split": "0.0.1",
        "class-list": "0.1.1",
        "core-js": "2.4.1",
        "font-awesome": "4.7.0",
        "html-element": "2.2.0",
        "identity-obj-proxy": "3.0.0",
        "jquery": "3.2.1",
        "lodash.clonedeep": "4.5.0",
        "lodash.flowright": "3.5.0",
        "lodash.intersection": "4.4.0",
        "lodash.isempty": "4.4.0",
        "lodash.isinteger": "4.0.4",
        "lodash.isplainobject": "4.0.6",
        "mitt": "1.1.3",
        "moment": "2.18.1",
        "moment-timezone": "0.5.13",
        "ngx-mask": "2.4.4",
        "npm": "5.8.0",
        "preact": "8.2.7",
        "primeng": "4.1.0",
        "raf": "3.4.0",
        "reflect-metadata": "0.1.10",
        "regenerator-runtime": "0.11.1",
        "rxjs": "5.5.2",
        "source-map-loader": "0.2.3",
        "webpack-cli": "2.0.13",
        "zone.js": "0.8.11"
    },
    "devDependencies": {
        "@angular-devkit/build-optimizer": "0.5.6",
        "@angular/cli": "1.7.2",
        "@angular/compiler-cli": "5.2.9",
        "@skatejs/ssr": "0.19.1",
        "@types/jasmine": "2.5.36",
        "@types/jest": "22.1.3",
        "@types/node": "6.0.73",
        "add-stream": "1.0.0",
        "babel-core": "6.26.0",
        "babel-loader": "7.1.2",
        "babel-plugin-root-import": "5.1.0",
        "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
        "babel-plugin-transform-react-jsx": "6.24.1",
        "babel-preset-env": "1.6.1",
        "babel-preset-es2015": "6.24.1",
        "babel-preset-stage-3": "6.24.1",
        "circular-dependency-plugin": "5.0.2",
        "codelyzer": "3.1.2",
        "copy-webpack-plugin": "4.5.1",
        "css-loader": "0.28.4",
        "eslint": "4.15.0",
        "eslint-plugin-angular": "3.1.1",
        "extract-text-webpack-plugin": "4.0.0-beta.0",
        "file-loader": "1.1.11",
        "gulp": "3.9.1",
        "gulp-angular-templatecache": "2.0.0",
        "gulp-concat": "2.6.1",
        "html-loader": "0.5.5",
        "html-webpack-plugin": "3.0.7",
        "husky": "0.14.3",
        "jasmine-marbles": "0.2.0",
        "jasmine-spec-reporter": "4.1.1",
        "jest": "21.2.1",
        "jest-preset-angular": "4.0.1",
        "jest-sonar-reporter": "1.3.0",
        "license-webpack-plugin": "1.3.1",
        "lodash": "4.17.4",
        "node-sass": "4.8.3",
        "npm-run-all": "4.1.2",
        "null-loader": "0.1.1",
        "postcss-loader": "2.1.3",
        "postcss-url": "7.3.2",
        "promise.prototype.finally": "3.0.0",
        "protractor": "4.0.14",
        "raw-loader": "0.5.1",
        "rimraf": "2.6.1",
        "sass-loader": "6.0.6",
        "script-loader": "0.7.2",
        "smart-banner-webpack-plugin": "3.0.1",
        "style-loader": "0.13.2",
        "ts-node": "3.0.6",
        "tslint": "5.4.3",
        "typescript": "2.4.2",
        "uglifyjs-webpack-plugin": "1.2.4",
        "webpack": "4.4.1",
        "webpack-dev-server": "3.1.1",
        "write-file-webpack-plugin": "4.2.0"
    },
    "repository": {},
    "jestSonar": {
        "reportPath": "coverage",
        "reportFile": "unit-tests.xml",
        "indent": 4
    }
}

I appreciate any and all help.


Solution

  • Looking over the ngx-mask library, it seems like you forgot to import the library using the forRoot() version to set up the config provider that the MaskService needs. Adding this to your AppModule should solve it (according to the library's documentation):

    import {NgxMaskModule} from 'ngx-mask';
    
    @NgModule({
      (...)
      imports: [
        NgxMaskModule.forRoot(options)
      ]
      (...)
    })
    

    Note: The options parameter is optional.