Skip to content

Commit

Permalink
Merge pull request #110 from clojure/bug/cljs-3332-firebase
Browse files Browse the repository at this point in the history
CLJS-3332: improperly indexed Node libraries
  • Loading branch information
swannodette authored Dec 17, 2021
2 parents 89b4c19 + a0116ce commit 34cc207
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 19 deletions.
71 changes: 56 additions & 15 deletions src/main/clojure/cljs/closure.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2766,27 +2766,68 @@
[]))))

(defn- node-file-seq->libs-spec*
"Given a sequence of non-nested node_module paths where the extension ends in
`.js/.json`, return lib-spec maps for each path containing at least :file,
:module-type, and :provides."
[module-fseq opts]
(letfn [(package-json? [path]
(boolean (re-find #"node_modules[/\\](@[^/\\]+?[/\\])?[^/\\]+?[/\\]package\.json$" path)))]
(let [pkg-jsons (into {}
(comp
(map #(.getAbsolutePath %))
(filter package-json?)
(map (fn [path]
[path (json/read-str (slurp path))])))
module-fseq)
trim-package-json (fn [s]
(if (string/ends-with? s "package.json")
(subs s 0 (- (count s) 12))
s))]
(= "package.json" (.getName (io/file path))))

(top-level-package-json? [path]
(boolean (re-find #"node_modules[/\\](@[^/\\]+?[/\\])?[^/\\]+?[/\\]package\.json$" path)))

;; the path sans the package.json part
;; i.e. some_lib/package.json -> some_lib
(trim-package-json [s]
(if (string/ends-with? s "package.json")
(subs s 0 (- (count s) 12))
s))

(trim-relative [path]
(cond-> path
(string/starts-with? path "./")
(subs 2)))

(add-exports [pkg-jsons]
(reduce-kv
(fn [pkg-jsons path {:strs [exports] :as pkg-json}]
(reduce-kv
(fn [pkg-jsons export _]
;; NOTE: ignore "." exports for now
(if (= "." export)
pkg-jsons
(let [export-pkg-json
(io/file
(trim-package-json path)
(trim-relative export)
"package.json")]
(cond-> pkg-jsons
(.exists export-pkg-json)
(assoc
(.getAbsolutePath export-pkg-json)
(json/read-str (slurp export-pkg-json)))))))
pkg-jsons exports))
pkg-jsons pkg-jsons))]
(let [
;; a map of all the *top-level* package.json paths and their exports
;; to the package.json contents as EDN
pkg-jsons (add-exports
(into {}
(comp
(map #(.getAbsolutePath %))
(filter top-level-package-json?)
(map (fn [path]
[path (json/read-str (slurp path))])))
module-fseq))]
(into []
(comp
(map #(.getAbsolutePath %))
(map (fn [path]
(merge
{:file path
:module-type :es6}
;; if the file is *not* a package.json, then compute what
;; namespaces it :provides to ClojureScript
(when-not (package-json? path)
(let [pkg-json-main (some
(fn [[pkg-json-path {:as pkg-json :strs [name]}]]
Expand All @@ -2795,13 +2836,13 @@
(when-not (nil? entry)
;; should be the only edge case in
;; the package.json main field - Antonio
(let [entry (cond-> entry
(string/starts-with? entry "./")
(subs 2))
(let [entry (trim-relative entry)
entry-path (-> pkg-json-path
(string/replace \\ \/)
trim-package-json
(str entry))]
;; find a package.json entry point that matches
;; the `path`
(some (fn [candidate]
(when (= candidate (string/replace path \\ \/))
name))
Expand Down
12 changes: 8 additions & 4 deletions src/main/clojure/cljs/util.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
(if (== n Integer/MIN_VALUE)
0
(Math/abs n)))]
(str synthethetic-version-prefix
(str synthethetic-version-prefix
(qualifier (reduce unchecked-add-int (map file-hash (file-seq (main-src-directory)))))))))

(defn ^String clojurescript-version
Expand Down Expand Up @@ -390,14 +390,18 @@
(str (string/join ", " (pop xs)) " and " (peek xs)))))

(defn module-file-seq
"Return a seq of all files in `node_modules` ending in `.js` or `.json` that are
not in an internally nested `node_modules` dir."
([] (module-file-seq (io/file "node_modules")))
([dir]
(let [fseq (tree-seq
(fn [^File f]
;; ignore embedded node_modules, the user did not install
;; these
(and (. f (isDirectory))
(not (boolean
(re-find #"node_modules[\\\/].*[\\\/]node_modules"
(.getPath f))))))
(not (boolean
(re-find #"node_modules[\\\/].*[\\\/]node_modules"
(.getPath f))))))
(fn [^File d]
(seq (. d (listFiles))))
dir)]
Expand Down
3 changes: 3 additions & 0 deletions src/test/cljs_build/firebase/core.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(ns firebase.core
(:require ["firebase/auth" :as auth]))

21 changes: 21 additions & 0 deletions src/test/clojure/cljs/build_api_tests.clj
Original file line number Diff line number Diff line change
Expand Up @@ -796,3 +796,24 @@
(ana/with-warning-handlers [(collecting-warning-handler ws)]
(build/build (build/inputs (io/file inputs "cljs_3311_regress/core.cljs")) opts cenv))
(is (empty? @ws)))))

(deftest test-cljs-3332
(testing "Test that package.json w/ exports work, Firebase as example"
(let [out (.getPath (io/file (test/tmp-dir) "npm-deps-test-out"))]
(test/delete-out-files out)
(test/delete-node-modules)
(spit (io/file "package.json") "{}")
(let [{:keys [inputs opts]} {:inputs (str (io/file "src" "test" "cljs_build"))
:opts {:main 'firebase.core
:output-dir out
:optimizations :none
:install-deps true
:npm-deps {:firebase "9.3.0"}
:closure-warnings {:check-types :off}
:target :bundle}}
cenv (env/default-compiler-env)]
(build/build (build/inputs (io/file inputs "firebase/core.cljs")) opts cenv)
(is (= #{"firebase/auth"} (:node-module-index @cenv))))
(.delete (io/file "package.json"))
(test/delete-node-modules)
(test/delete-out-files out))))

0 comments on commit 34cc207

Please sign in to comment.