summaryrefslogtreecommitdiff
path: root/posts/2014-02-15-cursive-nrepl-cljs-oh-my.org
blob: 74e6f9e26a25bbe69f6223c99ea0922a622cc454 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#+BEGIN_QUOTE
  This notes are mostly for me to remember how to get an environment up
  and running.
#+END_QUOTE

I've tried to play with
[[https://github.com/clojure/clojurescript][Clojurescript]] a few times
already, but I never managed to get an environment working as I wanted.
Granted, I didn't try very hard, and my requirements are probably not
commons, so I'm not blaming the tools.

This time I've decided to dedicate a little bit more times and try to
see how far I could go. My requirements are:

-  it needs to work in a linux VM
-  I want to have a nREPL connection

   -  so I can execute code from the REPL and execute them in the
      browser
   -  I also want to be able to call functions from the browser REPL

-  It needs to work within Emacs and/or Intellij IDEA

The Intellij IDEA requirement is new. I've never used an IDE before and
I've decided to give it a try. I've installed the
[[http://cursiveclojure.com][Cursive]] plugin for Intellij and so far
I'm happy with it.

I'm pleased to say that after a few hours I had a completely working
environment meeting all my requirements. I'm pretty sure this notes will
become outdated quickly, so I'll try update this post as I discover more
things.

** The VM

I like Vagrant and there's no reason to not use it for this kind of
projects. I've created a
[[https://github.com/franckcuny/devbox][repository]] on GitHub with my
setup for that. It's a simple VM with VirtualBox and Vagrant. I'm using
Ansible to do the provisioning part.

After cloning the repository, you can run =vagrant up= and a virtual
machine, running Ubuntu 13.10, will be started and provisionned (a bunch
of tools like tmux are installed, but what really interest us here is
the openjdk). Once it's up, a I run =vagrant ssh= then I start a =tmux=
session.

** Create a project

I create a project using the
[[https://github.com/magomimmo/cljs-start][cljs-start]] template for
leiningen. To be honest, all the hard work is done by this template, I'm
just putting the pieces together to have the setup I want build around
it. With this template, you get:

-  the ability to start a HTTP server for serving your static files
-  a browser-repl from nREPL

This plugin relies on [[https://github.com/cemerick/austin][Austin]].

All I needed to do was to run =lein new cljs-start project= (where
project is the name of my project).

** The REPL

Once you've started to work with a REPL it's hard to go back to a
language that don't have one. When working with Clojure, you get used
very quickly to it, especially since nREPL is so nice, and allows you to
work on a remote box.

The only tricky thing when setting up the VM is to be sure to forward a
few ports for:

-  nREPL - so you can connect from the host to the REPL running on the
   guest
-  the browser REPL - so your REPL can talk to the browser

I run the REPL in headless mode on the VM (in my =tmux= session), from
my project's directory:

#+BEGIN_SRC sh
    # specify a port that I will be forwarded from my host to the guest
    AUSTIN_DEFAULT_SERVER_PORT=4343 lein repl :headless :host 0.0.0.0 :port 4242
#+END_SRC

The =AUSTIN_DEFAULT_SERVER_PORT= variable is the port that will be used
by your REPL to talk to the browser. That's why you need to forward this
port in Vagrant. The other options (*host* and *port*) are here to tell
the repl to listen on all the interfaces (so I can connect from the
host) on the given port.

** Editor

#+BEGIN_QUOTE
  I'm focusing on Intellij IDEA here, but it works the same with
  Emacs/[[https://github.com/clojure-emacs/cider][CIDER]].
#+END_QUOTE

To install the Cursive plugin, you need to go to
[[http://cursiveclojure.com/userguide/index.html][this page]] and follow
the instructions.

I can now open a project in Intellij and start coding. I've configured
my project to use a remote REPL.

#+CAPTION: remote nrepl

[[/imgs/remote-nrepl.webp]]
Now I can connect to the remote REPL and do a quick test to see if it
works:

#+CAPTION: test remote nrepl

[[/imgs/test-remote-nrepl.webp]]
Great! It's time to start the web server to serve our static files and
see if I can connect the browser-repl to it too. Running the following
code in the REPL should do the trick:

#+BEGIN_EXAMPLE
    (run) ;; will start a server with jetty on port 3000, that I can reach from port 4000
    (browser-repl) ;; that’s the *really* cool part
#+END_EXAMPLE

If I want to test something, all I have to do is to load the file into
the REPL and then call a function. For example:

#+BEGIN_EXAMPLE
    (.log js/console "Hi from Intellij IDEA!")
#+END_EXAMPLE

and see the output in my browser's console!

#+CAPTION: it works!

[[/imgs/nrepl-it-works.webp]]
When working on the project, I can run evaluate the file or a form and
send it to the browser. Again, this would be the same with Emacs,
instead of having CIDER to use a local nREPL session, you'll just
connect to a remote one.

** Conclusion

I realize that it's not the easiest setup. I'm maintaining the build
system we have at work for our sites; we use javascript and nodejs, and
I'm really upset by the complexity of our process. If I had to put with
all of that to build a site I would be pretty mad. Still, I think this
setup can be simplified a lot. But using a VM also makes it easier to
give a working environment to a new developer, and it's easy to throw it
away, after all, I'm using it mostly to run the REPL and to have it
working in an environment similar to what it would be in production.

I have to admit that so far, I enjoy Cursive, it's stable and it works
well. I'm still learning how to use the IDE, but some features are
usefull (creating the functions, checking the number of parameters,
displaying docstring, etc). We will see how long I stick to it.