question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Tree shaking not working correctly

See original GitHub issue

I’m not sure if it’s not just a webpack configuration issue on my end, but the tree shaking doesn’t seem to work correctly when importing in a specific way.

E.g., if I import icons as described in the readme

# main.js

import { library } from '@fontawesome/fontawesome-svg-core'
import {
  faCog,
  faInfo,
  faSearch,
  faSignInAlt,
  faSignOutAlt,
  faSort,
  faSpinner,
  faUser
} from '@fortawesome/free-solid-svg-icons'

library.add(
  faCog, faInfo, faSearch, faSignInAlt, faSignOutAlt, faSort, faSpinner, faUser
)

my bundle size is around 900kb.

However, if I import them like this

# main.js

import { library } from '@fontawesome/fontawesome-svg-core'
import { faCog } from '@fortawesome/free-solid-svg-icons/faCog'
import { faInfo } from '@fortawesome/free-solid-svg-icons/faInfo'
import { faSearch } from '@fortawesome/free-solid-svg-icons/faSearch'
import { faSignInAlt } from '@fortawesome/free-solid-svg-icons/faSignInAlt'
import { faSignOutAlt } from '@fortawesome/free-solid-svg-icons/faSignOutAlt'
import { faSort } from '@fortawesome/free-solid-svg-icons/faSort'
import { faSpinner } from '@fortawesome/free-solid-svg-icons/faSpinner'
import { faUser } from '@fortawesome/free-solid-svg-icons/faUser'

library.add(
  faCog, faInfo, faSearch, faSignInAlt, faSignOutAlt, faSort, faSpinner, faUser
)

My bundle size is just about 400kb.

I use the component as described in the readme (in separate components though):

# Example Vue component

<template>
  <div>
    <font-awesome-icon icon="search" />
  </div>
</template>

<script>
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

export default {
  // […]
  components: {
    FontAwesomeIcon
  }
}
</script>

I have installed the following Font Awesome related packages:

{
  "@fortawesome/fontawesome-svg-core": "^1.2.0",
  "@fortawesome/free-solid-svg-icons": "^5.1.0",
  "@fortawesome/vue-fontawesome": "^0.1.0"
}

I’m using the latest version of webpack (4.12.1). Here is my config:

# webpack.common.js

const path = require('path')

const CleanWebpackPlugin = require('clean-webpack-plugin')
const { VueLoaderPlugin } = require('vue-loader')
const DotenvPlugin = require('dotenv-webpack')

module.exports = {
  entry: path.resolve(__dirname, 'src/main.js'),
  output: {
    filename: 'app.js',
    path: path.resolve(__dirname, 'dist')
  },
  resolve: {
    extensions: ['*', '.js', '.json', '.vue', '.scss'],
    alias: {
      '@@': path.resolve(__dirname, 'src')
    }
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            js: 'babel-loader'
          }
        }
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.s?[ac]ss$/,
        use: [
          'style-loader',
          'postcss-loader',
          {
            loader: 'sass-loader',
            options: {
              includePaths: [
                path.resolve(__dirname, 'src/assets/scss')
              ]
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(path.resolve(__dirname, 'dist'), {
      verbose: false,
      watch: false
    }),
    new VueLoaderPlugin(),
    new DotenvPlugin()
  ],
  stats: {
    entrypoints: false,
    modules: false
  }
}
# webpack.prod.js

require('dotenv').config()

const merge = require('webpack-merge')
const minifyHtml = require('htmlclean')

const CopyWebpackPlugin = require('copy-webpack-plugin')

const common = require('./webpack.common.js')

module.exports = merge(common, {
  plugins: [
    new CopyWebpackPlugin([
      {
        context: 'src',
        from: '**/*.html',
        transform: content => {
          content = content.toString()

          content = content.replace(
            '<title></title>', `<title>${process.env.TITLE}</title>`
          )

          return minifyHtml(content)
        }
      },
      {
        context: 'src',
        from: '**/*',
        ignore: '**/*.{html,scss,js,vue,DS_Store}'
      },
      {
        context: 'src',
        from: '.**/*',
        ignore: '.**/*.{html,scss,js,vue,DS_Store}'
      }
    ])
  ]
})

My build task is simply webpack -p --config webpack.prod.js.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:5
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
imtblcommented, Jul 2, 2018

@robmadole Thank you, it seems like the issue was with my Babel configuration.

I’ve been using the following:

// .babelrc

{
  "presets": ["env"],
  "plugins": [
    ["transform-runtime", {
      "polyfill": false,
      "regenerator": true
    }]
  ]
}

While @vue/cli uses @vue/babel-preset-app:

// .babelrc

{
  "presets": ["@vue/app"]
}

Using the same preset now gives me the desired result: it doesn’t seem to make a difference anymore which of the two import styles I use.

I’ve had to adjust some other stuff, such as upgrading to "@babel/core": "7.0.0-beta.47" from "babel-core": "^6.26.3" and fixing it to that version because using the latest beta (51) @vue/babel-preset-app would cause Yarn to spam the console with wrong peer dependency version errors.

But all in all, it seems to work fine now. Still, I’ll think about switching my project over to @vue/cli instead of running my own webpack configuration just so I won’t have to spend more time in the future trying to figure out why certain stuff doesn’t work. It also seems to feature some useful stuff like caching and code splitting which I haven’t even bothered to configure in my own config yet. 😄

1reaction
robmadolecommented, Jul 2, 2018

@mserajnik I’ve created this using vue-cli 3.

https://github.com/robmadole/vue-fontawesome-issue-109

Tree shaking works with this. I don’t see any issues with your reproduction but you might compare your config to the vue-cli config by using vue inspect. There are a lot of moving parts.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Webpack Tree Shaking not working when importing from a file ...
If I remove the moment import from module.js tree shaking works fine and i only see square in my bundle. Is this how...
Read more >
Tree shaking not working for ES module library #9337 - GitHub
The way I thought tree shaking worked is as long as the library I'm depending on used ES6 module exports, webpack would remove...
Read more >
How I fixed webpack tree shaking in 3 easy steps
Tree shaking is an important step in Webpack bundling to get rid of unused stuff. This should help describe how to easily get...
Read more >
Tree-Shaking Problems with Component Libraries - Medium
Tree -shaking isn't magic, and much like the garbage collector, you need to understand a little of what it's doing to get the...
Read more >
Tree Shaking - SurviveJS
Starting from webpack 5, tree shaking has been improved and it works in cases where it didn't work before, including nesting and CommonJS....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found