reagent-template
reagent-template copied to clipboard
Deploying to Heroku gives 'ClojureScript has not been compiled!'
I've created an app using this template (great stuff btw) and am now trying to deploy using Heroku as per the README instructions.
In the project directory I run
lein do clean, uberjar
git init
git add .
git commit -m "init"
heroku create
git push heroku master
After the last command, the remote deploys the app and verifies it. One of the messages during deployment is: Compiling "target/cljsbuild/public/js/app.js" from ["src/cljs" "src/cljc" "env/prod/cljs"]
which seems to be correct.
However, the app gives the message 'ClojureScript has not been compiled!' which I am familiar with from local development. Locally this just means I haven't run lein figwheel
yet, but I'm not sure what I ought to do since this is the deployed version.
Any help is appreciated, cheers!
Looking in the console log, I see the following error:
Uncaught TypeError: (intermediate value)(intermediate value)(intermediate value).qg is not a function
It's usually an indication that some external Js function got munged during advanced compilation. You probably just have to add externs for any Js libraries you're using.
Just to give more detail on what's happening. The compiler will minify the Js code it produces, so if it sees something like someFunction
, then it will create a shortened name from it such as qg
.
The compiler is able to track all the names it converts in ClojureScript code and core JavaScript functions. However, when you use code from a library, the compiler won't know about it. This is where externs come in. The externs tell the compiler what symbols need to be guarded against renaming, so they're not munged during compilation.
In most cases you can just supply the library as its own extern. For example, if you have your libraries under resources/public/js
, then you just add them in the compiler options as follows:
{:source-paths ["src/cljs"]
:compiler
{:output-to "target/cljsbuild/public/js/app.js"
:output-dir "target/uberjar"
:externs ["react/externs/react.js"]
["public/js/mylib.js"] ;; <-- your js library
:optimizations :advanced
:pretty-print false}}
This "reloading" seems to still occur for me when deployed to heroku despite adding all my javascript files. (By the way, is each extern it's own vector? Seems un-clojurelike to me. Would have expected a single vector with all strings / filenames as elements)
Could this be because I'm including javascript from a web resource (via Reagent)
(include-js "https://code.jquery.com/jquery-2.2.3.min.js")
Sorry, the externs is a typo. It should be a single vector:
["react/externs/react.js"
"public/js/mylib.js"]
You would need the resources to be available on the classpath/filesystem during the compilation step. So, if you're including the resource from a CDN, you would need a local copy to compile the externs.
You're a rockstar @yogthos - thank you. I'm still getting the "compiling" thing on heroku with the reagent lein template and all local js and things setup as above but I'll keep digging.
Ps - whatever's minimizing jquery (Google Closure?) gives a mess of errors when optimizing jquery :)
Sorry to hear you're still having problems. One more thing to look at might be cljsjs repository. If the libraries you're using are packaged there, then they will have externs packaged with them. There's also more externs info on here.
The compiler shouldn't be doing anything to jQuery itself. What happens when externs are generated is that it tries to infer the function signatures from the library. That can give a lot of warnings. You can suppress these by adding the following to your cljsbuild:
:closure-warnings {:externs-validation :off}
@ekhall @yogthos So what status this issues have? Have you resolved it?