Fork me on GitHub
#squint
<
2023-10-25
>
sher08:10:41

Maybe more a babashka question, do tasks in bb.edn join/pipe their stdio when they are run in parallel? Like in https://github.com/squint-cljs/squint/blob/main/examples/vite-react/bb.edn#L4 vite-react example, where you spawn 2 shells.

borkdude08:10:38

I'm not sure what you mean by join/pipe

sher08:10:38

I mean: we can see stdout/stderr output from both shells in the single terminal session.

sher10:10:03

Currently squint watch compiles all the files in the path, but the compile command requires file list provided by name. To use squint for production (in the future) we may need a build command that behaves almost like watch (transpiles all files in the path), but also applies production level optimizations, sans watch feature.

borkdude10:10:55

If you upgrade squint, compile compiles all files in path

borkdude10:10:41

If you want optimizations I recommend using a tool like esbuild

sher10:10:43

Sorry, optimizations maybe not required. squint -> mjs/jsx -> (vite/esbuild etc.) -> production bundle will be more proper.

sher10:10:18

Now testing with squint version 0.3.35 should I try with the master branch instead?

borkdude10:10:48

No, check the latest version on npm

borkdude10:10:01

And re-run npm install

borkdude10:10:42

This should work since I’m also using it on CI in a test project

sher10:10:06

Great. Will use the latest.

sher10:10:02

Maybe I was mislead by the --help output?

sher10:10:05

vite-react on main $ npx squint --help
Squint v0.0.0

Usage: squint <subcommand> <opts>

Subcommands:

-e           <expr>  Compile and run expression.
run       <file.cljs>     Compile and run a file
watch                     Watch :paths in squint.edn
compile   <file.cljs> ... Compile file(s)
repl                      Start repl
help                      Print this help

Use squint <subcommand> --help to show more info.

borkdude10:10:27

Just don’t use any arguments, just “npx squint compile”

borkdude10:10:53

Yeah maybe the help should be updated :)

sher11:10:43

Created a new vite project (React/JSX), added squint-cljs to deps and bb.edn squint.edn . The plan is to not change vite directory structure, but add a separate src-cljs path, that outputs into src which is watched by vite. The issue is that squint watch or squint compile are not outputting transpiled files into src folder. https://github.com/sher/squint-vite

borkdude11:10:20

I'll have a look

borkdude11:10:09

the issue is that you have to name your source directory src-cljs, not src_cljs

borkdude11:10:57

I get the confusion but everything on the path needs to use underscores, but not the path directories itself, unless you write :paths ["src_cljs"]

sher12:10:33

Oh, this helped! But, ultimately, the cli should warn that it could not find the path .

borkdude12:10:42

sure, issue (+ PR?) welcome

👌 1
sher12:10:03

Btw, what is the meaning of adding - to functions and tasks, does it mean an entry point hint? Like here https://github.com/squint-cljs/squint/blob/main/examples/vite-react/bb.edn#L4

borkdude13:10:44

- means "private", these tasks don't show up in bb tasks output

🙇 1
sher13:11:21

Still working on squint-vite and trying to https://github.com/sher/squint-vite/blob/main/bb.edn#L2 to the dest path, replicating what https://github.com/squint-cljs/squint/blob/main/src/squint/internal/cli.cljs#L142. Added shadow-cljs to node dependencies, but can't require it in the babashka task. Getting this error.

----- Error --------------------------------------------------------------------
Type:     java.io.FileNotFoundException
Message:  Could not locate shadow/esm.bb, shadow/esm.clj or shadow/esm.cljc on classpath.
Location: <expr>:4:47
The idea is to use chokidar to watch the paths and copy all non-cljs.

borkdude13:11:12

@URCRY0U87 I don't understand what you're trying to accomplish. When you run npx squint watch, files are already watched and compiled by squint? (it uses chokidar under the hood btw) and why do you need shadow-cljs?

sher13:11:25

What I m trying to do is copy files like styles, images that can be required like this https://github.com/sher/squint-vite/blob/main/src-cljs/core.cljs#L5

sher13:11:02

And the compiled output will be like vite would expect https://github.com/sher/squint-vite/blob/main/src/core.jsx

sher13:11:17

And rely on vite to handle bundling css or other static assets.

borkdude13:11:48

Why don't you just write (:require ["assets/core.css"])?

borkdude13:11:27

$ ./node_cli.js --show --no-run -e '(ns foo (:require ["assets/core.css"]))'
import * as squint_core from 'squint-cljs/core.js';
import 'assets/core.css';

sher13:11:14

I am doing as you mentioned above, but the actual assets/core.css file is never copied to the output destination folder, never processed by squint's chokidar watch function.

sher13:11:31

My understanding is that chokidar now filters only cljs files https://github.com/squint-cljs/squint/blob/main/src/squint/internal/cli.cljs#L152

borkdude13:11:44

this file doesn't have to be compiled using squint, so why should squint watch it? vite itself should pick up on it

borkdude13:11:47

where does assets live in your directory structure? I think you should just place this where vite can already see it

sher13:11:46

You are correct. The plan was, to make it more developer friendly, to write the app in the src-cljs folder, also putting all static assets there. Then the dev or build tasks would compile cljs files and copy static assets to the src folder.

sher13:11:55

This way src folder can be also gitignored

sher13:11:42

Sorry for confusion, the src folder will be the destination for squint compiler.

borkdude13:11:54

right, I think we could add maybe something to squint watch to support this, to watch all files but to copy all other assets that aren't .cljs files

sher13:11:36

Also thought about this, but am not sure if this copy feature has place in squint.

borkdude13:11:17

I think that would be the easiest way

sher13:11:23

Great, will try.

borkdude13:11:30

Then you could add :paths ["src" "resources"] and even separate the css stuff from the srces

sher13:11:04

Have to think about making this configurable. Certainly :paths ["src" "resources"] could work, also clojure way to separate resources. But then vite also should be able have access to files out of src scope.

sher13:11:22

I will try possible options and create a PR.

sher13:11:44

Thank you.

borkdude14:11:35

> But then vite also should be able have access to files out of src scope No, these files are copied to :output-dir and vite is going to pick them up as relative imports

sher14:11:57

Oh right, thanks

borkdude14:11:42

I'll have a go at it right now

sher14:11:56

Nice. I was still figuring out how to implement and test it locally.

borkdude15:11:54

@URCRY0U87 publishing 0.4.41 now, all non .cljc/.cljs files are just copied over to the output-dir

sher15:11:54

Thank you. Will test it right away.

sher15:11:59

Do you think it is ok to be the default behavior, with no option to disable it?

borkdude15:11:37

that's what it is now

borkdude15:11:48

there is no option to disable it

borkdude15:11:27

this also works nicely if you want to include some .js files among your .cljs files btw

👍 1
sher15:11:37

If all works as expected, can I update your https://github.com/squint-cljs/squint/tree/main/examples/vite-react example or create a new example?

sher23:11:30

Just tried and files other than cljs are recursively copied to :output-dir 🎉 Things left to do: • update squint-vite and squint README, mention caveats like ◦ asset imports must have relative path (:require ["./assets/some.css"]) or (:require ["../resources/assets/some.css"]) ▪︎ depending on where you wish to keep them ◦ bb tasks should run in parallel in order to have their stdio piped ▪︎ {:parallel true} option can also be re-considered, because dependent tasks may run serially but still have stdio piped, so we can see output from every spawned process ▪︎ {:parallel false :stdio "pipe"} as an option for node https://nodejs.org/docs/latest-v18.x/api/child_process.html#optionsstdio Will prepare a PR.

sher23:11:04

This is a great change. Now you can write full vite project with just bb/squint.

borkdude10:11:53

I'm not sure what you mean with the stdio issue but maybe it will become clear in the PR

sher10:11:25

Yes, I will try to clarify this matter.

sher10:11:49

Sorry, not pipe but inherit (in nodejs terms) so all spawned child processes' logs will be print to parent process streams.

sher10:11:35

Currently, if you not state that tasks should run in parallel child process logs dont appear. https://github.com/sher/squint-vite/blob/main/bb.edn#L5

borkdude11:11:39

They don't appear since the "second" task doesn't even run, it's blocked by the other one until it finishes

borkdude11:11:54

It doesn't have to do with inherit/pipe etc

borkdude11:11:32

You can however start the two tasks in separate terminals, then it should work

sher11:11:30

I see, if a task depends on multiple other tasks listing them like -dev {:depends [dev:squint dev:vite]} , none other tasks will run until the previous one is finished?

sher11:11:09

Unless we declare them to run in parallel dev (run '-dev {:parallel true})

sher11:11:30

Now I understand the point. But in dev mode, processes may watch and never exit. You may have bunch of those processes, that bundle some sort of deliverables. Maybe there is a way to accommodate this case, maybe we can consider.

borkdude11:11:29

I don't think anything has to change really. watch is a development task. when you need to bundle stuff up, you quit the watcher, and run squint compile + vite build or whatever

sher11:11:49

I am excited to share vite-bb with others who wanted to write clojure for frontend SPA.

👍 1
borkdude11:11:49

squint-vite you mean?

sher11:11:18

Still not sure which is the main: squint or bb

sher11:11:50

Plan is to create a npm create vite-bb command

borkdude11:11:07

bb is just a development tool, it has nothing to do with vite or JavaScript

borkdude11:11:15

bb is more like JVM Clojure than ClojureScript

borkdude11:11:47

or do you want to create a web application with a backend in bb?

sher11:11:43

For this phase, I want to create a command that will give the dev a boilerplate to create a vite SPA project scaffold which has bb.edn squint.edn etc.

sher11:11:26

I am looking forward to attracting more enthusiasts to both https://github.com/sher/squint-vite/tree/main frontend, using vite SPA and nbb fastify https://github.com/sher/nbb/tree/main/examples/fastify to create a public facing service, all written in cljs.

borkdude11:11:02

you can build the backend in nbb too :)

borkdude11:11:05

eh squint I mean

borkdude11:11:29

but the nREPL experience isn't as great yet with squint, working on it

sher11:11:06

fastify-nbb is working just well

sher11:11:40

Oh, nREPL - for newcomers like me, we were never used to that kind of development

sher11:11:48

So no rush

sher11:11:39

But, ruby on rails we had this experience decades ago, with rails c command. You can query database, you can require any class etc.

sher11:11:17

Squint nREPL if combined with browser websocket, refresh the state of an item: this should be very complicated.

borkdude11:11:59

yes, but for Node.js applications nREPL is doable. I'm of the opinion that for front-end hot-reloading with vite is 90% what I want

borkdude11:11:28

still I want to have a go at making nREPL work for front-end too, eventually

borkdude11:11:40

but first nREPL on Node.js needs improvements

sher11:11:34

nREPL on Nodejs = Nodejs repl + (SCI) clojure + classpath + discovery paths ?

borkdude11:11:31

nREPL on Node.js with squint I mean. nREPL on Node.js with nbb already works perfectly

sher11:11:44

I understand it is complicated (without understanding the actual complexity), but JavaScript runtime engines trying their best.

borkdude11:11:33

> JavaScript runtime engines trying their best. Actually this is what makes it complicated: ES6 (immutable) modules destroy the REPL experiences, you have to basically undo everything ES6 modules stand for

borkdude11:11:48

so I don't agree with "trying their best" to make this experience possible ;)

sher11:11:34

Good REPL experience assumes mutation of imported modules?

sher11:11:39

Imported, external - that you have no control of to publish updates.

borkdude11:11:49

Of course. When you import function f from module F and you call it in your own function:

(ns my-ns (:require [foo :refer [f]]))

(defn g [] (f))
and f gets redefined, you want to see the updated version when you call g

borkdude11:11:32

so when you are in a REPL:

foo> (defn f [] 3)
f should get updated (which implies mutating the namespace)

borkdude11:11:47

and

my-ns> (g)
should return a different result

borkdude11:11:25

Every file in squint is compiled to an ES6 module but to make the above possible you basically have to work around it

sher11:11:15

Is it just a namespace/naming issue, because we can import and destruct values like import { a: b} from 'c' where original b inside the module, will be mapped to a within current context.

borkdude11:11:24

is this a question or a remark?

sher11:11:26

This seems to me that you are creating not only compiler, but have to struggle with linker.

borkdude12:11:14

It is not just a mapping problem. The original b can change because of what you are doing in the REPL, but ES6 module c can never change.

borkdude12:11:54

vite uses workarounds for this like adding a ?<timestamp> to each module and rewrite all imports using these timestamps

👀 1
borkdude12:11:27

CLJS makes the REPL experience possible by just using global mutable objects for namespaces

borkdude12:11:55

while emitting normal ES6 modules on non-REPL output

sher12:11:25

Now I kind of understand, that in REPL anythyng should happen, even rewriting the imported external library logic.

sher12:11:06

Actually, I do change code in node_modules/etc lib folder, to debug its' behavior.

borkdude12:11:40

In an ES6 module but without restarting Node.js for a node app? This is what a REPL should support

borkdude12:11:50

I mean, initially, I'm ok with just supporting this for code on :paths, not JavaScript libraries, but in a squint node app you will be working on multiple namespaces at the same time

sher12:11:40

With the latest squint copy command update, we can create a full web service: front: squint-vite back-api:nbb-fastify.

sher12:11:19

I see a chance to lure young programmers to lisp )

sher12:11:58

Figuring out the npm create command, planning to execute with bb wherever possible.

borkdude21:10:11

Compiling babashka.cli to squint so you can directly use it from JS :-D

[ '--foo', '1' ] {} => { foo: 1 }
[ '--foo', '1' ] { coerce: { foo: 'string' } } => { foo: '1' }
[ '--foo', '1' ] { coerce: { foo: [ 'string' ] } } => { foo: [ '1' ] }

🤯 6
👍 1
Chris McCormick01:10:04

If this means there's a possibility I can npm install a babashka-like-in-js then I'm very interested! The main thing that stops me from making my apps depend on bb is needing to install a separate binary outside the normal deployment flow.

borkdude08:10:52

This is only about one library, babashka.cli, so no, it doesn't mean that

borkdude08:10:46

bb itself has JVM-semantics, you cannot possibly port that all to pure JS

👍 1