Deploying to Heroku: dependencies of npm packages not getting installed when deploying app

I am writing a web application with the backend in Clojure and the frontend in Clojurescript with React and Reagent. I am trying to host it on Heroku.

When I run lein ubjerar locally, it builds fine and the app works.

However, when I try to deploy the app to Heroku via git push heroku master, I always end up with an error like this:

remote:        Preparing npm packages
remote:        Installing npm packages
remote:        npm packages successfully installed
remote:        Running shadow-cljs...
remote:        [:app] Compiling ...
remote:        The required JS dependency "object-assign" is not available, it was required by "node_modules/react/cjs/react.production.min.js".
remote:
remote:        Searched in:/tmp/build_c09494ebe081fa0581db343dc809fb45/node_modules
remote:
remote:        You probably need to run:
remote:          npm install object-assign
remote:
remote:        See: https://shadow-cljs.github.io/docs/UsersGuide.html#npm-install
remote:
remote:  !     Failed to build.
remote:  !     Push rejected, failed to compile Clojure (Leiningen 2) app.
remote:
remote:  !     Push failed
remote: Verifying deploy...
remote:
remote: !	Push rejected to getfluentspanish.
remote:
To https://git.heroku.com/getfluentspanish.git
 ! [remote rejected] master -> master (pre-receive hook declined)

This happens in spite of the fact that object-assign is listed as a dependency of the react npm package, which I already have listed as an item in :npm-deps in my project.clj. I have verified that when I build locally, the package installs fine (i.e. in this case node_modules/object-assign exists).

When I manually add object-assign as an explicit dependency in :npm-deps, I get the same error, but complaining about a different missing dependency that should get installed automatically (and does locally). When I add the new missing dependency, it complains about another. When I build locally with the new explicit dependencies, lein uberjar works but complains that there are now version conflicts because the implicit dependencies are often fixed at a different version.

Any idea how I can fix this?

you you have yarn.lock or package-lock.json in your project? There are used to make sure packages are installed in same same version in every environment.

I’m not familiar with :npm-deps though…

:npm-deps is used by the lein-shadow plugin to keep NPM dependencies in the project.clj file.

shadow-cljs automatically generates the package.json and I believe package-lock.json is created automatically by NPM on install.

I ended up giving up on using Git-based Heroku deployment and instead made a Dockerfile and managed to get deploys working that way (using locally built uberjars).

Here’s the wonderfully simple Dockerfile I used to make it all work. No other changes were necessary:

FROM openjdk:8-alpine
COPY target/uberjar/getfluentspanish.jar /getfluentspanish/app.jar
EXPOSE 3000
CMD ["java", "-jar", "/getfluentspanish/app.jar"]

I am really glad I learned how to use Docker because it seems like direct PaaS support for Clojure/Clojurescript apps is pretty limited.

Hope this helps someone else with the same problem.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.