'"Cannot read property 'flags' of undefined" with custom-webpack and istanbul-instrumenter-loader

My goal is to get dynamic code coverage of Protractor (v 7) E2E tests within Angular 12.

I'm following this thread: Code coverage for Protractor tests in Angular 5 Application

It is said, that https://www.npmjs.com/package/protractor-istanbul-plugin would not work with Angular 12, so I'm trying customWebpackConfig & istanbul-instrumenter-loader, but am stuck with the following error, when trying to build the project. I realy struggle with setting up things like this, so any help would be greatly appreciated!!

Errormessage

ng build

Generating browser application bundles (phase: setup)...
An error occurred during the build:
TypeError: Cannot read property 'flags' of undefined
    at checkUnreachable (myprojectpath\node_modules\typescript\lib\typescript.js:43458:31)
    at bindChildren (myprojectpath\node_modules\typescript\lib\typescript.js:40978:17)
    at bind (myprojectpath\node_modules\typescript\lib\typescript.js:42548:21)
    at bindSourceFile (myprojectpath\node_modules\typescript\lib\typescript.js:40523:17)
    at Object.bindSourceFile (myprojectpath\node_modules\typescript\lib\typescript.js:40460:9)
    at initializeTypeChecker (myprojectpath\node_modules\typescript\lib\typescript.js:79672:20)
    at Object.createTypeChecker (myprojectpath\node_modules\typescript\lib\typescript.js:44614:9)
    at Object.getTypeChecker (myprojectpath\node_modules\typescript\lib\typescript.js:107350:79)
    at new NgCompiler (myprojectpath\node_modules\@angular\compiler-cli\src\ngtsc\core\src\compiler.js:199:99)
    at Function.NgCompiler.fromTicket (myprojectpath\node_modules\@angular\compiler-cli\src\ngtsc\core\src\compiler.js:238:28)
    at new NgtscProgram (myprojectpath\node_modules\@angular\compiler-cli\src\ngtsc\program.js:95:47)
    at AngularWebpackPlugin.updateAotProgram (myprojectpath\node_modules\@angular-builders\custom-webpack\node_modules\@ngtools\webpack\src\ivy\plugin.js:310:32)
    at myprojectpath\node_modules\@angular-builders\custom-webpack\node_modules\@ngtools\webpack\src\ivy\plugin.js:187:24
    at Hook.eval [as call] (eval at create (myprojectpath\node_modules\@angular-builders\custom-webpack\node_modules\tapable\lib\HookCodeFactory.js:19:10), <anonymous>:24:1)
    at Hook.CALL_DELEGATE [as _call] (myprojectpath\node_modules\@angular-builders\custom-webpack\node_modules\tapable\lib\Hook.js:14:14)
    at Compiler.newCompilation (myprojectpath\node_modules\@angular-builders\custom-webpack\node_modules\webpack\lib\Compiler.js:1043:30)
An unhandled exception occurred: Cannot read property 'flags' of undefined

My configuration

myprojectpath\package.json

"devDependencies": {
    "@angular-builders/custom-webpack": "^12.0.0",
    "@angular-builders/dev-server": "^7.0.0",
    "@angular/cli": "~12.0.5",
    "@angular/compiler-cli": "~12.0.5",
    "@types/jasmine": "~3.8.0",
    "@types/node": "^12.11.1",
    "browserify-istanbul": "^3.0.1",
    "istanbul-instrumenter-loader": "^3.0.1",
    "jasmine-core": "~3.7.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.6.0",
    "typescript": "~4.2.3"
  }

myprojectpath\angular.json

     "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            ...
            "customWebpackConfig": {"path": "./custom-webpack.config.js"}
          },

myprojectpath\custom-webpack.config.js

const path = require("path");
 
module.exports = {
  module: {
    rules: [
      {
          test: /\.js$/, //TODO: should this point to the test subdir? Problem: unexpected token when trying to add the slash for the dir
          use: {
            loader: 'istanbul-instrumenter-loader',
            options: {
                //
            }
          }
      }
    ]
  }
};

myprojectpath\test\conf.js

exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['todo-spec.js']
};

myprojectpath\test\todo-spec.js

describe('demo test', function() {
  it('describtion', function() {
    browser.get('http://localhost:4200/');

    expect(...);
  });
});

Next steps according to the original thread would be

  1. Run your e2e/IT test suit on the instrumented bundle
webdriver-manager start
test\protractor conf.js
  1. Collect your istanbul coverage(window.__ coverage__) json from browser context & save it as coverage.json file. Genarate viewable report using istanbul comments istanbul report(istanbul should be installed globally),It will generate coverage/lcov-report folder with html files to view the code coverage report for each files.


Solution 1:[1]

I now are able to build the solution. My packages.json now looks like this:

  "devDependencies": {
    "@angular-builders/custom-webpack": "^12.0.0",
    "@angular-builders/dev-server": "^7.0.0",
    "@angular-devkit/build-angular": "~12.2.16",
    "@angular/cli": "~12.2.16",
    "@angular/compiler-cli": "~12.2.0",
    "@types/jasmine": "~3.8.0",
    "@types/node": "^12.11.1",
    "istanbul-instrumenter-loader": "^3.0.1",
    "jasmine-core": "~3.8.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",
    "protractor": "~7.0.0",
    "typescript": "~4.3.5"
  }

I also had to increase the budget size within the angular.json and had to dig into the source code of the istanbul-instrumenter-loader to allow for import and exports being defined anywhere:

\node_modules\istanbul-instrumenter-loader\node_modules\istanbul-lib-instrument\dist\instrumenter.js:121

   var ast = babylon.parse(code, {
        allowReturnOutsideFunction: opts.autoWrap, allowImportExportEverywhere: true, //CUSTOM EDIT: added allowImportExportEverywhere here
        sourceType: opts.esModules ? "module" : "script",
        plugins: ['asyncGenerators', 'dynamicImport', 'objectRestSpread', 'flow', 'jsx']
    });

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Stacker234