Angular-builders: Different webpack.config.js files for different configurations not working with v9.2

Created on 25 Sep 2020  路  8Comments  路  Source: just-jeb/angular-builders

Hello,
attempting to implement your recommended angular.json for different webpack configurations per https://github.com/just-jeb/angular-builders/issues/248#issuecomment-466650709

   "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "outputPath": "dist/electron-angular-native",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.png",
              "src/assets"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
                "customWebpackConfig": {
                    "path": "./prod-webpack.config.js"
                },
            },
            "development": {
                "customWebpackConfig": {
                    "path": "./dev-webpack.config.js"
                },
            }
          }
        },

Unfortunately, with v9.20 I can't get the webpack.config.js files to be picked up unless they're specified within the top-level options.

I can get it running with dev defaults only:

   "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
                "path": "./dev-webpack.config.js"
            },
            "outputPath": "dist/electron-angular-native",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.png",
              "src/assets"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
                "customWebpackConfig": {
                    "path": "./prod-webpack.config.js"
                },
            },
            "development": {
            }
          }
        },

.. but then prod-webpack.config.js is ignored when building with --configuration=production

Most helpful comment

Hi, just an update for those who found this after Angular 11.1.0 release:
You will probably need to use AngularWebpackPlugin instead of AngularCompilerPlugin.

For example in my case it looks like this:

import { AngularWebpackPlugin } from '@ngtools/webpack/src/ivy/plugin';

...
  const index = config.plugins?.findIndex((p) => {
    return p instanceof AngularWebpackPlugin;
  });
  if (index) {
    // @ts-expect-error pluginOptions is a private property
    const oldOptions = config.plugins?.[index].pluginOptions;
    oldOptions.directTemplateLoading = false;
    config.plugins?.splice(index);
    config.plugins?.push(new AngularWebpackPlugin(oldOptions));
  }

All 8 comments

My apologies - it's not ignored, it's just that my particular production config doesn't play nicely with aot compilation.

@DaveA-W did you happen to find a workaround? I'm having the same issue where the customWebpackConfig path in my configurations aren't being used.

My problem was that my custom prod-webpack.config.js had module rules to try and transform *.html templates as described in this Medium article.

var path =  require('path');

module.exports = {
  module: {
    rules: [{
      test: /\.html$/,
      use: ['data-cy-loader']
    }]
  },
  resolveLoader: {
    alias: {
      'data-cy-loader': path.join(__dirname, 'data-cy-loader.js')
    }
  }
}

This config file _was_ being loaded correctly.

However, if your production config options specify ahead-of-time aot: true compilation (which most prod configs for Angular 8+ do) then .html templates don't get processed the same way they do for just-in-time (JIT) builds which is what you may be using for ng serve.

If your issue looks to be related - i.e., your customWebpackConfig is trying to transform .html templates - then this discussion gives some leads that may be worth following up: https://github.com/IAMtheIAM/angular-webpack-nodejs-starter/issues/4

You can still apply loaders on your .html files by disabling direct templates loading.

Thanks for the tip @just-jeb, I'll try that out!

I imagine custom html loaders would be a common use case for people that install @angular-builders/custom-webpack. Could be worth a mention in the readme.md.

Hi @just-jeb following your links I was able to disable direct templates loading using this webpack.config.prod.ts:

import { AngularCompilerPlugin } from '@ngtools/webpack/src';
import * as path from 'path';
import * as webpack from 'webpack';

export default (config: webpack.Configuration): webpack.Configuration => {
  const index = config.plugins.findIndex(p => p instanceof AngularCompilerPlugin);
  const options = { ...config.plugins[index]._options, directTemplateLoading: false };
  config.plugins.splice(index);
  config.plugins.push(new AngularCompilerPlugin(options));

  config.module.rules.push({
    test: /\.html$/,
    use: [
      { loader: 'raw-loader' },
      { loader: path.resolve('./data-cy-loader.ts') },
    ],
  });

  return config;
};

Note that I first tried your alternative recommendation to just use a config delta but I did not have any success. Similar to this poster I couldn't get past the compiler TypeError: Cannot read property 'getTypeChecker' of undefined.

I'm also experiencing problems loading .svg templateUrls. I can't quite hit on a webpack.config combination that works across JIT and AOT builds for both regular svg loading and _also_ emulating the templateUrl handling triggered by { directTemplateLoading: true }. So for now I've resorted to inlining my svg templates where I use them.

Any further tips appreciated!

Not sure I understand your problem with SVGs, but maybe this can serve as an inspiration.

Hi, just an update for those who found this after Angular 11.1.0 release:
You will probably need to use AngularWebpackPlugin instead of AngularCompilerPlugin.

For example in my case it looks like this:

import { AngularWebpackPlugin } from '@ngtools/webpack/src/ivy/plugin';

...
  const index = config.plugins?.findIndex((p) => {
    return p instanceof AngularWebpackPlugin;
  });
  if (index) {
    // @ts-expect-error pluginOptions is a private property
    const oldOptions = config.plugins?.[index].pluginOptions;
    oldOptions.directTemplateLoading = false;
    config.plugins?.splice(index);
    config.plugins?.push(new AngularWebpackPlugin(oldOptions));
  }
Was this page helpful?
0 / 5 - 0 ratings