nuxt-community / fontawesome-module

Module to use Font Awesome icons in Nuxt.js
MIT License
110 stars 12 forks source link

Any way to reduce bundle size after tree shaking? #10

Open mfrascati opened 4 years ago

mfrascati commented 4 years ago

After correctly using tree shaking (I'm using about 20 icons, no layers) and setting:

    addCss: false,
    useLayers: false,
    useLayersText: false,

in module config, my top size in bundle is fontawesome-svg-core which includes some unuseful code for my needs and it seems there's no way to limit its size. Am I missing something? thanks image

pimlie commented 4 years ago

It seems more people have reported this in the Font-Awesome repo: https://github.com/FortAwesome/Font-Awesome/issues/16005

I dont see anything necessarily wrong at least on our side

fmakdemir commented 4 years ago

@pimlie The problem is fortawesome repo root index files are using old modules so doing import from root iconsets imports the whole set even if you write partial imports (since old modules work like that)

A workaround is using the way old nuxt-fontawesome package did, by separate imports from icon files so instead of:

import { faBars } from '@fortawesome/free-solid-svg-icons'; // imports whole set

doing this would allow the size to reduce:

import { faBars } from '@fortawesome/free-solid-svg-icons/faBars.js';  // imports only file itself
ludo237 commented 3 years ago

@pimlie The problem is fortawesome repo root index files are using old modules so doing import from root iconsets imports the whole set even if you write partial imports (since old modules work like that)

A workaround is using the way old nuxt-fontawesome package did, by separate imports from icon files so instead of:

import { faBars } from '@fortawesome/free-solid-svg-icons'; // imports whole set

doing this would allow the size to reduce:

import { faBars } from '@fortawesome/free-solid-svg-icons/faBars.js';  // imports only file itself

Are you suggesting to avoid pulling icons inside nuxt.config.js ?

fmakdemir commented 3 years ago

What I am suggesting is having separate imports that use icon files instead of importing them from module root. That was how old version of the module did it.

pimlie commented 3 years ago

@fmakdemir Tree-shaking should be working afaik, we have a test for that: https://github.com/nuxt-community/fontawesome-module/blob/master/test/module.test.js#L25

fmakdemir commented 3 years ago

From my experiments on a live environment it didn't work as intended. Is it possible that the issue is with webpack? We are using webpack@^4.29

pimlie commented 3 years ago

Could you please share your fontawesome config from nuext.confg and a bundle analyzer screenshot?

P4sca1 commented 3 years ago

Tree shaking is disabled in dev, so it imports the whole set in development. I suggest changing the code to do one import per icon (adding the icon name at the end of the import path) to only import icons that are used. This would improve page load time in dev which is especially relevant when not accessing the page via localost but via a proxy. In production it is more performant to do a single import as unused icons are tree shaked.

alexcroox commented 3 years ago

Note you can use babel-plugin-transform-imports lib to this automatically for you on build:

import { faApple } from '@fortawesome/free-brands-svg-icons'

build: {
  babel: {
    plugins: [
      'lodash',
      [
        'transform-imports',
        {
          /* eslint-disable no-template-curly-in-string */
          '@fortawesome/pro-regular-svg-icons': {
            transform: '@fortawesome/pro-regular-svg-icons/${member}',
            skipDefaultConversion: true
          },
          '@fortawesome/pro-solid-svg-icons': {
            transform: '@fortawesome/pro-solid-svg-icons/${member}',
            skipDefaultConversion: true
          },
          '@fortawesome/pro-light-svg-icons': {
            transform: '@fortawesome/pro-light-svg-icons/${member}',
            skipDefaultConversion: true
          },
          '@fortawesome/free-brands-svg-icons': {
            transform: '@fortawesome/free-brands-svg-icons/${member}',
            skipDefaultConversion: true
          },
          lodash: {
            transform: 'lodash/${member}',
            preventFullImport: true
          }
          /* eslint-enable no-template-curly-in-string */
        }
      ]
    ]
  }
}

Edit: my extracted example above includes handling of tree shaking for lodash so you can just remove that if you don't use it