On 3 Jul 2021, at 15:01, oliver <[email protected]> wrote:
Hi Gary
Thank you very much for this incredibly detailed answer!
Makes totally sense and particularly the tip with the —output-to
option is very helpful and exactly what I will need.
A follow-up question to the download part:
On the machine on which I will do the development I don’t have an
internet connection, but I could run a mock compile on a personal
machine with internet access and then copy everything in the .m2
directory via USB key or similar to the development computer.
The .m2 dependencies are machine-independent, right? I am asking
because the personal machine would be a Macbook and the development
machine is a Linux box.
Anyway, thanks again for all the information!
Ollie
On 3 Jul 2021, at 3:02, Gary Johnson wrote:
Hi Oliver,
clj is a shell script that provides an interface to several functions
within the clojure JAR file. The first time you run it, clj has to
download the clojure JAR and store it in your $HOME/.m2/repository
directory tree for later use.
Every time you run clj, it will check the current directory to see if
there is a deps.edn file present. If so, it will read the :deps map
from it to determine which dependency libraries need to be made
available on your JVM classpath. Any which have not already been
downloaded to $HOME/.m2/repository will be downloaded at this point
and save for later use.
Note, in particular, that to compile clojurescript to javascript, you
must include the clojurescript JAR in your deps.edn file. This will
ensure that it is downloaded to $HOME/.m2/repository and added to
your classpath, so that the `--main cljs.main --compile
hello-world.core --repl` command can be evaluated successfully.
At a minimum, you will need to add this to your project's deps.edn
file in order to run the clj command you provided:
```clojure
{:paths ["src/cljs"]
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
org.clojure/clojurescript {:mvn/version "1.10.866"}}}
```
Next, create the file src/cljs/hello_world/core.cljs, containing this
code:
```clojure
(ns hello-world.core)
(defn say-hello []
(js/alert "Hello from CLJS!"))
(say-hello)
```
At this point, your directory tree should look like this:
.
├── deps.edn
└── src
└── cljs
└── hello_world
└── core.cljs
Now you are ready to compile core.cljs into Javascript. Let's run the
command you provided in your original post:
clj -M --main cljs.main --compile hello-world.core --repl
This will read deps.edn, make sure you have the clojure and
clojurescript JARs in $HOME/.m2/repository (or download them if not),
spin up a JVM with src/cljs and both JARs on its classpath, load the
cljs.main namespace (from the clojurescript JAR), and run its -main
method with ["--compile" "hello-world.core" "--repl"] as its
arguments. This -main method is the entrypoint function for the
clojurescript compiler, which then loads the hello-world.core
namespace (found under src/cljs/hello_world/core.cljs <-- note that -
in namespaces becomes _ in filenames). The clojurescript compiler
then compiles your code into javascript under the out/ directory by
default. Finally, since you passed the "--repl" argument, a web
browser window will be opened and pointed to http://localhost:9000,
which loads up a default webpage provided the clojurescript JAR file,
that contains javascript code to connect back to your clj REPL, so
that the browser can act as the runtime environment for your
javascript code as well as any forms that you type at the REPL.
Since your code included a call to (say-hello) at the toplevel, this
function will be run as soon as the page loads, which will display a
javascript alert box in your browser window with the text "Hello from
CLJS!" in it.
To verify that everything is working correctly, you'll want to use
require and in-ns to load and navigate to your hello-world.core
namespace in the REPL. Then you can run the (say-hello) function
again interactively. Here's the command sequence you want to type:
ClojureScript 1.10.866
cljs.user=> (require 'hello-world.core)
nil
cljs.user=> (in-ns 'hello-world.core)
nil
hello-world.core=> (say-hello)
nil
If everything works correctly, you'll see the familiar javascript
alert box pop up in your browser window with the text "Hello from
CLJS!" in it.
Now, although this shows that your clojurescript to javascript
compilation is working correctly, it doesn't provide a
straightforward path to simply copy your javascript into a separate
web application and load it. That's because in order for your
say-hello function to work, you need to include not only your
generated javascript (from hello-world.core) but also all the
javascript for the clojurescript and google closure systems that are
the necessary dependencies here. If you look at out/main.js, you'll
see the javascript code that your browser window loads when it starts
up the browser REPL page. This code injects script tags into the page
to loads the clojurescript and google closure dependencies, then the
browser repl code, and finally loads your hello_world.core javascript
file (note again that javascript module names use _ rather than - as
in clojurescript).
If you look in out/hello_world/core.js, you'll see just the
javascript that your clojurescript file generated:
```javascript
goog.provide('hello_world.core');
goog.require('cljs.core');
hello_world.core.say_hello = (function hello_world$core$say_hello(){
return alert("Hello from CLJS!");
});
```
What you'll need to do for your simple practice example is to tell
the clojurescript compiler to combine all of the javascript that was
generated from your hello_world/core.cljs file together with all of
its dependencies into a single file, prune all of it to remove
everything that you don't absolutely need to make your code work,
minify all the variable and function names, and remove the
whitespace, so it loads quickly. That, my friend, is what we call
"advanced mode compilation". You can enable it with this command:
clj -M --main cljs.main --optimizations advanced --output-to app.js
--compile hello-world.core
When this command finishes, you'll find a file called app.js in the
current directory. Make a file called index.html in the current
directory containing this code:
```html
<html>
<head>
<title>CLJS Test Page</title>
<script type="text/javascript" src="app.js"></script>
</head>
<body>
Did you see an alert box?
</body>
</html>
```
Now simply open index.html in your web browser, and you'll see the
same alert box as before pop up with the text "Hello from CLJS!" in
it.
Hopefully, that will give you the tools you need to get your feet wet
with clojurescript programming. You can see all the command line
options for the clojurescript compiler by running this command:
clj -M --main cljs.main -h
Also, please keep in mind that clojurescript developers don't usually
work directly at the command line like this. Instead, they would
usually use a tool like figwheel-main or shadow-cljs to automate the
compilation process and hot-load live code changes to your browser
during development.
Welcome again to the wonderful world of clojure and clojurescript
programming. Have fun and happy hacking!
~Gary
On Thursday, July 1, 2021 at 9:52:07 AM UTC-4 Oliver Baumann wrote:
Total newbie tries out ClojureScript...
Got Clojure installed, chcekd that clj works. Then I walked through
the Getting Started tutorial, but get stuck on the compile (i.e.
transpile?) step:
I execute on the command line
clj -M --main cljs.main --compile hello-world.core --repl
and get
Error building classpath. Failed to read artifact descriptor for
org.clojure:clojure:jar:1.10.3
...
Caused by: java.io.EOFException: SSL peer shut down incorrectly
...
Looks like I need an internet connection to transpile the
hello_world file? Or do I something else totally wrong?
How can I transpile a simple dependency-less file to JavaScript
without internet connection?
--
Note that posts from new members are moderated - please be patient
with your first post.
---
You received this message because you are subscribed to a topic in
the Google Groups "ClojureScript" group.
To unsubscribe from this topic, visit
https://groups.google.com/d/topic/clojurescript/hTBTxE8POYc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to
[email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/clojurescript/0bd7a41a-d874-40c4-bdaa-cb8d2d7a92d6n%40googlegroups.com.
--
Note that posts from new members are moderated - please be patient
with your first post.
---
You received this message because you are subscribed to the Google
Groups "ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/clojurescript/C37F1522-3DF6-4FD2-86B8-FA6CF36EEA63%40halloleo.hailmail.net.