Angular - Custom Webpack Config to use SvgDocGen plugin
Tags: webpack, javascript, angular, tutorial
Published: 2020-02-21 09:11:15

Hello everyone, in last time I've posted [webpack plugin for generating demo and variables of your sprites.svg](https://dev.to/fasosnql/svg-doc-generator-based-on-sprites-svg-1ao6) file. In this post I would like to show you how to add custom webpack configuration to your Angular project to use some plugins - in this article [SVG Doc Generator](https://github.com/Fasosnql/svg-doc-gen).

I will be working with angular project generated by `angular-cli` so to go through it with me you can just generate simple app `ng new app-name`.

When we have generated angular app we have to install some builders to build this app with additional webpack config. So let's install:
```bash
  npm install @angular-builders/custom-webpack @angular-builders/dev-server --save-dev
```

Now we have to update `angular.json` to use installed builders.
```json
"architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./webpack.extends.js",
              "replaceDuplicatePlugins": true
            },
```
as you can see name of my webpack config is `webpack.extends.js` you can use whatever name you want.
Dump below we have to change builder for `ng serve`
```json
"serve": {
          "builder": "@angular-builders/custom-webpack:dev-server",

```

In root directory according to `path` which we added to angular.json we have to create `webpack.extends.js` file. It is a file where we will be keeping our additional webpack configuration. For now let's just export empty object:
```js
module.exports = {};
```

Perfect, we've updated builders and added custom webpack config to Angular app. Everything is working so let's go to next step and let's add some custom plugin.

## Adding Custom Webpack Plugin
As I mentioned above I'm gonna add [SVG Doc Generator](https://github.com/Fasosnql/svg-doc-gen). plugin. According to instruction we have to install it via npm

```bash
npm install --save-dev svg-doc-gen
```

Great, now we can configure plugin in our `webpack.extends.js` file. But before it I will add my sprites.svg file to generate styles and demo html based on this. My SVG file looks like:
```xml
<svg version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  viewBox="0 0 24 24">
    <defs>
      <style>
        svg.sprites {
        display: inline;
        }
        svg {
        display: none;
        }
        svg:target {
        display: inline;
        }

        svg[id^="primary-blue/"] use {
        fill: #047BC1;
        }

        svg[id^="primary-white/"] use {
        fill: #fefefe;
        }

        svg[id^="black/"] use {
        fill: #000000;
        }

        svg[id^="gray/"] use {
        fill: #AAAAAA;
        }

        svg[id^="green/"] use {
        fill: #197F86;
        }

        svg[id^="orange/"] use {
        fill: #C3561A;
        }

        svg[id^="red/"] use {
        fill: #B21F24;
        }

        svg[id^="secondary-blue/"] {
        fill: #002B49 !important;
        }

        svg[id^="white/"] {
        fill: #FFFFFF;
        }

      </style>
        <g id="def-icon1.svg">
            <path d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z"/>
            <path d="M0 0h24v24H0z" fill="none"/>
        </g>
        <g id="def-icon2.svg">
            <path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"/><path fill="none" d="M0 0h24v24H0V0z"/>
        </g>
        <g id="def-icon3.svg">
            <path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"/><path fill="none" d="M0 0h24v24H0V0z"/>
        </g>
        <g id="def-icon4.svg">
            <path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
        </g>
    </defs>
    <!--
        @SVGDoc
        name: Icon1
        variable: icon1
    -->
    <svg id="icon1.svg">
         <use xlink:href="#def-icon1.svg"/>
    </svg>
    <!--
        @SVGDoc
        name: Icon2
        variable: icon2
    -->
    <svg id="icon2.svg">
        <use xlink:href="#def-icon2.svg"/>
    </svg>
    <!--
        @SVGDoc
        name: Icon3
        variable: icon3
    -->
    <svg id="icon2.svg">
        <use xlink:href="#def-icon2.svg"/>
    </svg>
    <!--
        @SVGDoc
        name: Icon4
        variable: icon4
    -->
    <svg id="icon4.svg">
        <use xlink:href="#def-icon4.svg"/>
    </svg>
</svg>

```
As you see for every icon I've added `@SVGDocGen` comment according to plugin documentation. Now we can configure plugin,
Inside `webpack.extends.js` we have to add:
```js
const path = require('path');
const SVGDocGen = require('svg-doc-gen');

module.exports = {
  plugins: [
    new SVGDocGen({
      svgDefsPath: path.resolve(__dirname, 'src/assets/sprites.svg'),
      stylesConfig: {
        outputPath: path.resolve(__dirname, 'src/assets/styles/svg-vars.scss'),
        styleLang: 'scss',
        svgPathInFile: 'assets/sprites.svg'
      },
      htmlConfig: {
        outputPath: path.resolve(__dirname, 'src/assets/svg-demo/index.html')
      }
    })
  ]
};

```
This is configuration which is taking `sprites.svg` file from `assets` folder and generating variables and demo html with icons to `assets` folder.
Now when you run `ng serve` or `ng build` according to path if you open `src/assets/svg-demo/index.html` you should see that output:
![HTML output](https://dev-to-uploads.s3.amazonaws.com/i/1zfzpnofe4t7te92q2zs.png)

And `src/assets/styles/svg-vars.scss`:
```scss
$icon1: "assets/sprites.svg#icon1.svg";
$icon2: "assets/sprites.svg#icon2.svg";
$icon3: "assets/sprites.svg#icon2.svg";
$icon4: "assets/sprites.svg#icon4.svg";

```

Ok perfect, at the end we can just import our vars to `styles.scss` to get usage of generated variables. I.e:
```scss
@import "./assets/styles/svg-vars";

.icon1 {
  background: url($icon1);
  background-size: 100%;
  width: 2rem;
  height: 2rem;
}

```

That's all from me, If you have some questions feel free to add comments below this article. If you have some problems with configuring let's download this [zip](https://srv-file9.gofile.io/download/8APrqi/zip-svg.zip) package (this is working angular app generated for this article) and compare your code with code from this pack.