Tutorial
Angular CLI: Custom webpack Config
While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.
The Angular CLI gives us all sorts of power. One of these powers is the ability to forget about the webpack configuration process. This is great for most applications, but what if you want to add custom webpack functionality? This article looks at how we can achieve just that.
New Angular Application
To establish a common base, we’ll create a new Angular application with the Angular CLI:
# Install the Angular CLI globally
$ npm i @angular/cli -g
# Create a new Angular project with a name of your choosing && change directory
$ ng new AngularCustomWebpackConfig
> N
> SCSS
$ cd AngularCustomWebpackConfig
# Open this up in VS Code and Serve
$ code . && ng serve
A common dependency to many projects is the date library - moment.js
. This includes the ability to work with locales, but, it adds quite a bit to the overall bundle size.
Thankfully - there’s a webpack plugin which removes unnecessary locales. We’ll be using it in this project.
Dependencies
In order to use a custom webpack config, we’ll need the @angular-builders/custom-webpack
dependency. Add it to your project as a devDependency
like so:
$ npm i @angular-builders/custom-webpack -D
We can then install moment
to our project and import this into our project:
$ npm i moment --save
Custom webpack Configuration
We can then create a custom webpack configuration that rips out any locales that we don’t specifically choose to keep.
Inside of the root of your project, create a new file named custom-webpack.config.js
with the following:
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
module.exports = {
plugins: [
new MomentLocalesPlugin({
localesToKeep: ['fr']
})
]
};
This requires us to install the moment-locales-webpack-plugin
:
$ npm i moment-locales-webpack-plugin -D
Adding this to angular.json
Afterwards, we need to configure angular.json
to use this new configuration. Inside of the architect/build
object, update the builder
from @angular-devkit/build-angular:browser
to @angular-builders/custom-webpack:browser
and add the customWebpackConfig
key:
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./custom-webpack.config.js",
"replaceDuplicatePlugins": true
}
}
}
}
Custom webpack Configuration When Using ng serve
This is all we need to do if we only want our final, built, application to use the webpack config. However, if we wanted to test this config while using ng serve
, we have one more thing to do.
Install the @angular-builders/dev-server
custom web server from within npm
:
$ npm i @angular-builders/dev-server -D
We can then update this inside of serve/builder
in the angular.json
file:
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server"
}
Testing
Let’s check to see whether this works as intended! Head over to app.component.ts
and set the locale to fr
import { Component, OnInit } from '@angular/core';
import * as moment from 'moment'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
currentTimeFRLocale: string;
ngOnInit(): void {
moment.locale('fr');
this.currentTimeFRLocale = moment().format('LLL');
}
}
Then we can display this inside of app.component.html
:
<h1>{{ currentTimeFRLocale }}</h1>
Great. We’re able to see the current date and time with the fr
locale, as we’ve specifically told moment
to keep this with the plugin.
Let’s remove this from the custom-webpack.config.js
and select a different locale:
module.exports = {
plugins: [
new MomentLocalesPlugin({
localesToKeep: ['de']
})
]
};
You’ll need to restart the application with ng serve
for the application to update.
The locale has disappeared from the bundle! You’ll also notice that the bundle size is significantly smaller with this extra configuration than without.
Here’s the results without the configuration:
chunk {main} main.js, main.js.map (main) 22.6 kB [initial] [rendered]
Here’s the results with the configuration:
chunk {main} main.js, main.js.map (main) 10.2 kB [initial] [rendered]