Closed piotr-yuxuan closed 5 years ago
First you should generate a Build Report. This will tell you exactly where each byte is coming from.
By requiring "@material-ui/icons"
and "@material-ui/core"
you will get every single thing in the entire library. The solutions for webpack and the other JS tools do not yet work for shadow-cljs
so you need to do this manually.
Instead of ["@material-ui/core" :as mui]
+ mui/Avatar
do ["@material-ui/core/Avatar" :as mui-Avatar]
to only import the components you actually need. Same for the icons.
As far as I know this is already what I tried in https://github.com/piotr-yuxuan/shadow-cljs-wireframe/commit/b1e573838af0c2347d617da5dc57af39266ddaa5, to no avail. The require syntax is based on the Material UI doc.
Here is the build report as you suggested.
(ns wireframe.app
(:require [reagent.core :as reagent]
["@material-ui/core/styles/MuiThemeProvider" :default mui-ThemeProvider]
["@material-ui/core/styles" :refer [createMuiTheme]]
["@material-ui/core/colors" :as mui-colors]
["@material-ui/core/CssBaseline" :default mui-CssBaseline]
["@material-ui/core/Avatar" :default mui-avatar]
["@material-ui/icons/Android" :default AndroidIcon]))
(defn custom-theme
[]
(createMuiTheme (clj->js #js {:palette #js {:type "light"
:primary (.-blue mui-colors)
:secondary (.-orange mui-colors)}
:typography #js {:useNextVariants true}})))
(defn init []
(println "Hello World from shadow-cljs")
(reagent/render
[:> mui-ThemeProvider
{:theme (custom-theme)}
[:<>
[:> mui-CssBaseline]
[:h1 "This is my first, simple heading"]
[:> mui-avatar
[:> AndroidIcon {:color :secondary}]]]]
(.getElementById js/document "app")))
Seems to be reasonable small. Could probably be reduced further but the entire @material-ui
package is one gigantic mess and actually finding stuff is pretty hit or miss.
Congratulations you nailed it! I wasn't aware of :default
, I will have a look at it.
I'm looking forward to trying that! For the sake of completion I'll post the updated build report for those who might be interested.
See the translation table here: https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages
I encounter the same problem, react-icon, I observed its dist/ directory, only a very large index.js, is there no way to optimize it?
@wangzhe1995 react-icon
does not contain any large index.js
so I assume you mean a different package. In general if the package only contains a single large index.js
then there is no way to optimize it yes. Sometimes packages contain extra separate files in a lib
folder or sometimes an es
folder. Those files can usually the accessed directly but not all packages provide them.
React-icon https://github.com/react-icons/react-icons#readme
React-icon has a lot of icon font solutions, I am using fontawesome, I try to the "ls command" with node_modules directory and found that their fa/ directory has only the following files:
➜ ls node_modules/react-icons/fa
index.d.ts
index.esm.js
index.js
package.json
That is react-icons
not react-icon
, they are separate packages.
In this case the icons all seem to be generated via a build step, so there aren't even any separate source files you could include. There is currently no way to "optimize" this package.
Hi,
I've tried shadow-cljs and reagent interop with JS libraries (here: Material-UI) and it works like a charm. It's my first shot with shadow-cljs and I very thrilled. Thank you ❤️
However with production settings and minified builds, the resulting JS bundle isn't properly tree-shook. Vast packages are entirely included even if only a tiny part of them is required. As you can see in this minimal example repo, bundle size varies greatly from 792 KB to 5.74 MB after I import and use one single Material-UI icon.
It is a known issue and common solutions exist in JS-land, which deal with the library import in ES6. These solutions appear not to be (easily) applied to cljs code. Any general idea about how to tackle this issue in cljs-land?
This isn't only related to shadow-cljs project but I haven't figured out what's the best place to post it. If this isn't a proper place, would you be nice enough to hint me where to post? For the sake of completion I've created a thread in Reddit and I've posted about it in Slack.
Cheers.