For example, the simplest project is used:
package.json
{
"name": "test-fortawesome",
"version": "1.0.0",
"main": "src/index.js",
"scripts": {
"build": "webpack --mode production"
},
"sideEffects": false,
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.0-11",
"@fortawesome/free-brands-svg-icons": "^5.1.0-8",
"@fortawesome/free-regular-svg-icons": "^5.1.0-8",
"@fortawesome/free-solid-svg-icons": "^5.1.0-8"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.7.0",
"webpack": "^4.10.2",
"webpack-cli": "^3.0.0"
}
}
webpack.config.js
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: 'env'
}
}
},
]
}
};
If I use this method of loading icons (after npm run build
), the file size is equal to 35.1 KiB.
index.js
import { library, dom } from '@fortawesome/fontawesome-svg-core'
import { faSearch } from '@fortawesome/free-solid-svg-icons/faSearch'
import { faFileArchive } from '@fortawesome/free-solid-svg-icons/faFileArchive'
import { faDownload } from '@fortawesome/free-solid-svg-icons/faDownload'
import { faGithub } from '@fortawesome/free-brands-svg-icons/faGithub'
library.add(
faSearch,
faFileArchive,
faDownload,
faGithub
)
dom.watch()
But if I use the following method of loading icons, the file size is 792 KiB.
index.js
import { library, dom } from '@fortawesome/fontawesome-svg-core'
import { faSearch } from '@fortawesome/free-solid-svg-icons'
import { faFileArchive } from '@fortawesome/free-solid-svg-icons'
import { faDownload } from '@fortawesome/free-solid-svg-icons'
import { faGithub } from '@fortawesome/free-brands-svg-icons'
library.add(
faSearch,
faFileArchive,
faDownload,
faGithub
)
dom.watch()
How to turn on the tree shaking?
Hi!
Thanks for being part of the Font Awesome Community.
I can confirm.
The bundle file with the second approach (which is also the suggested approach)
@mlwilkerson could you please take a look?
This is definitely not working with the latest fontawesome version (that includes the pre-release ones).
Tree shaking in FA 5.1 does work with Webpack 4. Here's a repo to demonstrate.
Unfortunately, there are a few ways to get the configuration right and many ways to mis-configure.
I think in this case, it may not be working because of the babel-loader
rule in the webpack.config.js
. My demo repo, I did not include that intentionally, and it works.
In fact, if I had not used a webpack.config.js
at all, and just let Webpack 4 do its defaults, it would also have worked if not for this performance regression. Until the fix for that bug finds its way into the minifier plugin that Webpack 4 depends upon (uglify-es
aka terser
), you may need to modify webpack.config.js
to either disable the collapse_vars
compression option, or use Babel Minify instead of the Webpack UglifyJS plugin. I have a draft of these documented work arounds ready to publish to our docs on fontawesome.com but they have yet to be published.
Yes babel-loader is not allowing to tree shake fontawesome, is there any way around it?
I am using babel-loader and react fontawesome. Babel helps to transpile react JSX.
@mlwilkerson Thanks! You have suggested a way to solve the problem with babel-loader
. If you use the beta version of the library babel-loader 8.0.0-beta.3
and configure it correctly, tree shaking with the library will work.
package.json
{
"name": "test-fortawesome",
"version": "1.0.0",
"main": "src/index.js",
"scripts": {
"build": "webpack --mode production"
},
"sideEffects": false,
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.0",
"@fortawesome/free-brands-svg-icons": "^5.1.0",
"@fortawesome/free-regular-svg-icons": "^5.1.0",
"@fortawesome/free-solid-svg-icons": "^5.1.0"
},
"devDependencies": {
"@babel/core": "^7.0.0-beta.51",
"@babel/plugin-proposal-class-properties": "^7.0.0-beta.51",
"@babel/preset-env": "^7.0.0-beta.51",
"babel-loader": "^8.0.0-beta.3",
"webpack": "^4.12.0",
"webpack-cli": "^3.0.8"
}
}
webpack.config.js (slowly)
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'],
}
}
},
]
}
};
index.js
import { library, dom } from '@fortawesome/fontawesome-svg-core'
import { faSearch } from '@fortawesome/free-solid-svg-icons'
import { faFileArchive } from '@fortawesome/free-solid-svg-icons'
import { faDownload } from '@fortawesome/free-solid-svg-icons'
import { faGithub } from '@fortawesome/free-brands-svg-icons'
library.add(
faSearch,
faFileArchive,
faDownload,
faGithub
)
dom.watch()
And now the bundle file.js weighs only 34 KB.
Update. Yes, without configuring UglifyWebpackPlugin build works very slowly. By the way mlwilkerson is much faster.
webpack.config.js
const path = require('path');
const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin');
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'],
}
}
},
]
},
optimization: {
minimizer: [
new UglifyWebpackPlugin({
uglifyOptions: {
compress: {
collapse_vars: false
}
}
})
]
}
};
Why isn't it working with @babel/preset-react? Any idea?
What's broken? My version with beta version of babel-loader does not work?
if you use babel6.x,you have to set modules false , it's work;
babel 7.x set modules false default
Most helpful comment
Tree shaking in FA 5.1 does work with Webpack 4. Here's a repo to demonstrate.
Unfortunately, there are a few ways to get the configuration right and many ways to mis-configure.
I think in this case, it may not be working because of the
babel-loader
rule in thewebpack.config.js
. My demo repo, I did not include that intentionally, and it works.In fact, if I had not used a
webpack.config.js
at all, and just let Webpack 4 do its defaults, it would also have worked if not for this performance regression. Until the fix for that bug finds its way into the minifier plugin that Webpack 4 depends upon (uglify-es
akaterser
), you may need to modifywebpack.config.js
to either disable thecollapse_vars
compression option, or use Babel Minify instead of the Webpack UglifyJS plugin. I have a draft of these documented work arounds ready to publish to our docs on fontawesome.com but they have yet to be published.