Skip to content

Commit 79041d1

Browse files
anmonteiroswannodette
authored andcommitted
CLJS-2334: Also gather dependencies from foreign-libs that are modules
1 parent 88e1f39 commit 79041d1

5 files changed

Lines changed: 121 additions & 42 deletions

File tree

src/main/clojure/cljs/closure.clj

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2198,7 +2198,8 @@
21982198
(next (json/read-str (str iw))))
21992199
(do
22002200
(when-not (.isAlive proc)
2201-
(println (str ew)))
2201+
(binding [*out* *err*]
2202+
(println (str ew))))
22022203
[])))))
22032204

22042205
(defn node-inputs
@@ -2330,6 +2331,9 @@
23302331
(ana/warning :unsupported-preprocess-value @env/*compiler* js-module)
23312332
js-module)))
23322333

2334+
(defn- to-absolute-path [^String file-str]
2335+
(.getAbsolutePath (io/file file-str)))
2336+
23332337
(defn process-js-modules
23342338
"Given the current compiler options, converts JavaScript modules to Google
23352339
Closure modules and writes them to disk. Adds mapping from original module
@@ -2347,15 +2351,20 @@
23472351
(map :module-type js-modules)))]
23482352
(ana/warning :unsupported-js-module-type @env/*compiler* unsupported))
23492353
;; Load all modules - add :source so preprocessing and conversion can access it
2350-
js-modules (map (fn [lib]
2351-
(let [js (deps/load-foreign-library lib)]
2352-
(assoc js :source (deps/-source js opts))))
2353-
js-modules)
2354-
js-modules (map (fn [js]
2355-
(if (:preprocess js)
2356-
(preprocess-js js opts)
2357-
js))
2358-
js-modules)
2354+
js-modules (into []
2355+
(comp
2356+
(map (fn [lib]
2357+
(let [js (deps/load-foreign-library lib)]
2358+
(assoc js :source (deps/-source js opts)))))
2359+
(map (fn [js]
2360+
(if (:preprocess js)
2361+
(preprocess-js js opts)
2362+
js)))
2363+
(map (fn [js]
2364+
(cond-> (update-in js [:file] to-absolute-path)
2365+
(some? (:file-min js))
2366+
(update-in [:file-min] to-absolute-path)))))
2367+
js-modules)
23592368
js-modules (convert-js-modules js-modules opts)]
23602369
;; Write modules to disk, update compiler state and build new options
23612370
(reduce (fn [new-opts {:keys [file module-type] :as ijs}]
@@ -2368,9 +2377,17 @@
23682377
(-> new-opts
23692378
(update-in [:libs] (comp vec conj) (:out-file ijs))
23702379
;; js-module might be defined in either, so update both
2371-
(update-in [:foreign-libs] (comp vec (fn [libs] (remove #(= (:file %) file) libs))))
2372-
(update-in [:ups-foreign-libs] (comp vec (fn [libs] (remove #(= (:file %) file) libs)))))))
2373-
opts js-modules)))
2380+
(update-in [:foreign-libs]
2381+
(fn [libs]
2382+
(into []
2383+
(remove #(= (to-absolute-path (:file %)) file))
2384+
libs)))
2385+
(update-in [:ups-foreign-libs]
2386+
(fn [libs]
2387+
(into []
2388+
(remove #(= (to-absolute-path (:file %)) (to-absolute-path file)))
2389+
libs))))))
2390+
opts js-modules)))
23742391
opts)))
23752392

23762393
(defn- load-data-reader-file [mappings ^java.net.URL url]
@@ -2437,25 +2454,30 @@
24372454
requires (set (mapcat deps/-requires js-sources))
24382455
;; Select Node files that are required by Cljs code,
24392456
;; and create list of all their dependencies
2440-
node-required (set/intersection (set (keys top-level)) requires)]
2441-
(let [opts (-> opts
2457+
node-required (set/intersection (set (keys top-level)) requires)
2458+
expanded-libs (expand-libs (:foreign-libs opts))
2459+
opts (-> opts
24422460
(update :foreign-libs
24432461
(fn [libs]
24442462
(into (if (= target :nodejs)
24452463
[]
24462464
(index-node-modules node-required))
2447-
(expand-libs libs))))
2465+
(into expanded-libs
2466+
(node-inputs (filter (fn [{:keys [module-type]}]
2467+
(and (some? module-type)
2468+
(not= module-type :amd)))
2469+
expanded-libs))))))
24482470
process-js-modules)]
2449-
(swap! compiler-env (fn [cenv]
2450-
(-> cenv
2451-
;; we need to also track the whole top level - this is to support
2452-
;; cljs.analyze/analyze-deps, particularly in REPL contexts - David
2453-
(merge {:js-dependency-index (deps/js-dependency-index opts)})
2454-
(update-in [:node-module-index] (fnil into #{})
2455-
(if (= target :nodejs)
2456-
(map str node-required)
2457-
(map str (keys top-level)))))))
2458-
opts)))
2471+
(swap! compiler-env (fn [cenv]
2472+
(-> cenv
2473+
;; we need to also track the whole top level - this is to support
2474+
;; cljs.analyze/analyze-deps, particularly in REPL contexts - David
2475+
(merge {:js-dependency-index (deps/js-dependency-index opts)})
2476+
(update-in [:node-module-index] (fnil into #{})
2477+
(if (= target :nodejs)
2478+
(map str node-required)
2479+
(map str (keys top-level)))))))
2480+
opts))
24592481

24602482
(defn build
24612483
"Given a source which can be compiled, produce runnable JavaScript."
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(ns foreign-libs-cljs-2334.core
2+
(:require [mylib]))
3+
4+
(enable-console-print!)
5+
6+
(println "mylib:" mylib)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import leftPad from 'left-pad';
2+
3+
export var lp = function() {
4+
return leftPad(42, 5, 0);
5+
}

src/test/clojure/cljs/build_api_tests.clj

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,5 +497,29 @@
497497
(test/delete-out-files out)
498498
(build/build (build/inputs (io/file inputs "foreign_libs_dir_test/core.cljs")) opts)
499499
(is (.exists (io/file out "src/test/cljs_build/foreign-libs-dir/vendor/lib.js")))
500-
(is (true? (boolean (re-find #"goog\.provide\(\"module\$src\$test\$cljs_build\$foreign_libs_dir\$vendor\$lib\"\)"
500+
(is (true? (boolean (re-find #"goog\.provide\(\"module\$[A-Za-z0-9$_]+?src\$test\$cljs_build\$foreign_libs_dir\$vendor\$lib\"\)"
501501
(slurp (io/file out "src/test/cljs_build/foreign-libs-dir/vendor/lib.js"))))))))
502+
503+
(deftest cljs-1883-test-foreign-libs-use-relative-path
504+
(test/delete-node-modules)
505+
(let [out "cljs-2334-out"
506+
root (io/file "src" "test" "cljs_build")
507+
opts {:foreign-libs
508+
[{:file (str (io/file root "foreign_libs_cljs_2334" "lib.js"))
509+
:module-type :es6
510+
:provides ["mylib"]}]
511+
:npm-deps {:left-pad "1.1.3"}
512+
:install-deps true
513+
:output-dir (str out)}]
514+
(test/delete-out-files out)
515+
(build/build (build/inputs (io/file root "foreign_libs_cljs_2334")) opts)
516+
(let [foreign-lib-file (io/file out (-> opts :foreign-libs first :file))]
517+
(is (.exists foreign-lib-file))
518+
;; assert Closure finds and processes the left-pad dep in node_modules
519+
;; if it can't be found the require will be issued to module$left_pad
520+
;; so we assert it's of the form module$path$to$node_modules$left_pad$index
521+
(is (some? (re-find
522+
#"(?s).*?goog\.require\(\"[A-Za-z0-9$_]+?node_modules\$left_pad\$index\"\);.*"
523+
(slurp foreign-lib-file)))))
524+
(test/delete-out-files out)
525+
(test/delete-node-modules)))

src/test/clojure/cljs/module_processing_tests.clj

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
(ns cljs.module-processing-tests
22
(:require [clojure.java.io :as io]
33
[cljs.closure :as closure]
4-
[clojure.test :refer :all]
4+
[clojure.string :as string]
5+
[clojure.test :refer [deftest is]]
56
[cljs.env :as env]
67
[cljs.analyzer :as ana]
78
[cljs.compiler :as comp]
89
[cljs.js-deps :as deps]
910
[cljs.util :as util]
10-
[cljs.test-util :as test]))
11+
[cljs.test-util :as test])
12+
(:import [java.io File]))
1113

1214
;; Hard coded JSX transform for the test case
1315
(defn preprocess-jsx [ijs _]
@@ -23,6 +25,24 @@
2325
"React.createElement(\"circle\", {cx:\"100px\", cy:\"100px\", r:\"100px\", fill:this.props.color})"
2426
")"))))
2527

28+
(defn absolute-module-path
29+
([relpath]
30+
(absolute-module-path relpath false))
31+
([relpath code?]
32+
(let [filename (as-> (subs relpath (inc (.lastIndexOf relpath "/"))) $
33+
(string/replace $ "_" "-")
34+
(subs $ 0 (.lastIndexOf $ ".")))
35+
dirname (as-> (io/file relpath) $
36+
(.getAbsolutePath $)
37+
(subs $ 0 (.lastIndexOf $ (str File/separator)))
38+
(string/replace $ "/" "$")
39+
;; Windows
40+
(string/replace $ "\\" "$")
41+
(if code?
42+
(string/replace $ ":" "_")
43+
(string/replace $ ":" "-")))]
44+
(str "module" (when-not (.startsWith dirname "$") "$") dirname "$" filename))))
45+
2646
(defmethod closure/js-transforms :jsx [ijs opts]
2747
(preprocess-jsx ijs opts))
2848

@@ -47,10 +67,9 @@
4767
:preprocess :jsx}]
4868
:closure-warnings {:non-standard-jsdoc :off}})))
4969
"processed modules are added to :libs"))
50-
51-
(is (= {"React" {:name "module$src$test$cljs$reactJS"
70+
(is (= {"React" {:name (absolute-module-path "src/test/cljs/reactJS.js")
5271
:module-type :commonjs}
53-
"Circle" {:name "module$src$test$cljs$Circle"
72+
"Circle" {:name (absolute-module-path "src/test/cljs/Circle.js")
5473
:module-type :commonjs}}
5574
(:js-module-index @cenv))
5675
"Processed modules are added to :js-module-index")))
@@ -74,13 +93,14 @@
7493
:closure-warnings {:non-standard-jsdoc :off}})))
7594
"processed modules are added to :libs")
7695

77-
(is (= {"es6-hello" {:name "module$src$test$cljs$es6-hello"
96+
(is (= {"es6-hello" {:name (absolute-module-path "src/test/cljs/es6_hello.js")
7897
:module-type :es6}}
7998
(:js-module-index @cenv))
8099
"Processed modules are added to :js-module-index")
81100

82-
(is (= "goog.provide(\"module$src$test$cljs$es6_hello\");var sayHello$$module$src$test$cljs$es6_hello=function(){console.log(\"Hello, world!\")};module$src$test$cljs$es6_hello.sayHello=sayHello$$module$src$test$cljs$es6_hello"
83-
(slurp "out/src/test/cljs/es6_hello.js"))))))
101+
(is (re-find
102+
#"goog.provide\(\"module\$[a-zA-Z0-9$_]+?src\$test\$cljs\$es6_hello\"\);"
103+
(slurp "out/src/test/cljs/es6_hello.js"))))))
84104

85105
(deftest test-module-name-substitution
86106
(test/delete-out-files)
@@ -93,19 +113,21 @@
93113
(with-out-str
94114
(comp/emit (ana/analyze (ana/empty-env) form))))
95115
crlf (if util/windows? "\r\n" "\n")
96-
output (str "module$src$test$cljs$calculator.add((3),(4));" crlf)]
116+
output (str (absolute-module-path "src/test/cljs/calculator.js" true) ".add((3),(4));" crlf)]
97117
(swap! cenv
98118
#(assoc % :js-dependency-index (deps/js-dependency-index opts)))
99119
(binding [ana/*cljs-ns* 'cljs.user]
100120
(is (= (compile '(ns my-calculator.core (:require [calculator :as calc :refer [subtract add] :rename {subtract sub}])))
101121
(str "goog.provide('my_calculator.core');" crlf
102122
"goog.require('cljs.core');" crlf
103-
"goog.require('module$src$test$cljs$calculator');" crlf)))
123+
"goog.require('" (absolute-module-path "src/test/cljs/calculator.js" true) "');"
124+
crlf)))
104125
(is (= (compile '(calc/add 3 4)) output))
105126
(is (= (compile '(calculator/add 3 4)) output))
106127
(is (= (compile '(add 3 4)) output))
107128
(is (= (compile '(sub 5 4))
108-
(str "module$src$test$cljs$calculator.subtract((5),(4));" crlf))))))))
129+
(str (absolute-module-path "src/test/cljs/calculator.js" true)
130+
".subtract((5),(4));" crlf))))))))
109131

110132
(deftest test-cljs-1822
111133
(test/delete-out-files)
@@ -132,9 +154,9 @@
132154
:preprocess :jsx}]
133155
:closure-warnings {:non-standard-jsdoc :off}})))
134156
"processed modules are added to :libs"))
135-
(is (= {"React" {:name "module$src$test$cljs$react-min"
157+
(is (= {"React" {:name (absolute-module-path "src/test/cljs/react-min.js")
136158
:module-type :commonjs}
137-
"Circle" {:name "module$src$test$cljs$Circle-min"
159+
"Circle" {:name (absolute-module-path "src/test/cljs/Circle-min.js")
138160
:module-type :commonjs}}
139161
(:js-module-index @cenv))
140162
"Processed modules are added to :js-module-index")))
@@ -161,9 +183,9 @@
161183
:closure-warnings {:non-standard-jsdoc :off}})))
162184
"processed modules are added to :libs"))
163185

164-
(is (= {"React" {:name "module$src$test$cljs$reactJS"
186+
(is (= {"React" {:name (absolute-module-path "src/test/cljs/reactJS.js")
165187
:module-type :commonjs}
166-
"Circle" {:name "module$src$test$cljs$Circle"
188+
"Circle" {:name (absolute-module-path "src/test/cljs/Circle.js")
167189
:module-type :commonjs}}
168190
(:js-module-index @cenv))
169191
"Processed modules are added to :js-module-index")))

0 commit comments

Comments
 (0)