DEV Community

Przemek Nowak
Przemek Nowak

Posted on

Angular - Custom Webpack Config to use SvgDocGen plugin

Hello everyone, in last time I've posted webpack plugin for generating demo and variables of your sprites.svg 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.

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:

  npm install @angular-builders/custom-webpack @angular-builders/dev-server --save-dev

Now we have to update angular.json to use installed builders.

"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

"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:

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. plugin. According to instruction we have to install it via npm

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:

<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:

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

And src/assets/styles/svg-vars.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:

@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 package (this is working angular app generated for this article) and compare your code with code from this pack.

Latest comments (0)