|
57 | 57 | Result JSError CheckLevel DiagnosticGroups
|
58 | 58 | CommandLineRunner AnonymousFunctionNamingPolicy
|
59 | 59 | JSModule JSModuleGraph SourceMap ProcessCommonJSModules
|
60 |
| - ES6ModuleLoader AbstractCompiler TransformAMDToCJSModule |
| 60 | + AbstractCompiler TransformAMDToCJSModule |
61 | 61 | ProcessEs6Modules CompilerInput]
|
62 | 62 | [com.google.javascript.rhino Node]
|
63 | 63 | [java.nio.file Path Paths Files StandardWatchEventKinds WatchKey
|
|
74 | 74 | (defn random-string [length]
|
75 | 75 | (apply str (take length (repeatedly random-char))))
|
76 | 76 |
|
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 |
| - |
116 | 77 | ;; Closure API
|
117 | 78 | ;; ===========
|
118 | 79 |
|
|
1514 | 1475 |
|
1515 | 1476 | :else (str (random-string 5) ".js")))))
|
1516 | 1477 |
|
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 |
1553 | 1486 | 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) |
1556 | 1489 | ;; AMD modules are converted via CommonJS modules
|
1557 | 1490 | :commonjs
|
1558 | 1491 | module-type)))
|
|
1564 | 1497 | :language-in :language-out])
|
1565 | 1498 | (set-options (CompilerOptions.))))
|
1566 | 1499 |
|
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) |
1609 | 1539 |
|
1610 | 1540 | (defmulti js-transforms
|
1611 | 1541 | "Takes an IJavaScript with the source code set as source, transforms the
|
|
1636 | 1566 | (when (and res (or ana/*verbose* (:verbose opts)))
|
1637 | 1567 | (util/debug-prn "Copying" (str res) "to" (str out-file)))
|
1638 | 1568 | (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)) |
1645 | 1570 | (when res
|
1646 | 1571 | (.setLastModified ^File out-file (util/last-modified res))))
|
1647 | 1572 | (if (map? js)
|
|
1908 | 1833 | (not (false? (:static-fns opts))) (assoc :static-fns true)
|
1909 | 1834 | (not (false? (:optimize-constants opts))) (assoc :optimize-constants true)))))
|
1910 | 1835 |
|
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 |
| - |
1930 | 1836 | (defn process-js-modules
|
1931 | 1837 | "Given the current compiler options, converts JavaScript modules to Google
|
1932 | 1838 | Closure modules and writes them to disk. Adds mapping from original module
|
1933 | 1839 | namespace to new module namespace to compiler env. Returns modified compiler
|
1934 | 1840 | options where new modules are passed with :libs option."
|
1935 | 1841 | [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))) |
1939 | 1882 |
|
1940 | 1883 | (defn build
|
1941 | 1884 | "Given a source which can be compiled, produce runnable JavaScript."
|
|
0 commit comments