Fork me on GitHub
#shadow-cljs
<
2023-02-22
>
sergey.shvets03:02:41

Hi, I want to use a component library that (unfortunately) depends on webpack with shadow-cljs. After some research, I found that I could do :js-provider :external and this works just fine. My external file is built with webpack and the code does what I want. But now I'm stuck on how to do a development setup for it? Is hot reload with saving state not possible anymore? I understand that when I change a file, shadow-cljs will change the target/deps.js file and try to reload the code and it won't wait for webpack to update/generate the new dependencies file. Is there any way to workaround that or force an extra reload once webpack is done with refresh? Thank you!

thheller06:02:14

shadow-cljs will still reload CLJS code as normal, as long as you don't have changing JS deps everything should just work. webpack only needs to run if your JS deps actually change

sergey.shvets18:02:03

Thank you. Yes, that's what I figured, and I guess this is not that big of a deal as the dependencies don't change that often after a first few weeks of development. Are there any caveats with externs with webpack-as-a-js-bundler approach?

sergey.shvets19:02:04

Is it necessary to refresh the whole page once the external file is updated or I can trigger reload of the cljs code using the cli command (as when autobuild is off)? I can't seem to make it work. If it works I can do a simple webpack plugin to trigger watch-compile! once the external file is updated.

thheller19:02:39

can you explain what problem exactly you are running into? usually JS deps don't change that much, so I'm not sure why you are looking into reloading it so much?

thheller19:02:03

it is necessary to refresh the whole page, unless you setup some kind of hot-reload in the external file itself. shadow-cljs does not perform any reloading of any kind for that file.

sergey.shvets20:02:45

I use ant.design and import their components one by one instead of the whole library. Instead of (:require ["antd" :refer [Row Col]) I use ["antd/es/grid/col" :default Col] , so any time I bring a new component I need to recompile an external file, so that component is included. This helps to drastically reduce resulting bundle size, but somewhat annoying during development. But again, in a few weeks, I'll import most of the needed components and won't run into this problem anymore. I can live with the current solution.

sergey.shvets21:02:15

Thanks for the answers!

sergey.shvets02:02:48

Actually, I made it work. 1. Added a https://www.npmjs.com/package/webpack-livereload-plugin 2. Added a simple plugin to webpack that runs shadow/watch-compile! once the webpack build is done. It first shows an error, as shadow is much faster in recompile, but then it reloads properly.

Daniel Leong18:02:59

Hello! I'm running into an issue with the :node-test target for a react-native app where it's trying to import RN libs that use import {} statements, resulting in Cannot use import statement outside a module. My hacky workaround is to just delete those import lines with a script before running the tests file, but that doesn't work with watch mode, of course. Is there a built-in mechanism for ignoring those libs? They're basically just UI components so I don't need them to run tests

thheller07:02:28

many react-native packages do not work directly in node, ideally you split your namespaces in a way where the components aren't required in the first place. otherwise :resolve might help

thheller07:02:24

:js-options {:resolve {"react-native" false}} in the build config will entirely "remove" that require. this only works for packages you require directly though. so if you require something that loads react-native it'll still be included because node is responsible for that

Daniel Leong21:02:47

Thank you! I didn't think I was requiring those components in a way the tests would see them, but it turns out I was requiring some data from a ns that references one of those package components. Pulled it out to a separate ns and shadow is smart enough to not require those packages 👍 Hopefully won't need it but :resolve is a great tip as well, thanks!

Daniel Gerson14:05:43

Thanks you! Yes the :resolve {"react-native-lib-xxx" false,...} is a hack, but a useful one as it's an easy to test the remaining pure functions in the code base. Easiest way I've found out so far to achieve this.