Skip to content

Commit 732034b

Browse files
Deraendnolen
authored andcommitted
CLJS-1762: Bump Closure Compiler
- ES6ModuleLoader has been replaced with ModuleLoader, it no longer needs to be passed to ProcessCommonJSModules etc. constructors - This version requires the version 20160822 and any checks needed to work with older versions have been removed - Closure-compiler jar name has been changed so lib/ and closure/ directories should be removed before running bootstrap - Added simple tests to check that CommonJS module processing is working - convert-js-module has been changed convert-js-modules and it now converts all the modules per module-type at one go - Measure process-js-modules time
1 parent 7e15b1f commit 732034b

File tree

7 files changed

+180
-152
lines changed

7 files changed

+180
-152
lines changed

pom.template.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<dependency>
3131
<groupId>com.google.javascript</groupId>
3232
<artifactId>closure-compiler-unshaded</artifactId>
33-
<version>v20160315</version>
33+
<version>v20160911</version>
3434
</dependency>
3535
<dependency>
3636
<groupId>org.clojure</groupId>

project.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
[org.clojure/test.check "0.9.0" :scope "test"]
1515
[com.cognitect/transit-clj "0.8.285"]
1616
[org.clojure/google-closure-library "0.0-20160609-f42b4a24"]
17-
[com.google.javascript/closure-compiler-unshaded "v20160315"]
17+
[com.google.javascript/closure-compiler-unshaded "v20160911"]
1818
[org.mozilla/rhino "1.7R5"]]
1919
:profiles {:1.6 {:dependencies [[org.clojure/clojure "1.6.0"]]}
2020
:uberjar {:aot :all :main clojure.main}}

script/bootstrap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
set -e
44

55
CLOJURE_RELEASE="1.9.0-alpha7"
6-
CLOSURE_RELEASE="20160315"
6+
CLOSURE_RELEASE="20160911"
77
DJSON_RELEASE="0.2.6"
88
TRANSIT_RELEASE="0.8.285"
99
GCLOSURE_LIB_RELEASE="0.0-20160609-f42b4a24"
@@ -98,7 +98,7 @@ echo "Cleaning up Rhino archive..."
9898
rm rhino$RHINO_RELEASE.zip
9999

100100
echo "Copying closure/compiler/compiler.jar to lib/compiler.jar"
101-
cp closure/compiler/compiler.jar lib
101+
cp closure/compiler/closure-compiler-v$CLOSURE_RELEASE.jar lib
102102

103103
echo "Fetching tools.reader $TREADER_RELEASE ..."
104104
curl --retry 3 -O -s https://repo1.maven.org/maven2/org/clojure/tools.reader/$TREADER_RELEASE/tools.reader-$TREADER_RELEASE.jar || { echo "Download failed."; exit 1; }

src/main/clojure/cljs/closure.clj

Lines changed: 91 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
Result JSError CheckLevel DiagnosticGroups
5858
CommandLineRunner AnonymousFunctionNamingPolicy
5959
JSModule JSModuleGraph SourceMap ProcessCommonJSModules
60-
ES6ModuleLoader AbstractCompiler TransformAMDToCJSModule
60+
AbstractCompiler TransformAMDToCJSModule
6161
ProcessEs6Modules CompilerInput]
6262
[com.google.javascript.rhino Node]
6363
[java.nio.file Path Paths Files StandardWatchEventKinds WatchKey
@@ -74,45 +74,6 @@
7474
(defn random-string [length]
7575
(apply str (take length (repeatedly random-char))))
7676

77-
(util/compile-if
78-
(.getConstructor ES6ModuleLoader
79-
(into-array java.lang.Class
80-
[java.util.List java.lang.Iterable]))
81-
(do (def is-new-es6-loader? true)
82-
(def default-module-root ES6ModuleLoader/DEFAULT_FILENAME_PREFIX))
83-
(def is-new-es6-loader? false))
84-
85-
(util/compile-if
86-
(.getConstructor ES6ModuleLoader
87-
(into-array java.lang.Class
88-
[AbstractCompiler java.lang.String]))
89-
(def is-old-es6-loader? true)
90-
(def is-old-es6-loader? false))
91-
92-
(util/compile-if
93-
(and (.getConstructor ProcessCommonJSModules
94-
(into-array java.lang.Class
95-
[com.google.javascript.jscomp.Compiler ES6ModuleLoader]))
96-
(or is-new-es6-loader? is-old-es6-loader?))
97-
(def can-convert-commonjs? true)
98-
(def can-convert-commonjs? false))
99-
100-
(util/compile-if
101-
(and can-convert-commonjs?
102-
(.getConstructor TransformAMDToCJSModule
103-
(into-array java.lang.Class
104-
[AbstractCompiler])))
105-
(def can-convert-amd? true)
106-
(def can-convert-amd? false))
107-
108-
(util/compile-if
109-
(and (.getConstructor ProcessEs6Modules
110-
(into-array java.lang.Class
111-
[com.google.javascript.jscomp.Compiler ES6ModuleLoader Boolean/TYPE]))
112-
(or is-new-es6-loader? is-old-es6-loader?))
113-
(def can-convert-es6? true)
114-
(def can-convert-es6? false))
115-
11677
;; Closure API
11778
;; ===========
11879

@@ -1514,45 +1475,17 @@
15141475

15151476
:else (str (random-string 5) ".js")))))
15161477

1517-
(defn get-js-module-root [js-file]
1518-
(let [path (.getParent (io/file js-file))]
1519-
(cond->> path
1520-
(.startsWith path File/separator) (str ".")
1521-
(not (.startsWith path (str "." File/separator))) (str "." File/separator)
1522-
(not (.endsWith path File/separator)) (#(str % File/separator)))))
1523-
1524-
(util/compile-if is-new-es6-loader?
1525-
(defn make-es6-loader [source-files]
1526-
(let [^List module-roots (list default-module-root)
1527-
^List compiler-inputs (map #(CompilerInput. %) source-files)]
1528-
(ES6ModuleLoader. module-roots compiler-inputs)))
1529-
(defn make-es6-loader [closure-compiler file]
1530-
(let [module-root (get-js-module-root file)]
1531-
(ES6ModuleLoader. closure-compiler module-root))))
1532-
1533-
(defn ^Node get-root-node [ijs closure-compiler]
1534-
(let [^CompilerInput input (->> (deps/-source ijs)
1535-
(js-source-file (:file ijs))
1536-
(CompilerInput.))]
1537-
(.getAstRoot input closure-compiler)))
1538-
1539-
(defn get-source-files [opts]
1540-
(->> (concat (:foreign-libs opts)
1541-
(:ups-foreign-libs opts))
1542-
(filter #(let [module-type (:module-type %)]
1543-
(or (= module-type :amd)
1544-
(= module-type :commonjs)
1545-
(= module-type :es6))))
1546-
(map (fn [lib]
1547-
(let [lib (deps/load-foreign-library lib)]
1548-
(js-source-file (:file lib) (deps/-source lib)))))))
1549-
1550-
(defmulti convert-js-module
1551-
"Takes a JavaScript module as an IJavaScript and rewrites it into a Google
1552-
Closure-compatible form. Returns an IJavaScript with the converted module
1478+
(defn get-source-files [js-modules]
1479+
(map (fn [lib]
1480+
(js-source-file (:file lib) (deps/-source lib)))
1481+
js-modules))
1482+
1483+
(defmulti convert-js-modules
1484+
"Takes a list JavaScript modules as an IJavaScript and rewrites them into a Google
1485+
Closure-compatible form. Returns list IJavaScript with the converted module
15531486
code set as source."
1554-
(fn [{module-type :module-type :as ijs} opts]
1555-
(if (and (= module-type :amd) can-convert-amd?)
1487+
(fn [module-type js-modules opts]
1488+
(if (= module-type :amd)
15561489
;; AMD modules are converted via CommonJS modules
15571490
:commonjs
15581491
module-type)))
@@ -1564,48 +1497,45 @@
15641497
:language-in :language-out])
15651498
(set-options (CompilerOptions.))))
15661499

1567-
(util/compile-if can-convert-commonjs?
1568-
(defmethod convert-js-module :commonjs [ijs opts]
1569-
(let [{:keys [file module-type]} ijs
1570-
^List externs '()
1571-
^List source-files (get-source-files opts)
1572-
^CompilerOptions options (make-convert-js-module-options opts)
1573-
closure-compiler (doto (make-closure-compiler)
1574-
(.init externs source-files options))
1575-
es6-loader (if is-new-es6-loader?
1576-
(make-es6-loader source-files)
1577-
(make-es6-loader closure-compiler file))
1578-
cjs (ProcessCommonJSModules. closure-compiler es6-loader)
1579-
^Node root (get-root-node ijs closure-compiler)]
1580-
(util/compile-if can-convert-amd?
1581-
(when (= module-type :amd)
1582-
(.process (TransformAMDToCJSModule. closure-compiler) nil root)))
1583-
(.process cjs nil root)
1584-
(report-failure (.getResult closure-compiler))
1585-
(assoc ijs :source (.toSource closure-compiler root)))))
1586-
1587-
(util/compile-if can-convert-es6?
1588-
(defmethod convert-js-module :es6 [ijs opts]
1589-
(let [{:keys [file]} ijs
1590-
^List externs '()
1591-
^List source-files (get-source-files opts)
1592-
^CompilerOptions options (doto (make-convert-js-module-options opts)
1593-
(.setLanguageIn CompilerOptions$LanguageMode/ECMASCRIPT6)
1594-
(.setLanguageOut CompilerOptions$LanguageMode/ECMASCRIPT5))
1595-
closure-compiler (doto (make-closure-compiler)
1596-
(.init externs source-files options))
1597-
es6-loader (if is-new-es6-loader?
1598-
(make-es6-loader source-files)
1599-
(make-es6-loader closure-compiler file))
1600-
cjs (ProcessEs6Modules. closure-compiler es6-loader true)
1601-
^Node root (get-root-node ijs closure-compiler)]
1602-
(.processFile cjs root)
1603-
(report-failure (.getResult closure-compiler))
1604-
(assoc ijs :source (.toSource closure-compiler root)))))
1605-
1606-
(defmethod convert-js-module :default [ijs opts]
1607-
(ana/warning :unsupported-js-module-type @env/*compiler* ijs)
1608-
ijs)
1500+
(defn get-js-root [closure-compiler]
1501+
(.getSecondChild (.getRoot closure-compiler)))
1502+
1503+
(defn get-closure-sources
1504+
"Gets map of source file name -> Node, for files in Closure Compiler js root."
1505+
[closure-compiler]
1506+
(let [source-nodes (.children (get-js-root closure-compiler))]
1507+
(into {} (map (juxt #(.getSourceFileName ^Node %) identity) source-nodes))))
1508+
1509+
(defn add-converted-source [closure-compiler result-nodes {:keys [file] :as ijs}]
1510+
(assoc ijs :source (.toSource closure-compiler ^Node (get result-nodes file))))
1511+
1512+
(defmethod convert-js-modules :commonjs [module-type js-modules opts]
1513+
(let [^List externs '()
1514+
^List source-files (get-source-files js-modules)
1515+
^CompilerOptions options (doto (make-convert-js-module-options opts)
1516+
(.setProcessCommonJSModules true)
1517+
(.setTransformAMDToCJSModules (= module-type :amd)))
1518+
closure-compiler (doto (make-closure-compiler)
1519+
(.init externs source-files options))]
1520+
(.parse closure-compiler)
1521+
(report-failure (.getResult closure-compiler))
1522+
(map (partial add-converted-source closure-compiler (get-closure-sources closure-compiler)) js-modules)))
1523+
1524+
(defmethod convert-js-modules :es6 [module-type js-modules opts]
1525+
(let [^List externs '()
1526+
^List source-files (get-source-files js-modules)
1527+
^CompilerOptions options (doto (make-convert-js-module-options opts)
1528+
(.setLanguageIn CompilerOptions$LanguageMode/ECMASCRIPT6)
1529+
(.setLanguageOut CompilerOptions$LanguageMode/ECMASCRIPT5))
1530+
closure-compiler (doto (make-closure-compiler)
1531+
(.init externs source-files options))]
1532+
(.parse closure-compiler)
1533+
(report-failure (.getResult closure-compiler))
1534+
(map (partial add-converted-source closure-compiler (get-closure-sources closure-compiler)) js-modules)))
1535+
1536+
(defmethod convert-js-modules :default [module-type js-modules opts]
1537+
(ana/warning :unsupported-js-module-type @env/*compiler* (first js-modules))
1538+
js-modules)
16091539

16101540
(defmulti js-transforms
16111541
"Takes an IJavaScript with the source code set as source, transforms the
@@ -1636,12 +1566,7 @@
16361566
(when (and res (or ana/*verbose* (:verbose opts)))
16371567
(util/debug-prn "Copying" (str res) "to" (str out-file)))
16381568
(util/mkdirs out-file)
1639-
(spit out-file
1640-
(cond-> js
1641-
(map? js) (assoc :source (deps/-source js))
1642-
(:preprocess js) (js-transforms opts)
1643-
(:module-type js) (convert-js-module opts)
1644-
true deps/-source))
1569+
(spit out-file (deps/-source js))
16451570
(when res
16461571
(.setLastModified ^File out-file (util/last-modified res))))
16471572
(if (map? js)
@@ -1908,34 +1833,52 @@
19081833
(not (false? (:static-fns opts))) (assoc :static-fns true)
19091834
(not (false? (:optimize-constants opts))) (assoc :optimize-constants true)))))
19101835

1911-
(defn- process-js-modules*
1912-
[opts k]
1913-
(let [js-modules (filter :module-type (k opts))]
1914-
(reduce (fn [new-opts {:keys [file module-type] :as lib}]
1915-
(if (or (and (= module-type :commonjs) can-convert-commonjs?)
1916-
(and (= module-type :amd) can-convert-amd?)
1917-
(and (= module-type :es6) can-convert-es6?))
1918-
(let [ijs (write-javascript opts (deps/load-foreign-library lib))
1919-
module-name (-> (deps/load-library (:out-file ijs)) first :provides first)]
1920-
(doseq [provide (:provides ijs)]
1921-
(swap! env/*compiler*
1922-
#(update-in % [:js-module-index] assoc provide module-name)))
1923-
(-> new-opts
1924-
(update-in [:libs] (comp vec conj) (:out-file ijs))
1925-
(update-in [k]
1926-
(comp vec (fn [libs] (remove #(= (:file %) file) libs))))))
1927-
new-opts))
1928-
opts js-modules)))
1929-
19301836
(defn process-js-modules
19311837
"Given the current compiler options, converts JavaScript modules to Google
19321838
Closure modules and writes them to disk. Adds mapping from original module
19331839
namespace to new module namespace to compiler env. Returns modified compiler
19341840
options where new modules are passed with :libs option."
19351841
[opts]
1936-
(-> opts
1937-
(process-js-modules* :foreign-libs)
1938-
(process-js-modules* :ups-foreign-libs)))
1842+
(let [;; Modules from both :foreign-libs (compiler options) and :ups-foreign-libs (deps.cljs)
1843+
;; are processed together, so that files from both sources can depend on each other.
1844+
;; e.g. commonjs module in :foreign-libs can depend on commonjs module from :ups-foreign-libs.
1845+
js-modules (filter :module-type (concat (:foreign-libs opts) (:ups-foreign-libs opts)))]
1846+
(if (seq js-modules)
1847+
(util/measure
1848+
"Process JS modules"
1849+
(let [;; Load all modules - add :source so preprocessing and conversion can access it
1850+
js-modules (map (fn [lib]
1851+
(let [js (deps/load-foreign-library lib)]
1852+
(assoc js :source (deps/-source js))))
1853+
js-modules)
1854+
js-modules (map (fn [js]
1855+
(if (:preprocess js)
1856+
(js-transforms js opts)
1857+
js))
1858+
js-modules)
1859+
;; Conversion is done per module-type, because Compiler needs to process e.g. all CommonJS
1860+
;; modules on one go, so it can handle the dependencies between modules.
1861+
;; Amdjs modules are converted separate from CommonJS modules so they can't
1862+
;; depend on each other.
1863+
modules-per-type (group-by :module-type js-modules)
1864+
js-modules (mapcat (fn [[module-type js-modules]]
1865+
(convert-js-modules module-type js-modules opts))
1866+
modules-per-type)]
1867+
1868+
;; Write modules to disk, update compiler state and build new options
1869+
(reduce (fn [new-opts {:keys [file] :as ijs}]
1870+
(let [ijs (write-javascript opts ijs)
1871+
module-name (-> (deps/load-library (:out-file ijs)) first :provides first)]
1872+
(doseq [provide (:provides ijs)]
1873+
(swap! env/*compiler*
1874+
#(update-in % [:js-module-index] assoc provide module-name)))
1875+
(-> new-opts
1876+
(update-in [:libs] (comp vec conj) (:out-file ijs))
1877+
;; js-module might be defined in either, so update both
1878+
(update-in [:foreign-libs] (comp vec (fn [libs] (remove #(= (:file %) file) libs))))
1879+
(update-in [:ups-foreign-libs] (comp vec (fn [libs] (remove #(= (:file %) file) libs)))))))
1880+
opts js-modules)))
1881+
opts)))
19391882

19401883
(defn build
19411884
"Given a source which can be compiled, produce runnable JavaScript."

src/test/cljs/Circle.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
var React = require('./react');
2+
3+
var Circle = React.createClass({
4+
render: function() {
5+
return(
6+
<svg width="200px" height="200px" className="center">
7+
<circle cx="100px" cy="100px" r="100px" fill={this.props.color}>
8+
</circle>
9+
</svg>
10+
);
11+
}
12+
});
13+
14+
module.exports = Circle;

src/test/cljs/react.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
(function(f){
2+
if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}
3+
else if(typeof define==="function"&&define.amd){define([],f)}
4+
else{var g;if(typeof window!=="undefined"){g=window}
5+
else if(typeof global!=="undefined"){g=global}
6+
else if(typeof self!=="undefined"){g=self}
7+
else{g=this}g.React = f()}
8+
})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
9+
'use strict';
10+
11+
var React = {
12+
createElement: function() {}
13+
};
14+
15+
module.exports = React;
16+
17+
},{}]},{},[1])(1)
18+
});

0 commit comments

Comments
 (0)