4

I'm trying to remove unnecessary Cypress attributes from html files in Angular 7 application.

I found this SOLUTION

So I added to my angular.json:

"build": {
  "builder": "angular-cli-builders:custom-webpack-browser",
  "options": {
    "customWebpackConfig": {
      "path": "./webpack/webpack.extra.js",
      "mergeStrategies": {
        "externals": "append"
      }
    },

and attributes are removed when I use ng build, but when I'll use ng build --prod then attributes are not removed, why?

I was trying to add it here too, no success:

 "configurations": {
   "production": {
     "customWebpackConfig": { [...]
DiPix
  • 5,755
  • 15
  • 61
  • 108

2 Answers2

0

@angular-builders/custom-webpack has four options depending on your build (universal, dev, etc). It is actually quite easy once you read these simple instructions.

Jonathan
  • 3,893
  • 5
  • 46
  • 77
-1

The solution on Medium referenced in this question is out of date for Angular 8+.

Firstly, the angular-cli-builders npm package is deprecated. You will need the version of @angular-builders/custom-webpack that is appropriate for your Angular version instead.

Then, if your builds are using ahead-of-time compilation - which most production configurations will - then it is very difficult to intercept and replace the data-cy attributes within source .html files. The only way I could reliably get this to work was to examine the built .js output, and replace the attributes within there instead.

Here's the relevant parts of a working angular.json file for Angular 9:

{
  "projects": {
    "datacy": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "sourceMap": true,
            "namedChunks": true
          },
          "configurations": {
            "production": {
              "customWebpackConfig": {
                "path": "./webpack-config.prod.ts",
                "mergeStrategies": {
                  "module.rules": "prepend"
                }
              },
              "optimization": true,
              "aot": true,
              ...

webpack.config.prod.ts

import * as path from 'path';
import * as webpack from 'webpack';

export default {
  module: {
    rules: [{
      test: /\.js$/,
      use: [{ loader: path.resolve('./data-cy-loader.ts') }],
    }],
  },
} as webpack.Configuration;

data-cy-loader.ts

/*
  HTML formatting looks like <element data-cy="value">
  Inlined within a javascript string, it looks like <element data-cy=\"value\">

  Compiled AOT, the element attributes are turned into an array:
    [["class", "cssClassName"], ["data-cy", "value"], ...]

  The data-cy attribute may appear at the start, middle, or end of this array.
*/
export default (source: string) => {
  if (source.indexOf('data-cy') >= 0) {
    return source.replace(/\["data-cy" ?,"([^"]*)"\],/g, '')              // ["data-cy", "..."], variants
                 .replace(/, ?\["data-cy", ?"([^"]*)"\]/g, '')            // , ["data-cy", "..."]] variant
                 .replace(/(\[")?data-cy(=|(",))\\?"([^"]*)"(\])?/g, ''); // [["data-cy","..."]] and html variants
  }
  return source;
};
Dave A-W
  • 609
  • 7
  • 13