{"id":447,"date":"2020-09-22T12:39:10","date_gmt":"2020-09-22T10:39:10","guid":{"rendered":"http:\/\/www.myblog.nguenkam.com\/?p=447"},"modified":"2022-06-08T17:59:58","modified_gmt":"2022-06-08T15:59:58","slug":"how-to-customize-your-angular-build-with-webpack","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2020\/09\/22\/how-to-customize-your-angular-build-with-webpack\/","title":{"rendered":"How to Customize Your Angular Build With Webpack"},"content":{"rendered":"\n<p>If you\u2019re a frontend dev in the world today you\u2019ve probably heard of (and possibly even used)&nbsp;<strong>webpack<\/strong>. The Angular build process uses webpack behind the scenes to transpile TypeScript to JavaScript, transform Sass files to CSS, and many other tasks. To understand the importance of this build tool, it helps to understand why it exists.<\/p>\n\n\n\n<p>Browsers have very limited support for JavaScript modules. In practice, any JavaScript application loaded into the browser should be contained in a single source file. On the other hand, it is good software development practice to separate out code into modules contained in separate files. When deploying a JavaScript application for the browser, the modules must then be built into a single source file. Bundling multiple modules into a single file is the main purpose of webpack.<\/p>\n\n\n\n<p>Webpack is not limited to simply bundling source files. Because it can support a multitude of plugins, it can perform many additional tasks. Webpack module loaders are able to parse different file types. This allows, for example, Angular TypeScript files to use the&nbsp;<code>import<\/code>&nbsp;statement to import stylesheet files. Usually, webpack is hidden behind the Angular command-line tool. But in some cases, it may be necessary to tweak the configuration of webpack when building an Angular application.<\/p>\n\n\n\n<p>In earlier versions of Angular, it was possible to eject the webpack configuration and modify it directly.  But, since Angular 8, access to the base configuration has been disabled. But it is still possible to extend the webpack configuration and add additional loaders or configuration options. In this tutorial,we will see  how to create an Angular application and tweak the webpack configuration.<\/p>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Set Up Angular With Webpack<\/span><\/h4>\n\n\n\n<p>To allow customization of the webpack configuration, you will need to install the custom webpack Angular builder. Navigate into the Project directory&nbsp;&nbsp;and run the following command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm i @angular-builders\/custom-webpack<\/code><\/pre>\n\n\n\n<p>You will be using the&nbsp;<code>webpack-define<\/code>&nbsp;plugin to inject global value definitions into your code. As an example, this could be used to feature flag parts of your applications.<\/p>\n\n\n\n<p>To enable custom webpack configurations, open the&nbsp;<code>angular.json<\/code>&nbsp;configuration file. Locate the line&nbsp;<code>\"builder\": \"@angular-devkit\/build-angular:browser\"<\/code>&nbsp;inside the&nbsp;<code>architect.build<\/code>&nbsp;section. Replace it with the following lines.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"builder\": \"@angular-builders\/custom-webpack:browser\",<\/code><\/pre>\n\n\n\n<p>Now, inside&nbsp;<code>architect.build.options<\/code>&nbsp;add the following property.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"customWebpackConfig\": {\n  \"path\": \".\/custom-webpack.config.js\"\n},<\/code><\/pre>\n\n\n\n<p>This adds the&nbsp;<code>custom-webpack.config.js<\/code>&nbsp;to the default webpack configuration for the&nbsp;<code>ng build<\/code>&nbsp;command. To also enable the configuration for the&nbsp;<code>ng serve<\/code>&nbsp;command, locate the line&nbsp;<code>\"builder\": \"@angular-devkit\/build-angular:dev-server\",<\/code>&nbsp;and replace it with the code below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"builder\": \"@angular-builders\/custom-webpack:dev-server\",<\/code><\/pre>\n\n\n\n<p>Now create the file&nbsp;<code>custom-webpack.config.js<\/code>&nbsp;and paste the following content into it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const webpack = require('webpack');\n\nmodule.exports = {\n  plugins: &#91;\n    new webpack.DefinePlugin({\n      'STABLE_FEATURE': JSON.stringify(true),\n      'EXPERIMENTAL_FEATURE': JSON.stringify(false)\n    })\n  ]\n};<\/code><\/pre>\n\n\n\n<p>This creates two global constants,&nbsp;<code>STABLE_FEATURE<\/code>&nbsp;and&nbsp;<code>EXPERIMENTAL_FEATURE<\/code>, and makes them available in your application. To read more about the usage of the&nbsp;<code>DefinePlugin<\/code>, please see the&nbsp;<a href=\"https:\/\/webpack.js.org\/plugins\/define-plugin\/\">DefinePlugin\u2019s documentation<\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>The&nbsp;<code>DemoComponent<\/code>&nbsp;will display content depending on the feature flags that you defined in the webpack configuration. Open&nbsp;<code>demo.component.ts<\/code>&nbsp;file and paste the following code into it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { Component, OnInit } from '@angular\/core';\n\ndeclare const STABLE_FEATURE: boolean;\ndeclare const EXPERIMENTAL_FEATURE: boolean;\n\n@Component({\n  selector: 'app-demo',\n  templateUrl: '.\/demo.component.html',\n  styleUrls: &#91;'.\/demo.component.css']\n})\nexport class DemoComponent implements OnInit {\n  stableFeature: string;\n  experimentalFeature: string;\n\n  constructor() { }\n\n  ngOnInit() {\n    this.stableFeature = STABLE_FEATURE ? 'Stable feature enabled' : 'Stable feature disabled';\n    this.experimentalFeature = EXPERIMENTAL_FEATURE ? 'Experimental feature enabled' : 'Experimental feature disabled';\n  }\n}<\/code><\/pre>\n\n\n\n<p>Note the declarations of&nbsp;<code>STABLE_FEATURE<\/code>&nbsp;and&nbsp;<code>EXPERIMENTAL_FEATURE<\/code>&nbsp;at the top of the file. These are needed for TypeScript to know that the two constants exist. But also notice that no values are assigned here.<\/p>\n\n\n\n<p>Next, open&nbsp;<code>the file demo.component.html<\/code>&nbsp;and replace the contents with the following lines.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;div class=\"container\"&gt;\n  &lt;div class=\"row mt-5\"&gt;\n    &lt;div class=\"col-sm col-md-8 offset-md-2\"&gt;\n      &lt;h2&gt;Demo Features&lt;\/h2&gt;\n      &lt;p&gt;\n        {{stableFeature}}\n      &lt;\/p&gt;\n      &lt;p&gt;\n        {{experimentalFeature}}\n      &lt;\/p&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n&lt;\/div&gt;\nAdd Angular<\/code><\/pre>\n\n\n\n<p>Well done! You have completed the implementation of an Angular application with a custom webpack configuration.&nbsp;<\/p>\n\n\n\n<p>You can try out the application by opening the terminal again and running the following command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ng serve<\/code><\/pre>\n\n\n\n<p>Open your browser and navigate to&nbsp;<code>http:\/\/localhost:4200\/<\/code>&nbsp;and you will see your application. You should see something like this.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/d33wubrfki0l68.cloudfront.net\/5c90b43348771d3447274d9560820ad25e5d3654\/0c526\/assets-jekyll\/blog\/angular-webpack\/completed-demo-71581444f6a7df800e741c166959387913409507fa226ee4326d3091f3030125.png\" alt=\"The completed application\"\/><\/figure>\n\n\n\n<h5>References:<\/h5>\n\n\n\n<p><a href=\"https:\/\/developer.okta.com\/\">https:\/\/developer.okta.com\/<\/a><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019re a frontend dev in the world today you\u2019ve probably heard of (and possibly even used)&nbsp;webpack. The Angular build process uses webpack behind the scenes to transpile TypeScript to JavaScript, transform Sass files to CSS, and many other tasks. To understand the importance of this build tool, it helps to understand why it exists. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1965,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[37,104],"tags":[40,106,105,107],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/447"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=447"}],"version-history":[{"count":7,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/447\/revisions"}],"predecessor-version":[{"id":1975,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/447\/revisions\/1975"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/1965"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=447"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=447"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}