Fork me on GitHub
#shadow-cljs
<
2023-10-02
>
Michaël Salihi14:10:09

Hi! When I set up Portfolio https://github.com/cjohansen/portfolio#shadow-cljs on an existing projet using shadow.lazy , I get Could not find module for ns error:

[:portfolio] Build failure:
------ ERROR -------------------------------------------------------------------
 File: /home/xxx/myproject/diffusion/frontend/devcards/myproject/diffusion/frontend/components/recherche/avancee/nomenclature.cljs:24:17
--------------------------------------------------------------------------------
  21 |             [myproject.diffusion.frontend.components.recherche.common-nomenclature :as nomenclature-front]
  22 |             [myproject.diffusion.frontend.components.recherche.avancee.dewey :as front-dewey]))
  23 | 
  24 | (def lazy-dewey (lazy/loadable myproject.diffusion.domain.nomenclature.dewey/nomenclature-dewey-notations-geographiques))
-----------------------^--------------------------------------------------------
Encountered error when macroexpanding shadow.lazy/loadable.
Could not find module for ns: myproject.diffusion.domain.nomenclature.dewey at line 24 myproject/diffusion/frontend/components/recherche/avancee/nomenclature.cljs
Any clue how can I debug? I suppose it's a classpath issue, right?

Michaël Salihi14:10:37

More specifically, the error only occurs when I require a namespace from another build using code splitting via :modules. Otherwise it works. Is there any solution for this case?

thheller14:10:49

what is your build config?

thheller14:10:12

this usually just means that this namespace is just not included in the build at all

Michaël Salihi14:10:03

Currently I have 2 builds: • The main app • One for portfolio

:dev-http {4005 ["resources/portfolio/public" "classpath:public"]}
:builds   {:app          {:target           :browser
                          :output-dir       "resources/public/js"
                          :asset-path       "/js"
                          :module-loader    true
                          :modules          {:diffusion-frontend-main {:entries [myapp.diffusion.frontend.core]}
                                            :nomenclature            {:entries [myapp.diffusion.domain.nomenclature.public
                                                                                myapp.diffusion.domain.nomenclature.genre
                                                                                myapp.diffusion.domain.nomenclature.theme
                                                                                myapp.diffusion.domain.nomenclature.support
                                                                                myapp.diffusion.domain.nomenclature.source
                                                                                myapp.diffusion.domain.nomenclature.fiction
                                                                                myapp.diffusion.domain.nomenclature.scolaire
                                                                                myapp.diffusion.domain.nomenclature.types-fichiers
                                                                                myapp.diffusion.domain.nomenclature.type-produit] :depends-on #{:diffusion-frontend-main}}
                                            :app                     {:entries [myapp.diffusion.frontend.pages.root] :depends-on #{:diffusion-frontend-main :nomenclature}}
                          :compiler-options {:closure-defines     {"re_frame.trace.trace_enabled_QMARK_"        true
                                                                  "day8.re_frame.tracing.trace_enabled_QMARK_" true}
                                            :strip-type-prefixes #{"cljs.pprint"}}}
          :portfolio    {:target           :browser
                          :output-dir      "resources/portfolio/public/js"
                          :asset-path      "/js"
                          :modules         {:main {:entries [myapp.diffusion.frontend.portfolio]}}

thheller14:10:49

yeah. you need to add the lazy loaded namespaces to the entries there

Michaël Salihi14:10:50

Portfolio live in proper directory in project root :

portfolio/
├── myapp
│   └── diffusion
│       └── frontend
│           └── portfolio.cljs

thheller14:10:21

in the :portfolio build I mean, otherwise it is not included in the build at all

thheller14:10:30

and therefore can also not be lazy loaded

Michaël Salihi14:10:52

OK, thanks! it seems obvious to me now 🙂

Michaël Salihi14:10:49

Last thing, Is there a clean solution to avoid duplicate modules settings between builds?

thheller15:10:22

no. managing code splitting properly is a manual task

thheller15:10:00

are you sure you are benefitting from code splitting at all? I mean does the initial app render without triggering a load of the other modules? the setup seems kinda like it would always load everything anways?

Michaël Salihi15:10:09

Good question. I don't really know if code splitting is currently benefic as this setup is already in place when I started to work on this project. As you say, I think an audit performance will be interesting in future.

Michaël Salihi15:10:15

May can I ask what about the setup seems always load everything? The different dependencies I suppose.

Michaël Salihi15:10:36

Is Shadow-cljs report a good start to debug this?

thheller17:10:45

debug what? only you can answer how you use your code. my question was: when the user loads the initial page, does this additional module get loaded anyways?

thheller17:10:24

or is it actually delayed until the user clicks something or so?

thheller17:10:29

since there were so many namespaces that kinda seemed like it was essential to your app in some way?

Michaël Salihi07:10:34

Yes indeed, this is the case. Some modules is loaded only when user clicks to access some pages and/or advanced features.

thheller07:10:21

but this is not what your module setup says?

thheller07:10:33

you have an :app module, which I took to be the root of your app

thheller07:10:47

that depends on the two others, which means they'll always be loaded as well

thheller07:10:59

but I guess thats not it

Michaël Salihi07:10:03

First of all, thanks for this very informative exchange.

Michaël Salihi07:10:46

Already read at some time but thanks I'll refresh my memory.

Michaël Salihi07:10:50

About the current configuration, here is an loading execution example: 1. Hard reload on the homepage 2. Navigate to cart page load notice.js and panier.js 3. Go to advanced template settings page load gabarit.js

Michaël Salihi07:10:56

Seems good to me, right?

thheller10:10:14

hmm no clue what notice,panier and gabarit are, they are not defined in the above config

thheller10:10:44

and if the 4 files highlighted in green are all loaded at once, then what is the point is splitting them?

austinbirch19:10:26

Hey all, Does anybody know of any tricks to exclude an NPM dependency in a release build (`:target :browser`)? I’m using a library during development-time only (https://www.npmjs.com/package/pseudolocale – helps catch missing localisations), and it exposes one function that I’m calling within (if ^boolean goog.DEBUG …) . I never want to use it in a release build (though I guess goog.DEBUG could be overridden to true in a release build, so maybe that’s not how I should be thinking about this?) Not a big deal if not (small library anyway), and it’s the first time I’ve wanted to do something like this in ~6 years of CLJS development, so maybe I’m just being a bit backwards here.

thheller19:10:11

you can add :release {:js-options {:resolve {"pseudolocale" false}}} to the build config

thheller19:10:32

that will remove the lib from the release build, if its actually unused that should be fine

austinbirch19:10:51

Perfect, thanks @U05224H0W! (also thanks so much for your work on shadow-cljs!)