angular-cli-builders

Since Angular 6, there’s the possibility to hook into the compilation process using builders. The angular-cli-builders package does this for you and allows for adding a custom webpack configuration, including all the benefits you can imagine from a vanilla webpack setup.

The goal here, is to create a webpack config that checks each HTML file and runs a loader that will strip the data-cy attribute using a Regular Expression.

There are several files that need to be modified in order for this to work, starting with the package.json.

npm i angular-cli-builders --save-dev

This installs the package and modifies the package.json.

The angular.json embeds the project’s workspace and decides which transformations are used, which builders are used, and much more.

Consider lines 14 through 21, this selects the angular-cli-builder’s custom webpack browser and configures a file called webpack.extra.js to be appended to the existing internal Angular webpack configuration.

"builder": "angular-cli-builders:custom-webpack-browser",

"options": {

"customWebpackConfig": {

"path": "./webpack.extra.js",

"mergeStrategies": {

"externals": "append"

}

},

Line 55 allows you to hook into the serve process as well, leveraging the build configuration.

"builder": "angular-cli-builders:generic-dev-server",

The webpack.extra.js file needs to be created at the root of your project.

Here we can see the test for HTML files and the usage of the data-cy-loader, which is resolved using the data-cy-loader.js file.

This file tests the incoming source (HTML) for the existence of the [data-cy] attribute and replaces it with an empty string, removing it before it is even bundled.

This brings more advantages to the table, even unlimited advantages, since we can now freely choose whatever we want to do during the bundling process.

For example:

Generate a timestamp or watermark on each generated HTML page.

Prepend each JavaScript file with a certain line.

Ensure all debugger statements are purged from the source

…

Custom webpack plugins make this approach even more extensive.