Fork me on GitHub

On hacking on portal: I will try to share here my experience trying to see how portal works, and add features (in thread). I understand that the problems I'm getting are caused by my (wrong) mental models and inexperience, and so this is me trying to patch them. I will appreciate whatever explanation may come in response 😂❤️


Let's say I want to add a new color schema to portal, and I find the src/portal/colors.cljc file. Now, I want to be able to try the colors interactively, so I want to open a repl. The documentation on github suggests, since I use emacs, to cider-jack-in-clj&cljs. I'm a little confused about why I have to connect to both a clj and a cljs repl (this is not particularly tied to portal, I'm just confused about this). A little trial and error later I know that I should have chosen clojure-cli when prompted about which command to use, and then choose :client as the shadow target (just because the others seem less probable). When I do that I get briefly the error message:

error in process filter: ClojureScript is not available.  See  for details
but on the other hand I can evaluate sexps in the repl that is open. Since I don't see a browser, given the error, I suspect that only the clj part of the repl is open, but don't know what that implies for me. I try to eval something. I wish I could start a portal, I go to portal.api, I open a repl in the usual manner. I go back to portal.colors , do some modification to a theme, eval back and forth a couple of time, but can't change the actual colors. I remember that there's a dev folder that probably contains useful code;


I find that there is a start!, watch, and repl in dev/user.clj that I should probably try to use. I try to eval the namespace declaration in dev/user.clj and I get:

Could not locate tracker__init.class, tracker.clj or tracker.cljc on classpath
Some grep later, I understand that I should have probably started my repl with the :dev alias, so that I get the ns-tracker dependency. I restart the repl. Same cljs error as before but now it dawns on me that maybe I should also include some other aliases, like :cljs, or :shadow. There are a bunch of them, and while I can see the dependencies that they bring in, I'm not sure I understand the affordances that they'll bring me. Let's go with :dep:cljs:shadow as added dependencies.


I pushed up a fix for .dir-locals so jack-in should work better now. Also, cleaned up user.cljs to make things easier. I would try master real quick and see if it's any better 👌

❤️ 1

Thank you! I'm going to try this right away. I hope this kind of narration is useful to you too (maybe to understand where a beginner might struggle). It is surely useful to me 😍

👍 1

Yeah, if you are having issues working in the source tree, it's probably something that needs to be fixed via docs or code 💯

🙌 1

Also, I think themes are pulled in directly by the cljs code so you just need to save the file and shadow should do the rest 👌


The need for two repls is because one is connected to the host runtime (jvm) and the other will be connected to the portal ui which will be running in the browser.


I know that this sounds like a very dumb questions, but, when I open both a clj and cljs repl in emacs, and I can find two buffers that are repls, but both seem to have shadow cljs stuff:

;;  Startup: /run/current-system/sw/bin/clojure -A:dev:cljs:shadow -Sdeps '{:deps {nrepl/nrepl {:mvn/version "0.9.0"} cider/cider-nrepl {:mvn/version "0.28.3"} refactor-nrepl/refactor-nrepl {:mvn/version "3.5.2"} cider/piggieback {:mvn/version "0.5.2"}} :aliases {:cider/nrepl {:main-opts ["-m" "nrepl.cmdline" "--middleware" "[shadow.cljs.devtools.server.nrepl/middleware,refactor-nrepl.middleware/wrap-refactor,cider.nrepl/cider-middleware,cider.piggieback/wrap-cljs-repl]"]}}}' -M:cider/nrepl
is the same thing as:
;;  Startup: /run/current-system/sw/bin/clojure -A:dev:cljs:shadow -Sdeps '{:deps {nrepl/nrepl {:mvn/version "0.9.0"} cider/cider-nrepl {:mvn/version "0.28.3"} refactor-nrepl/refactor-nrepl {:mvn/version "3.5.2"} cider/piggieback {:mvn/version "0.5.2"}} :aliases {:cider/nrepl {:main-opts ["-m" "nrepl.cmdline" "--middleware" "[shadow.cljs.devtools.server.nrepl/middleware,refactor-nrepl.middleware/wrap-refactor,cider.nrepl/cider-middleware,cider.piggieback/wrap-cljs-repl]"]}}}' -M:cider/nrepl
how do I see which one is the clj one?


One should be in user while the other is in cljs.user

🙌 1

and then, assumed I want to in fact hack colors, which portal should I open? Both the one in portal.api and the one in portal.web will have an interface


Either or should be fine, the running client code is the same so it should be identical


ok, so, I in the clj one I required portal.api and started a portal. Then I changed some colors in colors, but pressing C-c C-c doesn't change anything. When I have two repls, who am I sending the evaluation to?


I'm also noticing in the cljs repl I have a repeated occurrence of:

[:client] Build failure:
The required JS dependency "anser" is not available, it was required by "portal/ui/inspector.cljs".


which might be the reason for which hot reloading isn't working. And then, trying to evaluate (require '[portal.web :as p]) in the cljs repl tells me that there are no available js runtimes (maybe because of the error)


You might need to npm install 👌

🙌 1

Also, if you are trying to open the dev version of portal, you need to do {:mode :dev}

🙌 1

I wanted the ability to run both (dev/prod) side-by-side so now you opt-in


In general though, if I didn't write in the cljs repl, but just issued the eval shortcut on a piece of code, which repl is going to get that? Both?


I'm working on improving the docs structure, and all this info will be included 💯

❤️ 1

If I can be of use I'm very willing to send documentation PRs

❤️ 1

So, I think for cider, it depends on the file extension: clj -> clj repl, cljs -> cljs repl, cljc -> both repls

🙌 1

This might be configurable in cider, not sure


so, after an npm install , the cljs repl compiles now, but still, if I try to require something in there, it will complain about not having a JS runtime. Is that a thing that I shouldn't be doing?


So, what that means is you need to open a dev version of portal.


cljs.user> (portal.web/open {:mode :dev})
No available JS runtime.
See ;; => nil


Yes, that will work after you open a portal via the jvm


I use the web portal to debug the portal ui itself so it's a little meta


I think juggling multiple runtimes is one of the challenging aspects of working on portal

🙌 1

This is especially true when working with extensions


I opened a jvm portal in the clj repl, but still the same error when trying to open this portal.web/open in the cljs one complains for lack of a runtime


where should the runtime be?


Is the jvm one a dev one too?


no it was not, restarting

🤞 1

They both need to be dev


I see, even just a jvm one is already sufficient to get hot reloading for colors

💯 1

when called with {:mode :dev}


yes, the different runtimes are the feature of all of this that confuses me the most


because it really seems that we could have just the JVM one, and do everything? Right?

👍 1

It was an actual question, I'm sure there's a reason to have all of them 😂


The major exception is having access to native objects, the jvm specific one doesn't have access to js objects

🙌 1

Also, I use the portal.web to debug the portal ui itself


so, when developing a cljs project that has a lot of js interop, a cljs portal is strictly more useful, right?

👍 1

what do you mean with using portal.web to debug the portal UI?


Try cmd+shift+o in the portal ui itself

🤯 1

To debug a portal ui, i need a version of portal that can ran from the ui 💯

💯 1

Usually I will open a dev portal and the web portal will be a prod one so my changes don't break my debugging

🤯 1

how are they kept distinct?


By the runtime they are connected to 👌

🙌 1

You mentioned in one of your presentations on portal that there's this kind of meta-hacking, but it never went into the presentation, and it's extremely interesting


Yeah, a good way for me to test / improve portal is via debugging itself


First initial proposal for a gruvbox theme

👏 5

Just reiterating that after @djblue's commit wrt prep, you can now run portal from a git version. If it is a normal deps.edn dependency, all that's required is, before starting the repl:

clj -X:deps prep

💯 1
❤️ 1
🎉 1