Skip to content

Commit 21da03e

Browse files
anmonteirodnolen
authored andcommitted
CLJS-1973: Add support for :npm-deps in upstream deps.cljs
This patch addresses the second part of the solution outlined in the following design doc: https://github.com/clojure/clojurescript/wiki/Enhanced-Node.js-Modules-Support It adds support for specifying a `:npm-deps` option in upstream `deps.cljs` files, as well as very basic conflict handling.
1 parent e6abaa7 commit 21da03e

File tree

2 files changed

+76
-30
lines changed

2 files changed

+76
-30
lines changed

src/main/clojure/cljs/closure.clj

Lines changed: 69 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,7 +1754,12 @@
17541754
([classloader]
17551755
(let [upstream-deps (map #(read-string (slurp %))
17561756
(enumeration-seq (. classloader (getResources "deps.cljs"))))]
1757-
(apply merge-with concat upstream-deps))))
1757+
(apply merge-with
1758+
(fn [a b]
1759+
(if (map? a)
1760+
(merge-with #(into #{%1} #{%2}) a b)
1761+
(concat a b)))
1762+
upstream-deps))))
17581763

17591764
(def get-upstream-deps (memoize get-upstream-deps*))
17601765

@@ -1879,6 +1884,18 @@
18791884
(format ":cache-analysis format must be :edn or :transit but it is: %s"
18801885
(pr-str cache-analysis-format))))
18811886

1887+
(defn check-npm-deps [{:keys [npm-deps]}]
1888+
(let [{ups-npm-deps :npm-deps} (get-upstream-deps)
1889+
conflicts (filter (fn [[dep v]]
1890+
(and (coll? v) (not (contains? npm-deps dep))))
1891+
ups-npm-deps)]
1892+
(binding [*out* *err*]
1893+
(doseq [[dep versions] conflicts]
1894+
(println (str "WARNING: NPM dependency " (name dep)
1895+
" conflicts between versions "
1896+
(util/conjunction-str versions)
1897+
". Specify a version in :npm-deps or the latest will be installed."))))))
1898+
18821899
(defn foreign-source? [js]
18831900
(and (satisfies? deps/IJavaScript js)
18841901
(deps/-foreign? js)))
@@ -1917,16 +1934,32 @@
19171934

19181935
(declare index-node-modules)
19191936

1937+
(defn compute-upstream-npm-deps
1938+
([]
1939+
(compute-upstream-npm-deps
1940+
(when env/*compiler*
1941+
(:options @env/*compiler*))))
1942+
([{:keys [npm-deps]}]
1943+
(let [{ups-npm-deps :npm-deps} (get-upstream-deps)]
1944+
(reduce
1945+
(fn [m [dep v]]
1946+
(cond-> m
1947+
(not (contains? npm-deps dep))
1948+
(assoc dep (if (coll? v)
1949+
(last (sort v))
1950+
v))))
1951+
{} ups-npm-deps))))
1952+
19201953
(defn add-implicit-options
1921-
[{:keys [optimizations output-dir]
1954+
[{:keys [optimizations output-dir npm-deps]
19221955
:or {optimizations :none
19231956
output-dir "out"}
19241957
:as opts}]
19251958
(let [opts (cond-> (update opts :foreign-libs
19261959
(fn [libs]
19271960
(into []
19281961
(util/distinct-merge-by :file
1929-
(index-node-modules opts)
1962+
(index-node-modules npm-deps opts)
19301963
(expand-libs libs)))))
19311964
(:closure-defines opts)
19321965
(assoc :closure-defines
@@ -1946,7 +1979,10 @@
19461979
:optimizations optimizations
19471980
:output-dir output-dir
19481981
:ups-libs libs
1949-
:ups-foreign-libs foreign-libs
1982+
:ups-foreign-libs (into []
1983+
(util/distinct-merge-by :file
1984+
(index-node-modules (compute-upstream-npm-deps opts) opts)
1985+
(expand-libs foreign-libs)))
19501986
:ups-externs externs
19511987
:emit-constants emit-constants
19521988
:cache-analysis-format (:cache-analysis-format opts :transit))
@@ -1992,30 +2028,31 @@
19922028

19932029
(defn maybe-install-node-deps!
19942030
[{:keys [npm-deps verbose] :as opts}]
1995-
(if-not (empty? npm-deps)
1996-
(do
1997-
(when (or ana/*verbose* verbose)
1998-
(util/debug-prn "Installing Node.js dependencies"))
1999-
(let [proc (-> (ProcessBuilder.
2000-
(into ["npm" "install" "module-deps"]
2001-
(map (fn [[dep version]] (str (name dep) "@" version)))
2002-
npm-deps))
2003-
.start)
2004-
is (.getInputStream proc)
2005-
iw (StringWriter. (* 16 1024 1024))
2006-
es (.getErrorStream proc)
2007-
ew (StringWriter. (* 1024 1024))
2008-
_ (do (.start
2009-
(Thread.
2010-
(bound-fn [] (pipe proc is iw))))
2011-
(.start
2012-
(Thread.
2013-
(bound-fn [] (pipe proc es ew)))))
2014-
err (.waitFor proc)]
2015-
(when (and (not (zero? err)) (not (.isAlive proc)))
2016-
(println (str ew)))
2017-
opts))
2018-
opts))
2031+
(let [npm-deps (merge npm-deps (compute-upstream-npm-deps opts))]
2032+
(if-not (empty? npm-deps)
2033+
(do
2034+
(when (or ana/*verbose* verbose)
2035+
(util/debug-prn "Installing Node.js dependencies"))
2036+
(let [proc (-> (ProcessBuilder.
2037+
(into ["npm" "install" "module-deps"]
2038+
(map (fn [[dep version]] (str (name dep) "@" version)))
2039+
npm-deps))
2040+
.start)
2041+
is (.getInputStream proc)
2042+
iw (StringWriter. (* 16 1024 1024))
2043+
es (.getErrorStream proc)
2044+
ew (StringWriter. (* 1024 1024))
2045+
_ (do (.start
2046+
(Thread.
2047+
(bound-fn [] (pipe proc is iw))))
2048+
(.start
2049+
(Thread.
2050+
(bound-fn [] (pipe proc es ew)))))
2051+
err (.waitFor proc)]
2052+
(when (and (not (zero? err)) (not (.isAlive proc)))
2053+
(println (str ew)))
2054+
opts))
2055+
opts)))
20192056

20202057
(defn node-module-deps
20212058
"EXPERIMENTAL: return the foreign libs entries as computed by running
@@ -2069,11 +2106,11 @@
20692106
(into [] (distinct (mapcat #(node-module-deps % opts) entries)))))
20702107

20712108
(defn index-node-modules
2072-
([]
2109+
([npm-deps]
20732110
(index-node-modules
20742111
(when env/*compiler*
20752112
(:options @env/*compiler*))))
2076-
([{:keys [npm-deps] :as opts}]
2113+
([npm-deps opts]
20772114
(let [node-modules (io/file "node_modules")]
20782115
(when (and (.exists node-modules) (.isDirectory node-modules))
20792116
(let [modules (map name (keys npm-deps))
@@ -2183,6 +2220,8 @@
21832220
(add-externs-sources opts)))))
21842221
([source opts compiler-env]
21852222
(env/with-compiler-env compiler-env
2223+
;; we want to warn about NPM dep conflicts before installing the modules
2224+
(check-npm-deps opts)
21862225
(let [compiler-stats (:compiler-stats opts)
21872226
all-opts (-> opts
21882227
maybe-install-node-deps!

src/main/clojure/cljs/util.cljc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,3 +312,10 @@
312312
(recur (next ks) ret b')))
313313
(merge ret b')))
314314
a))
315+
316+
(defn conjunction-str [xs]
317+
(let [xs (vec xs)]
318+
(case (count xs)
319+
1 (first xs)
320+
2 (str (first xs) " and " (second xs))
321+
(str (string/join ", " (pop xs)) " and " (peek xs)))))

0 commit comments

Comments
 (0)