Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import dynamically with webpack

I want to use FontAwesome's icons, but the whole package is too large and I have to select only the ones that I'm using

I'm using vue & webpack

Right now I have the standard:

import { library } from '@fortawesome/fontawesome-svg-core'

import { faGem as falFaGem, faDatabase as falFaDatabase } from '@fortawesome/pro-light-svg-icons'
import { faGem as farFaGem } from '@fortawesome/pro-regular-svg-icons'
import { faGem as fasFaGem } from '@fortawesome/pro-solid-svg-icons'

library.add(falFaGem, falFaDatabase, farFaGem, fasFaGem)

The thing is I have around 80 (for now) icons and some of them duplicates like faGem in the example, hence the "faGem as farFaGem"

I tried importing FAS from '@fortawesome/pro-regular-svg-icons' and making a foreach and adding to library only the icons that I need but webpack imports the whole package into the compiled code

Is there an easier, cleaner way to achieve this?

like image 249
John Avatar asked Jan 29 '19 10:01

John


1 Answers

I believe that the title to your question is a bit wrong. What you want to achieve is reduce the size of the FontAwesomes npm package and that is something that can be achieved in different ways.

The most common way nowadays is using Treeshaking. Basically, your code will be '''analysed''' and a graph of dependencies will be generated, before giving you the "compiled" version of your code it will remove all those modules that were not used from FontAwesome.

FontAwesome can perform TreeShaking if your tool (webpack) allows it, sadly it seems that there are some problems with Webpack 4 but they offer some work arounds like setting the variable modules false in your config:

   const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: './bundle.js'
  },
  module: {
    rules: [{
        test: /\.js$/,
        include: path.resolve(__dirname, 'src'),
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              ['@babel/preset-env', { modules: false }],
            ],
            plugins: ['@babel/plugin-proposal-class-properties'],
          }
        }
      },
    ]
  }
};

In the other hand I believe that what you want to achieve is quite difficult (you will still need to declare all the icons that you want to use from FontAwesome (to use a require(...) call dynamically is something that the tree shaking algorithm can not work around and it will import the whole npm package), and the same for the name conflicts.

If you want it to be a bit cleaner, maybe declare and add all this icons in a separated file of your project, but as far as I can tell, there is no a better way to achieve what you want.

like image 168
SirPeople Avatar answered Sep 18 '22 10:09

SirPeople