Fork me on GitHub
#reagent
<
2018-04-04
>
andrewboltachev16:04:32

Did anyone try new :npm-deps feature? I tried to use one module ( https://github.com/Stanko/react-animate-height ) and include it into Reagent project, but with advanced opmtimization it didn't work. After few hours of debug it seemd that this line in React https://github.com/facebook/react/blob/master/packages/react/src/ReactBaseClasses.js#L26 was optimized away by Google Closure Compiler

justinlee16:04:01

@andrewboltachev I have never had luck with the :npm-deps feature. I do not think it is really ready for prime time use. I would recommend other approaches. https://gist.github.com/jmlsf/f41b46c43a31224f46a41b361356f04d

pesterhazy16:04:22

no reason why this shouldn't support advanced

justinlee16:04:19

oh you’re actually trying to apply advanced optimizations to imported react components?

justinlee16:04:25

that’s going to be painful

pesterhazy16:04:41

the npm modules shouldn't be fed through Closure of course

pesterhazy16:04:49

that's the point of the double bundle approach

pesterhazy16:04:10

it's going to be hard to outperform webpack on its own turf

andrewboltachev16:04:56

@pesterhazy If they have externs, why not?

juhoteperi17:04:40

@pesterhazy The whole idea of ClojureScript Node module support is to run Node module code through the same Closure-compiler whole-app optimization as JS emited by ClojureScript compiler. This allows better dead-code-elimination than is possible by using webpack for external deps and Closure for Cljs output.

justinlee17:04:07

@juhoteperi lol! why doesn’t it say that in the documentation for the feature? that explains quite a bit of the trouble people have with the feature. given how hard it is to get javascript to compile with closure, that should be a giant red flag.

justinlee17:04:12

now i see at the tail end of of amonteiro’s blog post he mentions in passing that you can do DCE on npm modules. there’s nothing about that in the compiler option entry. why is it even linked? shouldn’t you be able to turn it off? the way most developers (based on my interactions with at least a dozen confused people on slack and including myself) perceive this feature is simply a convenient way of getting access to an npm module

juhoteperi17:04:43

As the Closure optimization is application level setting, no, it can't be turned of just for the npm modules.

justinlee17:04:07

i mean, i see how it mentioned dead code elimination at the top, but I don’t see anything in that article that actually says, “hey, if you use this feature and turn on advanced optimizations, you’d better be ready for it”

juhoteperi17:04:13

And that would help, as npm module code needs to be parsed and transpiled into ClosureJS so it can be part of ClojureScript app.

juhoteperi17:04:59

In general I don't think advanced optimizations with npm module is any harder (easier in some cases) than with foreign libs (cljsjs). React is just complex beast and uses does some dynamic things that can cause problems, but these are usually fixable with proper externs, just like problems with foreign-libs.

juhoteperi17:04:34

With simple npm libs externs aren't even needed because Closure will e.g. apply same renaming to both npm JS and Cljs JS code,.

justinlee17:04:50

well somehow whatever @thheller is doing results in small code packages and npm integration that is 99% seamless

justinlee17:04:31

I think it is super cool to push the boundaries on getting npm modules into whole program optimization, but it is totally unfair to beginners not to warn them that if they just want something functional and convenient, then :npm-deps is not the way to go. They will run into something that requires a deeper understanding of the closure compiler at some point.

pablore17:04:04

How could I adapt components from a cljsjs package?

juhoteperi17:04:29

Well, my recommendation for pretty much everyone (even for advanced users) would be to use cljsjs / foreign-libs, that is the most robust way for now. (I'm not familiar with shadow-cljs.)

pesterhazy17:04:46

The most robust way is to use webpack

pesterhazy17:04:15

It may not be the most elegant or forward looking one, but it's guaranteed to work

pesterhazy17:04:40

because it uses the same code path as thousands of React projects out there

juhoteperi17:04:41

Depends on how you define robust. Most npm packages are anyway browserified by webpack or similar tool by the author or by cljsjs scripts.

juhoteperi17:04:00

Most cljsjs packages use the same UMD modules as provided by package authors.

pesterhazy17:04:36

Correct, but at some point you'll need a more recent version of a package, or one that hasn't been packaged

pesterhazy17:04:05

The vast React ecosystem dwarfs what is available on Cljsjs

juhoteperi17:04:23

True. My experience here is going to be skewed as being Cljsjs maintainer I can just package anything or update any package as needed.

pesterhazy17:04:26

Which is not to minimize the contribution of Cljsjs — it's a wonderful project and works well

juhoteperi17:04:47

Though I don't want to use that many JS packages, I usually find React + Leaflet enough.

pesterhazy17:04:47

I've used in for years and rarely ran into problems

justinlee17:04:52

if you use 3 or 4 react libraries, the version control issue gets out of hand really quickly with a cljsjs type solution

pesterhazy17:04:58

I use react-select, react-native-web, react-ace, react-burger-menu, react-notification-system, react-webcam, ...

andrewboltachev17:04:34

add react-bootstrap, react-material

justinlee17:04:51

react-virtualized react-flip-move 🙂

pesterhazy17:04:57

It gives you a huge boost in productivity especially at the beginning of a project to be able to just pick a pre-baked widget off npm

justinlee17:04:21

and in some cases like react-virtualized, the functionality is so sophisticated you’ll never replicate it

pesterhazy17:04:37

@lee.justin.m agreed, it's a very clever library

pesterhazy17:04:08

So in principle I agree, start with cljsjs, but as your project grows at the moment you'll want to tap into npm

pesterhazy17:04:38

And building a secondary bundle using webpack is by far the least painful way to get there

justinlee17:04:26

well… shadow-cljs is the least painful way but we can agree to disagree on that 🙂

pesterhazy17:04:38

(I should note that I have little experience with shadow-cljs)

justinlee17:04:04

the webpack solution is certainly the most robust. you know for sure it’ll work.

justinlee17:04:28

but the real issue is the “Clojurescript is not an island” blog post and the “javascript modules” page on http://clojurescript.org both breeze past the fact that this feature is super advanced and not at all robust, so new people march straight down this path and then wonder why nothing works

pesterhazy17:04:15

I think that's right. It feels like it should be labeled "alpha" until 90% of npm modules just work

juhoteperi17:04:33

It is labelled alpha, but probably not everywhere.

justinlee17:04:37

well that’s the other problem: “alpha” has no meaning given that spec is being used everywhere and is labeled “alpha”

justinlee17:04:01

It needs a concrete list of issues and problems at the beginning and a suggestion of what else to use in the meantime.

pesterhazy17:04:04

It's certainly one of the most frequently asked questions in #clojurescript and #reagent on Slack

pesterhazy17:04:52

I'd offer to contribute a webpack integration guide, but I fear it wouldn't be well received

juhoteperi17:04:14

@lee.justin.m Lots of good suggestions here. ClojureScript site is managed on github and takes PRs 🙂

justinlee17:04:50

i’ve already written up my thoughts and so has @pesterhazy. can’t spend a bunch of time writing a PR that nobody wants. not sure who makes decisions or what the process is for suggesting bigger changes like that.

juhoteperi17:04:31

About the issue list, I think I might have done something like that somewhere. Reagent 0.8 guide mentions some: https://github.com/reagent-project/reagent/blob/master/docs/0.8-upgrade.md

👍 4
justinlee17:04:56

@juhoteperi does “node modules” in that table mean including react/react-dom via “:npm-deps”?

juhoteperi17:04:58

Yes. This is again a thing that is not really made clear in the docs. :npm-deps is about installing npm packages during Cljs build, but ClojureScript doesn't care if packages are installed by npm install or what, as long as they are available on node_modules directory during Cljs build.

juhoteperi17:04:10

(The Reagent 0.8 doc mentions this)

justinlee17:04:37

Ah ok. Interesting.

geraldodev19:04:15

Do you recommend a material-ui wrapper ? Using directly ?

pesterhazy20:04:50

@geraldodev my general recommendation would be to use it directly; that way you know you can use all the features, instead relying on a wrapper with potentially incomplete docs or coverage

pesterhazy20:04:23

besides using react component from reagent directly with the :> syntax is fairly seemless

pesterhazy20:04:44

(as for including material-ui see the discussion above 🙂)

pesterhazy20:04:29

n.b. I haven't tried those particular cljs wrappers, so they may be very good; it's just my general experience that it's best to go to the source, if you can

pesterhazy20:04:40

same with using Java libs in Clojure — a wrapper often creates more problems than it solves; what's worse, some are written by authors with an incomplete understanding of the library they're wrapping

geraldodev20:04:34

@pesterhazy fair point. I came to that conclusion too, in this case because they are migrating to 1.0 and it's a rewrite.

geraldodev20:04:44

the wrapper @gadfly361suggested is almost on point on the stable version. It uses 0.19 when the stable is 0.20

geraldodev20:04:21

I'm impressed by the adapters they wrote for auto completion https://material-ui-next.com/demos/autocomplete/