Clojurescript + Node.js 0.12.7 issue (error "process.binding('evals') No such module: evals") - node.js

I'm trying to use Node.js + ClojureScript, and I found an article for it.
http://www.mase.io/code/clojure/node/2015/01/24/getting-started-with-clojurecript-and-node/
Following the instruction to find this error:
process.binding('evals').NodeScript.runInThisContext.call(
^
Error: No such module: evals
at Error (native)
The issue seems that I need to use old version of node: https://groups.google.com/forum/#!topic/clojurescript/VneLWVpwe6o and https://github.com/kanso/kanso/issues/422
Mine is 0.12.7
pow> node --version
v0.12.7
In this case, I may need to use old version of node, but better yet, is there a way to bypass this issue? If none exists, how to use the old version of node.js in Mac OS X?
Edit
Following https://github.com/creationix/nvm, I could install 0.10.32 version of node.js.
pow> nvm install 0.10.32
pow> node --version
v0.10.32
However, it gives me another error message:
pow> node entrypoint.js
Hello world!
/Users/smcho/Desktop/clojurescript/pow/out/server/cljs/core.js:12133
var fixed_arity = f.cljs$lang$maxFixedArity;
^
TypeError: Cannot read property 'cljs$lang$maxFixedArity' of null
Edit2
The error was because I forgot to update the core.cljs module to include ((set! *main-cli-fn* -main). It's mentioned in the original article, together with https://groups.google.com/forum/#!topic/clojurescript/DYpsiCmsyIs and https://github.com/clojure/clojurescript/wiki/Quick-Start#running-clojurescript-on-nodejs.

From the post, there are two ways to make it working, with Mac OSX, the two approaches require different version of node.js, and this is not clearly explained in the post.
The version that works with old node.js
_project.clj
(defproject pow "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:url "http://example.com/FIXME"
:dependencies [[org.clojure/clojure "1.6.0"]
[org.clojure/clojurescript "0.0-2725"]]
:node-dependencies [[source-map-support "0.2.8"]]
:plugins [[lein-cljsbuild "1.0.4"]
[lein-npm "0.4.0"]]
:source-paths ["src" "target/classes"]
:clean-targets ["out/server/pow" "out/server/pow.js"]
:cljsbuild {
:builds [{:id "server"
:source-paths ["src/server"]
:compiler {
:main pow.core
:output-to "out/server/pow.js"
:output-dir "out/server"
:optimizations :none
:target :nodejs
:cache-analysis true
:source-map true}}
]})
entry.js
// entrypoint.js
require("./out/server/goog/bootstrap/nodejs");
require("./out/server/pow");
require("./out/server/pow/core");
Run the script that executes the old node.js
#!/bin/bash
lein new mies pow
cd pow
cp ../_project.clj project.clj
mkdir src/server
mv src/pow src/server/
lein cljsbuild once
cp ../entrypoint.js .
/Users/smcho/.nvm/v0.10.32/bin/node entrypoint.js
The version that works with new node.js
Modify the _project.clj
:optimizations :simple <-
:source-map "out/server/pow.js.map" <-
Run first part of runme.sh
lein new mies pow
cd pow
cp ../_project.clj project.clj
mkdir src/server
mv src/pow src/server/
MOdify core.clj
(ns pow.core
(:require
[clojure.browser.repl :as repl]))
(enable-console-print!)
(defn -main []
(println "Hello world!"))
(set! *main-cli-fn* -main)
Then the second part of shell script
cd pow
lein cljsbuild once
node out/server/pow.js
One more note
I wanted to use ClojureScript/Node.js in order to test clojureScript code without using web browsers. I found LightTable, and
a good tutorial about it. All I need to is open the LightTable, connect to LightTable UI as an output, then execute the script. So, I have much less reason to use ClojureScript/Node.js as of now.

I fixed this with two steps:
1) Declaring a main function
(ns testproj.core
(:require
[clojure.browser.repl :as repl]))
(enable-console-print!)
(defn -main []
(println "Hello world!"))
(set! *main-cli-fn* -main)
2) Setting optimizations: simple in my project.clj, as noted at the very bottom of this blog post. For reasons unknown to me, optimizations: none breaks things.

Related

How to make cljs files works with figwheel repl via fireplace.vim?

I have a project on ClojureScript and I'm using vim for code editing, so I want to access repl inside editor, what is accessible using fireplace.vim.
It works well if you have a brand new flat project - you just open the directory, start clojure repl, open vim in the same directory, create an expression and evaluate it using cpp.
https://youtu.be/vHDLDNoAdLE
But when I working with figwheel project I want to connect to figwheel repl in order to calculate something from cljs file, so I start a figwheel which starts the repl on port 7888 eventually and connect to that repl with fireplace using :Connect command and it works for only clj files, not for cljs.
https://youtu.be/ue42Yh0v6UQ
When I'm trying to evaluate an expression in .cljs file fireplace throwing this error:
Error detected while processing function
37_printop1..37_opfunc[35]..fireplace#client: line 10:
E605: Exception not caught: Fireplace: class
java.lang.ClassNotFoundException
Does anyone have any idea how to make it work (fireplace + .cjls files)?
The problem was in fireplace.vim plugin
at line 323 in fireplace.vim
let response = connection.eval("((or (resolve 'cider.piggieback/cljs-repl)"
must be line:
let response = connection.eval("((or (resolve 'cider.piggieback/wrap-cljs-repl)"
because cider.piggieback defines wrap-cljs-repl function in line 299:
(defn wrap-cljs-repl [handler]
Have you "Piggiebacked" ("enable the use of a ClojureScript REPL on top of an nREPL session") to connect Fireplace to the Figwheel REPL?
:Piggieback (figwheel-sidecar.repl-api/repl-env)
See https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-with-Vim#still-in-vim-piggieback-on-clojurescript
Related to ClassNotFound Exception cemmerick.piggieback:
You have to include cemerick.piggieback in your project.clj or profiles.clj. See https://github.com/nrepl/piggieback:
:profiles {:dev {:dependencies [[com.cemerick/piggieback "0.2.1"]
[figwheel-sidecar "0.5.18"]]
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}}
Here is a sequence of steps I took to make work figwheel REPL with vim fireplace:
Add these dependencies to /home/{username}/.clojure/deps.edn:
...
:aliases {:nrepl
{:extra-deps
{nrepl/nrepl {:mvn/version "0.6.0"}
cider/cider-nrepl {:mvn/version "0.23.0"}
cider/piggieback {:mvn/version "0.4.2"}}}}
...
Add these ones to the project:
...
:deps {com.bhauman/figwheel-main {:mvn/version "0.2.3"}
figwheel-sidecar {:mvn/version "0.5.19"}}
...
Run a project from a terminal with the next command:
clj -R:nrepl -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware cider.piggieback/wrap-cljs-repl]"
Connect to an nREPL from vim using:
:Connect nrepl://localhost:{port}
Start a figwheel REPL and connect to it:
:CljEval (do (require 'figwheel.main.api) (figwheel.main.api/start "dev"))
:CljEval (do (use 'figwheel.main.api) (figwheel.main.api/cljs-repl "dev"))

Scala.js - pass command line arguments from SBT run

When running the app using the sbt run while developing normal JVM app, I can pass command line arguments using run <args>. When I try the same with Scala.js, I get an error "No valid parser available". When trying runMain variant like runMain Main.main arg, the error is "Expected non-whitespace character", with arrow pointing just behind Main.main.
Is there some way how to pass arguments to the Scala.js / Node.js application when running it from SBT?
(I am using Scala.js 0.6.15).
No, there isn't, because JavaScript does not have a notion of command-line arguments. Node.js does, but only if started from the command-line, and that use case is not supported by the sbt plugin, I'm afraid.
Feel free to file a feature request. I'm not sure it can be accommodated, but we can look into it eventually.
One can define a custom task calling node.js, and parse arguments using SBT parsers. Add this into build.sbt:
import complete.DefaultParsers._
lazy val runa = inputKey[Unit]("Run app with arguments")
runa := {
(fastOptJS in Compile).value // build it first
val args: Seq[String] = spaceDelimited("<arg>").parsed
val npmRun = "node index.js" + args.map("\"" + _ + "\"").mkString(" "," ","")
npmRun.!
}
You also need to create a file index.js in your project root, containing something like this:
require("./target/scala-2.12/xxxx-jsdeps.js");
require("./target/scala-2.12/xxxx-fastopt.js");
In the intervening years, a library has emerged to address this:
https://ben.kirw.in/decline/

REPL session for a ClojureScript library in the vein of `lein try`

Sometimes I want to try out a library in a REPL. For example when I need to know the date 100 days from now, I do:
lein try clj-time
(require '[clj-time.core :as t])
(t/plus (t/today) (t/days 100))
Or with boot:
boot -d clj-time repl -e "(require '[clj-time.core :as t])"
(t/plus (t/today) (t/days 100))
This is already great, but this still has a few seconds of start up time.
My question: can I get the same functionality using ClojureScript and Node and perhaps have a faster startup time? How can I get the example above with cljs-time?
You can use Planck with the jar you're wanting to try by adding it to Planck's "classpath" (it's not an actual classpath since there's no JVM involved). See the Planck Dependencies documentation.
E.g.:
planck -c ~/.m2/repository/com/andrewmcveigh/cljs-time/0.4.0/cljs-time-0.4.0.jar

How do I include this directory in the $PATH env var?

I'm building a package for Github's Atom editor and Im running into a challenge trying to get a child process to execute with node js. I'm pretty sure that the problem is that the environment that Atom runs in, doesn't include the path to the mrt script. So when I run this from within my package:
exec = require("child_process").exec
child = undefined
child = exec("/usr/local/bin/mrt add iron-router", { cwd: path },(error, stdout, stderr) -
console.log "stdout: " + stdout
console.log "stderr: " + stderr
console.log "exec error: " + error if error isnt null
return
)
in the console, I get:
Atom has a web inspector built right into it and you can actually see the Paths that atom has included. So when I go to Atom's console and type: process.env.PATH it shows the paths: /usr/bin:/bin:/usr/sbin:/sbin. So I somehow need to make atom aware of that mrt script's path. Anyone know how I might go about doing that?
I also reached out on on Atom's discussion forum yesterday, but have yet to come up with a solution.
Edit:
I should also note that the normal command for excuting the mrt package installer is mrt add package-name but as advised on Atom's discussion forum, I've been using the full path.
Edit 2:
I've creating symlinks to node in my /usr/bin directory, and it's working now. Now I'm trying to get node to create the symlinks for me using fs.symlink but that doesn't seem to be working.
To sum it up, the problem is that Atom uses PATH from where it is launched. Consequently, the path to node and the path to mrt where not included in Atom's path. The solution came to me when someone on the Atom Discussion forum pointed out Atom's Class BufferedNodeProcess.
At the time of Answer there is a slight bug with that class so I was not able to use it - the Github team works fast, I wouldn't be surprised if it was fixed within the next couple days. I was, however, able use some of the code to get Atom's environments. Also, I ended up using node's spawn method instead of execute since that's what BufferedNodeProcess uses. Plus you can read each individual line of the stdout.
options =
cwd: atom.project.getPath()
options.env = Object.create(process.env) unless options.env?
options.env["ATOM_SHELL_INTERNAL_RUN_AS_NODE"] = 1
node = (if process.platform is "darwin" then path.resolve(process.resourcesPath, "..", "Frameworks", "Atom Helper.app", "Contents", "MacOS", "Atom Helper") else process.execPath)
mrt = spawn(node, [
"/usr/local/lib/node_modules/meteorite/bin/mrt.js"
"add"
"iron-router"
], options )
mrt.stdout.on "data", (data) ->
console.log "stdout: " + data
return
mrt.stderr.on "data", (data) ->
console.log "stderr: " + data
return
mrt.on "close", (code) ->
console.log "child process exited with code " + code
return

How do I use (require :PACKAGE) in clisp under Ubuntu Hardy?

I am trying to evaluate the answer provided here, and am getting the error: "A file with name ASDF-INSTALL does not exist" when using clisp:
dsm#localhost:~$ clisp -q
[1]> (require :asdf-install)
*** - LOAD: A file with name ASDF-INSTALL does not exist
The following restarts are available:
ABORT :R1 ABORT
Break 1 [2]> :r1
[3]> (quit)
dsm#localhost:~$
cmucl throws a similar error:
dsm#localhost:~$ cmucl -q
Warning: #<Command Line Switch "q"> is an illegal switch
CMU Common Lisp CVS release-19a 19a-release-20040728 + minimal debian patches, running on crap-pile
With core: /usr/lib/cmucl/lisp.core
Dumped on: Sat, 2008-09-20 20:11:54+02:00 on localhost
For support see http://www.cons.org/cmucl/support.html Send bug reports to the debian BTS.
or to pvaneynd#debian.org
type (help) for help, (quit) to exit, and (demo) to see the demos
Loaded subsystems:
Python 1.1, target Intel x86
CLOS based on Gerd's PCL 2004/04/14 03:32:47
* (require :asdf-install)
Error in function REQUIRE: Don't know how to load ASDF-INSTALL
[Condition of type SIMPLE-ERROR]
Restarts:
0: [ABORT] Return to Top-Level.
Debug (type H for help)
(REQUIRE :ASDF-INSTALL NIL)
Source:
; File: target:code/module.lisp
(ERROR "Don't know how to load ~A" MODULE-NAME)
0] (quit)
dsm#localhost:~$
But sbcl works perfectly:
dsm#localhost:~$ sbcl -q
This is SBCL 1.0.11.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (require :asdf-install)
; loading system definition from
; /usr/lib/sbcl/sb-bsd-sockets/sb-bsd-sockets.asd into #<PACKAGE "ASDF0">
; registering #<SYSTEM SB-BSD-SOCKETS {AB01A89}> as SB-BSD-SOCKETS
; registering #<SYSTEM SB-BSD-SOCKETS-TESTS {AC67181}> as SB-BSD-SOCKETS-TESTS
("SB-BSD-SOCKETS" "ASDF-INSTALL")
* (quit)
Any ideas on how to fix this? I found this post on the internet, but using that didn't work either.
The instructions you got mentioned SBCL explicitely, so it's expected that they'll work better using SBCL, I suppose. Some other Lisps don't come with ASDF or don't hook it up to CL:REQUIRE. In the former case, you'll have load ASDF yourself beforehand. In the latter case, you'll need to call (asdf:oos 'asdf:load-op ) instead of (require ).
wget http://cclan.cvs.sourceforge.net/checkout/cclan/asdf/asdf.lisp
It worth checking out clbuild. http://common-lisp.net/project/clbuild/
To get a lisp webserver up and running. You only need:
darcs get http://common-lisp.net/project/clbuild/clbuild
cd clbuild
chmod +x ./clbuild
./clbuild check
./clbuild build slime hunchentoot
./clbuild preloaded
Now a lisp repl will start. There you write:
* (hunchentoot:start-server :port 8080)
Testing that the server answer:
wget -O - http://localhost:8080/
<html><head><title>Hunchentoot</title></head>
<body><h2>Hunchentoot Default Page</h2>
<p>This is the Hunchentoot default page....
try this before anything else:
(require :asdf)
you can steal some ideas from the environment we use. it's available at: darcsweb
see environment.lisp that loads and sets up asdf for us. (sbcl has asdf already loaded)
use clc:clc-require in clisp. Refer to 'man common-lisp-controller'. I had the same error in clisp and resolved it by using clc:clc-require. sbcl works fine with just require though.

Resources