Skip to content

Commit 34cc207

Browse files
authored
Merge pull request #110 from clojure/bug/cljs-3332-firebase
CLJS-3332: improperly indexed Node libraries
2 parents 89b4c19 + a0116ce commit 34cc207

File tree

4 files changed

+88
-19
lines changed

4 files changed

+88
-19
lines changed

Diff for: src/main/clojure/cljs/closure.clj

+56-15
Original file line numberDiff line numberDiff line change
@@ -2766,27 +2766,68 @@
27662766
[]))))
27672767

27682768
(defn- node-file-seq->libs-spec*
2769+
"Given a sequence of non-nested node_module paths where the extension ends in
2770+
`.js/.json`, return lib-spec maps for each path containing at least :file,
2771+
:module-type, and :provides."
27692772
[module-fseq opts]
27702773
(letfn [(package-json? [path]
2771-
(boolean (re-find #"node_modules[/\\](@[^/\\]+?[/\\])?[^/\\]+?[/\\]package\.json$" path)))]
2772-
(let [pkg-jsons (into {}
2773-
(comp
2774-
(map #(.getAbsolutePath %))
2775-
(filter package-json?)
2776-
(map (fn [path]
2777-
[path (json/read-str (slurp path))])))
2778-
module-fseq)
2779-
trim-package-json (fn [s]
2780-
(if (string/ends-with? s "package.json")
2781-
(subs s 0 (- (count s) 12))
2782-
s))]
2774+
(= "package.json" (.getName (io/file path))))
2775+
2776+
(top-level-package-json? [path]
2777+
(boolean (re-find #"node_modules[/\\](@[^/\\]+?[/\\])?[^/\\]+?[/\\]package\.json$" path)))
2778+
2779+
;; the path sans the package.json part
2780+
;; i.e. some_lib/package.json -> some_lib
2781+
(trim-package-json [s]
2782+
(if (string/ends-with? s "package.json")
2783+
(subs s 0 (- (count s) 12))
2784+
s))
2785+
2786+
(trim-relative [path]
2787+
(cond-> path
2788+
(string/starts-with? path "./")
2789+
(subs 2)))
2790+
2791+
(add-exports [pkg-jsons]
2792+
(reduce-kv
2793+
(fn [pkg-jsons path {:strs [exports] :as pkg-json}]
2794+
(reduce-kv
2795+
(fn [pkg-jsons export _]
2796+
;; NOTE: ignore "." exports for now
2797+
(if (= "." export)
2798+
pkg-jsons
2799+
(let [export-pkg-json
2800+
(io/file
2801+
(trim-package-json path)
2802+
(trim-relative export)
2803+
"package.json")]
2804+
(cond-> pkg-jsons
2805+
(.exists export-pkg-json)
2806+
(assoc
2807+
(.getAbsolutePath export-pkg-json)
2808+
(json/read-str (slurp export-pkg-json)))))))
2809+
pkg-jsons exports))
2810+
pkg-jsons pkg-jsons))]
2811+
(let [
2812+
;; a map of all the *top-level* package.json paths and their exports
2813+
;; to the package.json contents as EDN
2814+
pkg-jsons (add-exports
2815+
(into {}
2816+
(comp
2817+
(map #(.getAbsolutePath %))
2818+
(filter top-level-package-json?)
2819+
(map (fn [path]
2820+
[path (json/read-str (slurp path))])))
2821+
module-fseq))]
27832822
(into []
27842823
(comp
27852824
(map #(.getAbsolutePath %))
27862825
(map (fn [path]
27872826
(merge
27882827
{:file path
27892828
:module-type :es6}
2829+
;; if the file is *not* a package.json, then compute what
2830+
;; namespaces it :provides to ClojureScript
27902831
(when-not (package-json? path)
27912832
(let [pkg-json-main (some
27922833
(fn [[pkg-json-path {:as pkg-json :strs [name]}]]
@@ -2795,13 +2836,13 @@
27952836
(when-not (nil? entry)
27962837
;; should be the only edge case in
27972838
;; the package.json main field - Antonio
2798-
(let [entry (cond-> entry
2799-
(string/starts-with? entry "./")
2800-
(subs 2))
2839+
(let [entry (trim-relative entry)
28012840
entry-path (-> pkg-json-path
28022841
(string/replace \\ \/)
28032842
trim-package-json
28042843
(str entry))]
2844+
;; find a package.json entry point that matches
2845+
;; the `path`
28052846
(some (fn [candidate]
28062847
(when (= candidate (string/replace path \\ \/))
28072848
name))

Diff for: src/main/clojure/cljs/util.cljc

+8-4
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
(if (== n Integer/MIN_VALUE)
4141
0
4242
(Math/abs n)))]
43-
(str synthethetic-version-prefix
43+
(str synthethetic-version-prefix
4444
(qualifier (reduce unchecked-add-int (map file-hash (file-seq (main-src-directory)))))))))
4545

4646
(defn ^String clojurescript-version
@@ -390,14 +390,18 @@
390390
(str (string/join ", " (pop xs)) " and " (peek xs)))))
391391

392392
(defn module-file-seq
393+
"Return a seq of all files in `node_modules` ending in `.js` or `.json` that are
394+
not in an internally nested `node_modules` dir."
393395
([] (module-file-seq (io/file "node_modules")))
394396
([dir]
395397
(let [fseq (tree-seq
396398
(fn [^File f]
399+
;; ignore embedded node_modules, the user did not install
400+
;; these
397401
(and (. f (isDirectory))
398-
(not (boolean
399-
(re-find #"node_modules[\\\/].*[\\\/]node_modules"
400-
(.getPath f))))))
402+
(not (boolean
403+
(re-find #"node_modules[\\\/].*[\\\/]node_modules"
404+
(.getPath f))))))
401405
(fn [^File d]
402406
(seq (. d (listFiles))))
403407
dir)]

Diff for: src/test/cljs_build/firebase/core.cljs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(ns firebase.core
2+
(:require ["firebase/auth" :as auth]))
3+

Diff for: src/test/clojure/cljs/build_api_tests.clj

+21
Original file line numberDiff line numberDiff line change
@@ -796,3 +796,24 @@
796796
(ana/with-warning-handlers [(collecting-warning-handler ws)]
797797
(build/build (build/inputs (io/file inputs "cljs_3311_regress/core.cljs")) opts cenv))
798798
(is (empty? @ws)))))
799+
800+
(deftest test-cljs-3332
801+
(testing "Test that package.json w/ exports work, Firebase as example"
802+
(let [out (.getPath (io/file (test/tmp-dir) "npm-deps-test-out"))]
803+
(test/delete-out-files out)
804+
(test/delete-node-modules)
805+
(spit (io/file "package.json") "{}")
806+
(let [{:keys [inputs opts]} {:inputs (str (io/file "src" "test" "cljs_build"))
807+
:opts {:main 'firebase.core
808+
:output-dir out
809+
:optimizations :none
810+
:install-deps true
811+
:npm-deps {:firebase "9.3.0"}
812+
:closure-warnings {:check-types :off}
813+
:target :bundle}}
814+
cenv (env/default-compiler-env)]
815+
(build/build (build/inputs (io/file inputs "firebase/core.cljs")) opts cenv)
816+
(is (= #{"firebase/auth"} (:node-module-index @cenv))))
817+
(.delete (io/file "package.json"))
818+
(test/delete-node-modules)
819+
(test/delete-out-files out))))

0 commit comments

Comments
 (0)