Skip to content

Commit 70d9405

Browse files
Maria Neisednolen
authored andcommitted
CLJS-1360: Refactor JS module processing to work with recent Google Closure compiler changes
The functionality of the ES6ModuleLoader has been rewritten, including some functionality that we use, such as the toModuleName method and the constructor of the ES6ModuleLoader. We now need to pass all modules of the same type to the Compiler, but are still converting only one module at a time. Also, it's safer to just get the module name from the converted lib directly instead of the method toModuleName. This change supports both versions of the ES6ModuleLoader for now. Once a new version of the Google Closure compiler gets released, we can probably remove support for the older version. Changes to the ES6ModuleLoader can be seen here: google/closure-compiler#1043.
1 parent a1dca29 commit 70d9405

File tree

1 file changed

+73
-53
lines changed

1 file changed

+73
-53
lines changed

src/main/clojure/cljs/closure.clj

Lines changed: 73 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
CommandLineRunner AnonymousFunctionNamingPolicy
5656
JSModule JSModuleGraph SourceMap ProcessCommonJSModules
5757
ES6ModuleLoader AbstractCompiler TransformAMDToCJSModule
58-
ProcessEs6Modules]
58+
ProcessEs6Modules CompilerInput]
5959
[com.google.javascript.rhino Node]
6060
[java.security MessageDigest]
6161
[javax.xml.bind DatatypeConverter]
@@ -72,44 +72,45 @@
7272
(defn random-string [length]
7373
(apply str (take length (repeatedly random-char))))
7474

75-
(defmacro ^:private compile-if
76-
"Evaluate `exp` and if it returns logical true and doesn't error, expand to
77-
`then`. Else expand to `else`."
78-
[exp then & else]
79-
(if (try (eval exp)
80-
(catch Throwable _ false))
81-
`(do ~then)
82-
`(do ~@else)))
83-
84-
(compile-if
75+
(util/compile-if
76+
(.getConstructor ES6ModuleLoader
77+
(into-array java.lang.Class
78+
[java.util.List java.lang.Iterable]))
79+
(do (def is-new-es6-loader? true)
80+
(def default-module-root ES6ModuleLoader/DEFAULT_FILENAME_PREFIX))
81+
(def is-new-es6-loader? false))
82+
83+
(util/compile-if
84+
(.getConstructor ES6ModuleLoader
85+
(into-array java.lang.Class
86+
[AbstractCompiler java.lang.String]))
87+
(def is-old-es6-loader? true)
88+
(def is-old-es6-loader? false))
89+
90+
(util/compile-if
8591
(and (.getConstructor ProcessCommonJSModules
8692
(into-array java.lang.Class
8793
[com.google.javascript.jscomp.Compiler ES6ModuleLoader]))
88-
(.getConstructor ES6ModuleLoader
89-
(into-array java.lang.Class
90-
[AbstractCompiler java.lang.String])))
94+
(or is-new-es6-loader? is-old-es6-loader?))
9195
(def can-convert-commonjs? true)
9296
(def can-convert-commonjs? false))
9397

94-
(compile-if
98+
(util/compile-if
9599
(and can-convert-commonjs?
96100
(.getConstructor TransformAMDToCJSModule
97101
(into-array java.lang.Class
98102
[AbstractCompiler])))
99103
(def can-convert-amd? true)
100104
(def can-convert-amd? false))
101105

102-
(compile-if
106+
(util/compile-if
103107
(and (.getConstructor ProcessEs6Modules
104108
(into-array java.lang.Class
105109
[com.google.javascript.jscomp.Compiler ES6ModuleLoader Boolean/TYPE]))
106-
(.getConstructor ES6ModuleLoader
107-
(into-array java.lang.Class
108-
[AbstractCompiler java.lang.String])))
110+
(or is-new-es6-loader? is-old-es6-loader?))
109111
(def can-convert-es6? true)
110112
(def can-convert-es6? false))
111113

112-
113114
;; Closure API
114115
;; ===========
115116

@@ -1227,53 +1228,73 @@
12271228
(not (.startsWith path (str "." File/separator))) (str "." File/separator)
12281229
(not (.endsWith path File/separator)) (#(str % File/separator)))))
12291230

1230-
(defn init-js-module-processing [js-file options]
1231-
(let [^List externs '()
1232-
^SourceFile source-file (js-source-file js-file (slurp js-file))
1233-
closure-compiler (doto (make-closure-compiler)
1234-
(.init externs [source-file] options))
1235-
^Node root (.parse closure-compiler source-file)]
1236-
{:closure-compiler closure-compiler
1237-
:root root}))
1231+
(util/compile-if is-new-es6-loader?
1232+
(defn make-es6-loader [source-files]
1233+
(let [^List module-roots (list default-module-root)
1234+
^List compiler-inputs (map #(CompilerInput. %) source-files)]
1235+
(ES6ModuleLoader. module-roots compiler-inputs)))
1236+
(defn make-es6-loader [closure-compiler file]
1237+
(let [module-root (get-js-module-root file)]
1238+
(ES6ModuleLoader. closure-compiler module-root))))
1239+
1240+
(defn ^Node get-root-node [file closure-compiler]
1241+
(let [^CompilerInput input (->> (slurp file)
1242+
(js-source-file file)
1243+
(CompilerInput.))]
1244+
(.getAstRoot input closure-compiler)))
1245+
1246+
(defn get-source-files [module-type opts]
1247+
(->> (:foreign-libs opts)
1248+
(filter #(= (:module-type %) module-type))
1249+
(map #(js-source-file (:file %) (slurp (:file %))))))
12381250

12391251
(defmulti convert-js-module
12401252
"Takes a JavaScript module and rewrites it into a Google Closure-compatible
12411253
form. Returns the source of the new module as a single string."
1242-
(fn [{module-type :module-type :as js}]
1254+
(fn [{module-type :module-type :as js} opts]
12431255
(if (and (= module-type :amd) can-convert-amd?)
12441256
;; AMD modules are converted via CommonJS modules
12451257
:commonjs
12461258
module-type)))
12471259

1248-
(compile-if can-convert-commonjs?
1249-
(defmethod convert-js-module :commonjs [js]
1250-
(let [js-file (:file js)
1251-
path (.getParent (io/file js-file))
1252-
module-root (get-js-module-root js-file)
1260+
(util/compile-if can-convert-commonjs?
1261+
(defmethod convert-js-module :commonjs [js opts]
1262+
(let [{:keys [file module-type]} js
1263+
^List externs '()
1264+
^List source-files (get-source-files module-type opts)
12531265
^CompilerOptions options (CompilerOptions.)
1254-
{:keys [closure-compiler root]} (init-js-module-processing js-file options)
1255-
es6-loader (ES6ModuleLoader. closure-compiler module-root)
1256-
cjs (ProcessCommonJSModules. closure-compiler es6-loader)]
1257-
(compile-if can-convert-amd?
1266+
closure-compiler (doto (make-closure-compiler)
1267+
(.init externs source-files options))
1268+
es6-loader (if is-new-es6-loader?
1269+
(make-es6-loader source-files)
1270+
(make-es6-loader closure-compiler file))
1271+
cjs (ProcessCommonJSModules. closure-compiler es6-loader)
1272+
^Node root (get-root-node file closure-compiler)]
1273+
(util/compile-if can-convert-amd?
12581274
(when (= (:module-type js) :amd)
12591275
(.process (TransformAMDToCJSModule. closure-compiler) nil root)))
12601276
(.process cjs nil root)
12611277
(.toSource closure-compiler root))))
12621278

1263-
(compile-if can-convert-es6?
1264-
(defmethod convert-js-module :es6 [js]
1265-
(let [js-file (:file js)
1266-
module-root (get-js-module-root js-file)
1279+
(util/compile-if can-convert-es6?
1280+
(defmethod convert-js-module :es6 [js opts]
1281+
(let [{:keys [file module-type]} js
1282+
^List externs '()
1283+
^List source-files (get-source-files module-type opts)
12671284
^CompilerOptions options (doto (CompilerOptions.)
12681285
(.setLanguageIn CompilerOptions$LanguageMode/ECMASCRIPT6)
12691286
(.setLanguageOut CompilerOptions$LanguageMode/ECMASCRIPT5))
1270-
{:keys [closure-compiler root]} (init-js-module-processing js-file options)
1271-
es6-loader (ES6ModuleLoader. closure-compiler module-root)
1272-
cjs (ProcessEs6Modules. closure-compiler es6-loader true)]
1287+
closure-compiler (doto (make-closure-compiler)
1288+
(.init externs source-files options))
1289+
es6-loader (if is-new-es6-loader?
1290+
(make-es6-loader source-files)
1291+
(make-es6-loader closure-compiler file))
1292+
cjs (ProcessEs6Modules. closure-compiler es6-loader true)
1293+
^Node root (get-root-node file closure-compiler)]
12731294
(.processFile cjs root)
12741295
(.toSource closure-compiler root))))
12751296

1276-
(defmethod convert-js-module :default [js]
1297+
(defmethod convert-js-module :default [js opts]
12771298
(ana/warning :unsupported-js-module-type @env/*compiler* js)
12781299
(deps/-source js))
12791300

@@ -1293,7 +1314,7 @@
12931314
(when-not (.exists out-file)
12941315
(util/mkdirs out-file)
12951316
(if (:module-type js)
1296-
(spit out-file (convert-js-module js))
1317+
(spit out-file (convert-js-module js opts))
12971318
(spit out-file (deps/-source js))))
12981319
(if (map? js)
12991320
(merge js ijs)
@@ -1547,21 +1568,20 @@
15471568
options where new modules are passed with :libs option."
15481569
[opts]
15491570
(let [js-modules (filter :module-type (:foreign-libs opts))]
1550-
(reduce (fn [opts {:keys [file module-type] :as lib}]
1571+
(reduce (fn [new-opts {:keys [file module-type] :as lib}]
15511572
(if (or (and (= module-type :commonjs) can-convert-commonjs?)
15521573
(and (= module-type :amd) can-convert-amd?)
15531574
(and (= module-type :es6) can-convert-es6?))
1554-
(let [module-name (-> (ProcessCommonJSModules/toModuleName file)
1555-
(string/replace "_" "-"))
1556-
ijs (write-javascript opts (deps/load-foreign-library lib))]
1575+
(let [ijs (write-javascript opts (deps/load-foreign-library lib))
1576+
module-name (-> (deps/load-library (:out-file ijs)) first :provides first)]
15571577
(doseq [provide (:provides ijs)]
15581578
(swap! env/*compiler*
15591579
#(update-in % [:js-module-index] assoc provide module-name)))
1560-
(-> opts
1580+
(-> new-opts
15611581
(update-in [:libs] (comp vec conj) (:out-file ijs))
15621582
(update-in [:foreign-libs]
15631583
(comp vec (fn [libs] (remove #(= (:file %) file) libs))))))
1564-
opts))
1584+
new-opts))
15651585
opts js-modules)))
15661586

15671587
(defn build

0 commit comments

Comments
 (0)