Loading Posts...

Customizing Angular CLI build — an alternative to ng eject (v2)

Customizing Angular CLI build — an alternative to ng eject (v2)

Customizing Angular CLI build — an alternative to ng eject (v2)

Important:

This is an updated version of Customizing Angular CLI build — an alternative to ng eject. The article is relevant for Angular 8+.

So your Angular CLI project just went a bit beyond TODO app and you have to customize your build configuration.
The question is how?

Angular CLI 1.x ng eject VS Angular CLI builders

In Angular CLI 1.x up to Angular 5 you had ng eject command for this, which was ejecting the whole underlying webpack configuration and allowing you to modify it as you please.

In Angular CLI 6 this command has been removed, and it is not coming back. Instead Angular CLI exposes an API for developers allowing them to hook into the build process by providing their own builders.
With the new Angular CLI you can customize the build process by defining your own builders as well as using one of the builders provided by the community.

Extending underlying Webpack configuration

So let’s go ahead and customize our build by extending the underlying Webpack configuration:

  • Install @angular-builders/custom-webpack:
    npm i -D @angular-builders/custom-webpack.
    Note that it requires @angular-devkit/build-angular>=0.800.0 so you might need to install it (if not yet installed):
    npm i -D @angular-devkit/build-angular
  • In angular.json change the @angular-devkit/build-angular:browser builder to @angular-builders/custom-webpack:browser :
"architect": {
...
"build": {
"builder": "@angular-builders/custom-webpack:browser"
"options": {
...
}
...
}
  • If you build a universal app and would like to modify your server build configuration use @angular-builders/custom-webpack:server instead of @angular-builders/custom-webpack:browser
  • Add customWebpackConfig to the build target options :
"architect": {
...
"build": {
"builder": "@angular-builders/custom-webpack:browser"
"options": {
"customWebpackConfig": {
"path": "./extra-webpack.config.js"
}
...
}
...
}

Check out the full description of customWebpackConfig object here.

  • Create extra-webpack.config.js in the root of your application (or whatever path you specified in angular.json).
  • Fill it with extra configuration you need (plain Webpack configuration).
  • Note that in contrary tong eject this configuration will be merged with the default Angular build configuration so you only have to configure the part you want to change/add.
    For example, if you want to add another Webpack loader, your Webpack config will look like this:
module.exports = {
module: {
rules: [
{
test: /.cool$/,
use: 'cool-loader'
}
]
}
};
  • Run ng build

Advanced webpack configuration

There are use cases when just merging the delta of Webpack config is not enough.
If it’s just a matter of multiple configurations (use one build config for development another for staging etc.) you can just keep these configurations in separate files and utilize the configurations option of build target.

However, sometimes it’s still not enough.
When you have a complicated logic for modifying your build configuration you can export a function from custom-webpack.config.js rather than exporting an object.
The function receives base Webpack config and the builder options as parameters and returns a modified config. No merge performed.
For example:

const webpack = require('webpack');
const pkg = require('./package.json');

module.exports = (config, options) => {
config.plugins.push(
new webpack.DefinePlugin({
'APP_VERSION': JSON.stringify(pkg.version),
}),
);

return config;
};

Modifying index.html

Since Angular CLI 8 index.html is not generated as part of Webpack build. This means that you cannot modify index.html by modifying Webpack config.
Instead you should use indexTransform option. This option allows you to provide a function that transforms index.html (either synchronously or not).

So what do you have to do:

module.exports = async (targetOptions, indexHtmlContent) => {
//your transformation here
return newIndexHtmlContent;
}

Note that it doesn’t have to be async .

  • Modify the builder and add indexTransform option in angular.json :
"architect": {
...
"build": {
"builder": "@angular-builders/custom-webpack:browser"
"options": {
"indexTransform": "./index-html-transform.js"
...
}
...
}
  • Run ng build

And what about ng serve?

Just replace @angular-devkit/build-angular:dev-server inside the serve target with @angular-builders/custom-webpack:dev-server .
Now if you run ng serve the build will use the config you’ve specified in browser target.

Additional sources

You can check out this example project which uses customWebpackConfig as well as indexTransform .

What is next

In the next article we will learn how to create your own builder.


Customizing Angular CLI build — an alternative to ng eject (v2) was originally published in Angular In Depth on Medium, where people are continuing the conversation by highlighting and responding to this story.

Get Free Email Updates!

Signup now and receive an email once I publish new content.

I agree to have my personal information transfered to MailChimp ( more information )

I will never give away, trade or sell your email address. You can unsubscribe at any time.

user

The author didnt add any Information to his profile yet

Loading Posts...