Icon system for react with webpack

Icon system for react with webpack

In web application one of the major important is building a scalable icon system for our application.

Why icon system is important?

We all know now a days without a icon we not able to see any web application in the internet world. building a scalable icon system is good investment of your application.

SVG Icon or font icons?

        Earlier web application using two types of icon method. first one font icon. second is SVG icon. both is a best option. but, I personally prefer SVG icons  over font icons.

Reason: When we use font icon the browser will consider as a text and anti-aliased.  But if you really want icons to be sharp, the SVG icons are a better choice.

Before jump into the setup. When we choose SVG icons for our app. it should load as a inline SVG not a direct link SVG in the DOM.

//Bad

<img src="icon-path/icons.svg" alt="icon" class="icon-class-name">

//Good  

<svg width="14" height="14" viewBox="0 0 14 14" data-v-dea60df8=""><path d="M7 0H0v14h7V0z" data-v-dea60df8=""></path> <path d="M10.5 7a3.5 3.5 0 100-7 3.5 3.5 0 000 7zM10.5 14a3.5 3.5 0 100-7 3.5 3.5 0 000 7z" data-v-dea60df8=""></path></svg>

If we load the SVG icon as a inline SVG in DOM we able to fill custom color for the icon.

SVG Icon Setup

  1. Node v16.3.2
  2. NPM version 8.1.2

create package.json file and add the below code in the file

{
  "name": "svg-icons-generation",
  "version": "1.0.0",
  "description": "",
  "main": "src/index.js",
  "files": ["build/"],
  "scripts": {
    "build": "webpack --config webpack.config.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "svg-sprite-loader": "^6.0.11",
    "svg-transform-loader": "^2.0.13",
    "webpack": "^5.67.0",
    "webpack-cli": "^4.9.2"
  },
  "dependencies": {
    "svgo-loader": "^3.0.0"
  }
}

2. create a webpack.config.js in root directory and replace the below code.

// Webpack uses this to work with directories
const path = require('path');
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');

// This is the main configuration object.
// Here, you write different options and tell Webpack what to do
module.exports = {

  // Path to your entry point. From this file Webpack will begin its work
  entry: './src/index.js',

  // Path and filename of your result bundle.
  // Webpack will bundle all JavaScript into this file
  output: {
    path: path.resolve(__dirname, 'build')
  },

  // Default mode for Webpack is production.
  // Depending on mode Webpack will apply different things
  // on the final bundle. For now, we don't need production's JavaScript 
  // minifying and other things, so let's set mode to development

  module: {
    rules: [
      {
        test: /\.svg$/,
        include: path.resolve(__dirname, 'src/icons'),
        use: [
          {
            loader: 'svg-sprite-loader', 
            options: {
              extract: true,
              outputPath: '/'
            }
          },
          'svgo-loader'
        ],
      }
    ]
  },

  plugins: [
    new SpriteLoaderPlugin({
      plainSprite: true
    })
  ]
};

The first level changes  are done. but, yet to complete have one step changes.

Then, create a src folder for writing svg icons generation logic and plain svg files placing folder. the folder should have below having structure.

//Folder structure
-src
 --Icons
   -icon1.svg
   -icon2.svg
 --index.js
-package.json
-webpack.config.js

Final one thing is icon generation main code index.js . This file need to import the svg icons using require and generate separate icons to sprite file.

//index.js

function requireAll(r) {
  r.keys().forEach(r);
}

requireAll(require.context('./icons/', true, /\.svg$/));

That's all. we done the setup changes.

Now, it time to see the output. run below command in your root directory. you will able to see the build folder and inside having the sprite icon svg file.

$ yarn build

That's it.

I hope this can be useful for you.

If you need to download the code base directly. Click me to download