Clojure + приложение Clojurescript на Heroku: зависимости пакетов npm не устанавливаются при развертывании приложения - PullRequest
1 голос
/ 19 июня 2019

Я пишу веб-приложение с бэкэндом в Clojure и внешним интерфейсом в Clojurescript с React и Reagent. Я пытаюсь разместить его на Heroku.

Когда я запускаю lein ubjerar локально, он прекрасно работает, и приложение работает.

Однако, когда я пытаюсь развернуть приложение в Heroku через git push heroku master, у меня всегда возникает ошибка, подобная этой:

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)

Это происходит несмотря на то, что object-assign указан как зависимость пакета react npm, который я уже перечислил как элемент в :npm-deps в моем project.clj. Я убедился, что при локальной сборке пакет устанавливается нормально (т. Е. В этом случае node_modules/object-assign существует).

Когда я вручную добавляю object-assign в качестве явной зависимости в :npm-deps, я получаю ту же ошибку, но жалуюсь на другую отсутствующую зависимость, которая должна быть установлена ​​автоматически (а делает локально). Когда я добавляю отсутствующую зависимость new , она жалуется на другую. Когда я строю локально с новыми явными зависимостями, lein uberjar работает, но жалуется, что в настоящее время существуют конфликты версий, потому что неявные зависимости часто исправляются в другой версии.

Есть идеи, как мне это исправить?

РЕДАКТИРОВАТЬ Вот мой project.clj

(defproject getfluentspanish "0.1.0-SNAPSHOT"

  :description "FIXME: write description"
  :url "http://example.com/FIXME"

  :dependencies [[cheshire "5.8.1"]
                 [cljs-ajax "0.8.0"]
                 [clojure.java-time "0.3.2"]
                 [com.cognitect/transit-clj "0.8.313"]
                 [com.google.javascript/closure-compiler-unshaded "v20190528" :scope "provided"]
                 [cprop "0.1.13"]
                 [day8.re-frame/http-fx "0.1.6"]
                 [funcool/struct "1.4.0"]
                 [luminus-immutant "0.2.5"]
                 [luminus-transit "0.1.1"]
                 [markdown-clj "1.10.0"]
                 [metosin/muuntaja "0.6.4"]
                 [metosin/reitit "0.3.7"]
                 [metosin/ring-http-response "0.9.1"]
                 [mount "0.1.16"]
                 [nrepl "0.6.0"]
                 [org.clojure/clojure "1.10.1"]
                 [org.clojure/clojurescript "1.10.520" :scope "provided"]
                 [org.clojure/google-closure-library "0.0-20190213-2033d5d9" :scope "provided"]
                 [org.clojure/tools.cli "0.4.2"]
                 [org.clojure/tools.logging "0.4.1"]
                 [org.webjars.npm/bulma "0.7.5"]
                 [org.webjars.npm/material-icons "0.3.0"]
                 [org.webjars/webjars-locator "0.36"]
                 [org.webjars/webjars-locator-jboss-vfs "0.1.0"]
                 [re-frame "0.10.6"]
                 [reagent "0.8.1"]
                 [ring-webjars "0.2.0"]
                 [ring/ring-core "1.7.1"]
                 [ring/ring-defaults "0.3.2"]
                 [selmer "1.12.12"]
                 [thheller/shadow-cljs "2.8.39" :scope "provided"]]

  :min-lein-version "2.0.0"

  :source-paths ["src/clj" "src/cljs" "src/cljc"]
  :test-paths ["test/clj"]
  :resource-paths ["resources" "target/cljsbuild"]
  :target-path "target/%s/"
  :main ^:skip-aot getfluentspanish.core

  :plugins [[lein-shadow "0.1.3"]
            [lein-immutant "2.1.0"]
            [lein-sassc "0.10.4"]
            [lein-auto "0.1.2"]]
   :sassc
   [{:src "resources/scss/screen.scss"
     :output-to "resources/public/css/screen.css"
     :style "nested"
     :import-path "resources/scss"}] 

   :auto
   {"sassc" {:file-pattern #"\.(scss|sass)$" :paths ["resources/scss"]}} 

  :hooks [leiningen.sassc]
  :clean-targets ^{:protect false}
  [:target-path "target/cljsbuild"]
  :shadow-cljs
  {:nrepl {:port 7002}
   :builds
   {:app
    {:target :browser
     :output-dir "target/cljsbuild/public/js"
     :asset-path "/js"
     :modules {:app {:entries [getfluentspanish.app]}}
     :devtools {:watch-dir "resources/public"}}
    :test
    {:target :node-test
     :output-to "target/test/test.js"
     :autorun true}}}

  :npm-deps [[core-js "^2.6.9"]
             [shadow-cljs "2.8.31"]
             [create-react-class "15.6.3"]
             [react "16.8.6"]
             [react-dom "16.8.6"]
             [react-beautiful-dnd "11.0.4"]
             [react-dnd "7.6.0"]
             [react-dnd-html5-backend "7.6.0"]
             [react-dnd-touch-backend "0.8.3"]
             [react-dnd-multi-backend "3.2.1"]]

  :profiles
  {:uberjar {:omit-source true
             :prep-tasks ["compile" ["shadow" "release" "app"]]

             :aot :all
             :uberjar-name "getfluentspanish.jar"
             :source-paths ["env/prod/clj" "env/prod/cljs"]
             :resource-paths ["env/prod/resources"]}

   :dev           [:project/dev :profiles/dev]
   :test          [:project/dev :project/test :profiles/test]

   :project/dev  {:jvm-opts ["-Dconf=dev-config.edn"]
                  :dependencies [[binaryage/devtools "0.9.10"]
                                 [cider/piggieback "0.4.1"]
                                 [expound "0.7.2"]
                                 [pjstadig/humane-test-output "0.9.0"]
                                 [prone "1.6.3"]
                                 [re-frisk "0.5.4.1"]
                                 [ring/ring-devel "1.7.1"]
                                 [ring/ring-mock "0.4.0"]]
                  :plugins      [[com.jakemccrary/lein-test-refresh "0.24.1"]]


                  :source-paths ["env/dev/clj" "env/dev/cljs" "test/cljs"]
                  :resource-paths ["env/dev/resources"]
                  :repl-options {:init-ns user}
                  :injections [(require 'pjstadig.humane-test-output)
                               (pjstadig.humane-test-output/activate!)]}
   :project/test {:jvm-opts ["-Dconf=test-config.edn"]
                  :resource-paths ["env/test/resources"]}



   :profiles/dev {}
   :profiles/test {}})

РЕДАКТИРОВАТЬ 2 В итоге я отказался от подхода развертывания git push heroku master и переключился на Docker. Я подробно описал процесс в ответе ниже.

Ответы [ 2 ]

0 голосов
/ 25 июня 2019

В итоге я отказался от развертывания Heroku на основе Git и вместо этого переработал его, чтобы использовать вместо него Docker.Теперь это работает, но единственным недостатком является то, что мне теперь приходится локально создавать новый образ Docker каждый раз, когда я хочу развернуть, который медленнее, чем git push heroku master, за которым следует lein uberjar на удаленном компьютере.Однако я могу перенести этот шаг на CI-сервер или что-то еще позже и выполнять сборку и развертывание через перехватчики Github, обеспечивая мне такой же уровень удобства.

На самом деле я был действительно впечатлен простотой использования Docker.Dockerfile, который я использую, исключительно тривиален:

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

Надеюсь, это поможет любому, кто пытается использовать его при попытке развернуть полнофункциональное приложение Clojure & Clojurescript на Heroku.

0 голосов
/ 21 июня 2019

Ваш проект основан на каком-то фреймворке (например, Luminus)?Можете ли вы опубликовать свой project.clj файл?Эта информация поможет другим понять, что происходит.

В зависимости от конфигурации вашего проекта, выполнение lein uberjar может делать разные вещи.Чаще всего используется серверная часть Clojure, где задача uberjar выполняет компиляцию Clojure и Java в байт-код и упаковывает результаты в файл JAR.Также возможно, что у вас есть псевдоним, который добавляет шаги для загрузки зависимостей из NPM и компиляции ClojureScript в ресурсы, которые также упакованы как часть JAR, но трудно сказать, не глядя на файл project.clj.

...