Open Vadorequest opened 4 years ago
Tree-shaking isn't quite this smart. It doesn't know if you are dynamically using an icon.
Right now we don't have anything better than just importing the icons individually. It's a pain, but that's the cost of keeping the bundle size small at the moment. We've got plans for helping with this in the future.
Thanks for confirming, that's what I assumed and I'll keep on importing them one by one until a better alternative comes to light!
Hmm I'm noticing my bundle is huge due to font awesome. It seems the entire lib is importing even though I'm only importing a few dozen icons using the explicit method. Any guidance on how to troubleshoot why the tree shaking might now be working? This is in a CRA boilerplate app using react-scripts for the build process.
Are you talking about the production or development build? Because it seems optimizations happens only for the production build.
@jimjeffers also, please look at the actual file size (not the web pack analyzer) for the production build. We've seen instances where the analyzer reports larger file sizes than what is really there.
Thanks for getting back to me. I could adjust the project to use deep imports if I have to that just seems like a big hassle so hopefully I can figure out the cause of this. Also for reference this is a mono-repo that has two packages that CRA SPAs.
Right here is the output after running:
NODE_ENV=production yarn build
yarn workspace v1.22.5 yarn run v1.22.5 $ react-scripts build Creating an optimized production build...
File sizes after gzip:
1.69 MB build/static/js/2.8f24654d.chunk.js 55.47 KB build/static/js/main.9f461445.chunk.js 41.39 KB build/static/js/3.39ba6be8.chunk.js 21.57 KB build/static/js/4.e2b6951c.chunk.js 4.35 KB build/static/css/main.5aa5159a.chunk.css 2.81 KB build/static/css/2.19b7558e.chunk.css 1.2 KB build/static/js/runtime-main.97381a6e.js 195 B build/static/js/5.3a6c9a11.chunk.js 195 B build/static/js/6.e5073874.chunk.js
I'm using Node 12.18.4
and here's my package.json:
{
"name": "web-client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@apollo/client": "^3.2.1",
"@babel/runtime": "^7.7.2",
"@fortawesome/fontawesome-svg-core": "^1.2.20",
"@fortawesome/pro-light-svg-icons": "^5.10.0",
"@fortawesome/pro-regular-svg-icons": "^5.10.0",
"@fortawesome/pro-solid-svg-icons": "^5.10.0",
"@fortawesome/react-fontawesome": "^0.1.4",
"@hookform/resolvers": "^1.0.0",
"@sentry/browser": "^5.10.2",
"@sentry/react": "^5.25.0",
"@sentry/tracing": "^5.25.0",
"graphql": "^15.3.0",
"graphql-tag": "^2.10.1",
"hsportal-schema": "1.0.0",
"luxon": "^1.17.2",
"react": "^16.13.1",
"react-dnd": "^11.1.3",
"react-dnd-html5-backend": "^11.1.3",
"react-dom": "^16.13.1",
"react-ga": "^2.7.0",
"react-google-recaptcha": "^1.1.0",
"react-helmet": "^5.2.1",
"react-hook-form": "^6.9.6",
"react-redux": "^7.1.0",
"react-router": "5.1.2",
"react-router-dom": "5.1.2",
"react-scripts": "3.4.3",
"session": "1.0.0",
"typescript": "~3.7.2",
"ui": "1.0.0",
"utils": "1.0.0",
"uuid": "^3.3.2",
"validations": "1.0.0",
"validator": "^11.1.0",
"yup": "^0.27.0"
},
"devDependencies": {
"@graphql-codegen/cli": "^1.13.2",
"@graphql-codegen/fragment-matcher": "^1.13.2",
"@graphql-codegen/introspection": "^1.13.2",
"@graphql-codegen/typescript": "^1.13.2",
"@graphql-codegen/typescript-operations": "^1.13.2",
"@graphql-codegen/typescript-react-apollo": "^1.13.2",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"@types/draft-js": "^0.10.38",
"@types/draftjs-to-html": "^0.8.0",
"@types/graphql": "^14.2.3",
"@types/humps": "^1.1.2",
"@types/jest": "^24.0.0",
"@types/jwt-decode": "^2.2.1",
"@types/luxon": "^1.15.2",
"@types/node": "^12.0.0",
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"@types/react-helmet": "^5.0.8",
"@types/react-redux": "^7.1.1",
"@types/react-router": "^5.1.2",
"@types/react-router-dom": "^5.1.0",
"@types/react-text-mask": "^5.4.6",
"@types/redux": "^3.6.0",
"@types/uuid": "^3.4.5",
"@types/yup": "^0.26.22",
"prettier": "^2.1.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"deploy": "yarn build && sls deploy client",
"prettier": "prettier --config ../../.prettierrc 'src/**/*.{ts,tsx}' --write"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
But running ls -lh
returns the following:
jimjeffers@Jims-iMac mcss % ls -lh packages/web-client/build/static/js
total 34736
-rw-r--r-- 1 jimjeffers staff 5.5M Nov 4 10:14 2.8f24654d.chunk.js
-rw-r--r-- 1 jimjeffers staff 2.2K Nov 4 10:14 2.8f24654d.chunk.js.LICENSE.txt
-rw-r--r-- 1 jimjeffers staff 8.9M Nov 4 10:14 2.8f24654d.chunk.js.map
-rw-r--r-- 1 jimjeffers staff 142K Nov 4 10:14 3.39ba6be8.chunk.js
-rw-r--r-- 1 jimjeffers staff 808B Nov 4 10:14 3.39ba6be8.chunk.js.LICENSE.txt
-rw-r--r-- 1 jimjeffers staff 620K Nov 4 10:14 3.39ba6be8.chunk.js.map
-rw-r--r-- 1 jimjeffers staff 106K Nov 4 10:14 4.e2b6951c.chunk.js
-rw-r--r-- 1 jimjeffers staff 275K Nov 4 10:14 4.e2b6951c.chunk.js.map
-rw-r--r-- 1 jimjeffers staff 233B Nov 4 10:14 5.3a6c9a11.chunk.js
-rw-r--r-- 1 jimjeffers staff 203B Nov 4 10:14 5.3a6c9a11.chunk.js.map
-rw-r--r-- 1 jimjeffers staff 233B Nov 4 10:14 6.e5073874.chunk.js
-rw-r--r-- 1 jimjeffers staff 209B Nov 4 10:14 6.e5073874.chunk.js.map
-rw-r--r-- 1 jimjeffers staff 391K Nov 4 10:14 main.9f461445.chunk.js
-rw-r--r-- 1 jimjeffers staff 1.0M Nov 4 10:14 main.9f461445.chunk.js.map
-rw-r--r-- 1 jimjeffers staff 2.4K Nov 4 10:14 runtime-main.97381a6e.js
-rw-r--r-- 1 jimjeffers staff 12K Nov 4 10:14 runtime-main.97381a6e.js.map
And here's a screenshot of that large bundle after running:
source-map-explorer 'build/static/js/*.js'
Also worth noting is that the CRA projects are importing a ui
package which as a library of shared components and this package also uses font-awesome/react-fonteawsome. Perhaps that is why the tree shaking might not be working as usual?
Just to be sure I found the other chunk where our UI package exists in the build. Doesn't seem that font awesome was duped because of the monorepo but maybe it's still possible:
Just following up on this one guys. It turns out the other packages in my monorepo were compiling with "CommonJS" which doesn't support tree shaking. I changed the "module" setting to "es6" and my issue went away! I recommend pointing people to webpack's docs on tree shaking -- specifically scroll down to the conclusion section which provides a good checklist:
@jimjeffers what did you change exactly to make sure only the FA icons are included that you are using in CRA?
@fullhdpixel I just set the "module"
attribute in my tsconfig.json to compile my sibling packages as ES6 instead of commonJS. It's been a few years so your mileage may vary with modern projects and FA6. But in my case I was compiling the packages in my monorepo as commonJS so that my jest tests wouldn't complain about transpiling dependencies. Webpack can't perform tree shaking on anything compiled in CommonJS.
Per your doc:
fab
contains all the font-awesome brand icons. Does that mean they'll be loaded by the browser even if they're not actually used?I'm working with Next.js and I'm currently naming all icons one by one and it's cumbersome, and I wish to import all icons and kinda hope tree shacking will remove those that aren't actually used.