|
7 | 7 | ; You must not remove this notice, or any other, from this software. |
8 | 8 |
|
9 | 9 | (ns cljs.closure |
10 | | - "Compile ClojureScript to JavaScript with optimizations from Google |
11 | | - Closure Compiler producing runnable JavaScript. |
12 | | -
|
13 | | - The Closure Compiler (compiler.jar) must be on the classpath. |
14 | | -
|
15 | | - Use the 'build' function for end-to-end compilation. |
16 | | -
|
17 | | - build = find-sources -> add-dependencies -> compile -> optimize -> output |
18 | | -
|
19 | | - Two protocols are defined: IJavaScript and Compilable. The |
20 | | - Compilable protocol is satisfied by something which can return one |
21 | | - or more IJavaScripts. |
22 | | -
|
23 | | - With IJavaScript objects in hand, calling add-dependencies will |
24 | | - produce a sequence of IJavaScript objects which includes all |
25 | | - required dependencies from the Closure library and ClojureScript, |
26 | | - in dependency order. This function replaces the closurebuilder |
27 | | - tool. |
28 | | -
|
29 | | - The optimize function converts one or more IJavaScripts into a |
30 | | - single string of JavaScript source code using the Closure Compiler |
31 | | - API. |
32 | | -
|
33 | | - The produced output is either a single string of optimized |
34 | | - JavaScript or a deps file for use during development. |
35 | | - " |
36 | 10 | (:refer-clojure :exclude [compile]) |
37 | 11 | (:require [cljs.util :as util :refer [distinct-by]] |
38 | 12 | [cljs.core :as cljsm] |
|
546 | 520 | [compilable opts] |
547 | 521 | (-compile compilable opts)) |
548 | 522 |
|
| 523 | +(defn find-sources |
| 524 | + "Given a Compilable, find sources and return a sequence of IJavaScript." |
| 525 | + [compilable opts] |
| 526 | + (-find-sources compilable opts)) |
| 527 | + |
549 | 528 | (defn compile-file |
550 | 529 | "Compile a single cljs file. If no output-file is specified, returns |
551 | 530 | a string of compiled JavaScript. With an output-file option, the |
|
724 | 703 | (js-dependencies {:libs ["closure/library/third_party/closure"]} ["goog.dom.query"]) |
725 | 704 | ) |
726 | 705 |
|
727 | | -(defn- add-core-macros-if-cljs-js |
| 706 | +(defn add-core-macros-if-cljs-js |
728 | 707 | "If a compiled entity is the cljs.js namespace, explicitly |
729 | 708 | add the cljs.core macros namespace dependency to it." |
730 | 709 | [compiled] |
|
856 | 835 | (let [url (deps/to-url (constants-filename opts))] |
857 | 836 | (javascript-file nil url [(str ana/constants-ns-sym)] ["cljs.core"]))) |
858 | 837 |
|
859 | | -;; Internally only REPLs use this. We do expose it in cljs.build.api - David |
860 | | - |
861 | 838 | (defn add-dependencies |
862 | | - "Given one or more IJavaScript objects in dependency order, produce |
| 839 | + "DEPRECATED: Given one or more IJavaScript objects in dependency order, produce |
863 | 840 | a new sequence of IJavaScript objects which includes the input list |
864 | 841 | plus all dependencies in dependency order." |
865 | 842 | [opts & inputs] |
|
1065 | 1042 | (str "#!" (or hashbang "/usr/bin/env node") "\n")) |
1066 | 1043 | (when preamble (preamble-from-paths preamble)))) |
1067 | 1044 |
|
1068 | | -(comment |
1069 | | - ;; add dependencies to literal js |
1070 | | - (add-dependencies {} "goog.provide('test.app');\ngoog.require('cljs.core');") |
1071 | | - (add-dependencies {} "goog.provide('test.app');\ngoog.require('goog.array');") |
1072 | | - (add-dependencies {} (str "goog.provide('test.app');\n" |
1073 | | - "goog.require('goog.array');\n" |
1074 | | - "goog.require('clojure.set');")) |
1075 | | - ;; add dependencies with external lib |
1076 | | - (add-dependencies {:libs ["closure/library/third_party/closure"]} |
1077 | | - (str "goog.provide('test.app');\n" |
1078 | | - "goog.require('goog.array');\n" |
1079 | | - "goog.require('goog.dom.query');")) |
1080 | | - ;; add dependencies with foreign lib |
1081 | | - (add-dependencies {:foreign-libs [{:file "samples/hello/src/hello/core.cljs" |
1082 | | - :provides ["example.lib"]}]} |
1083 | | - (str "goog.provide('test.app');\n" |
1084 | | - "goog.require('example.lib');\n")) |
1085 | | - ;; add dependencies to a JavaScriptFile record |
1086 | | - (add-dependencies {} (javascript-file false |
1087 | | - (deps/to-url "samples/hello/src/hello/core.cljs") |
1088 | | - ["hello.core"] |
1089 | | - ["goog.array"])) |
1090 | | - ) |
1091 | | - |
1092 | 1045 | ;; Optimize |
1093 | 1046 | ;; ======== |
1094 | 1047 |
|
|
1438 | 1391 |
|
1439 | 1392 | ;; optimize a ClojureScript form |
1440 | 1393 | (optimize {:optimizations :simple} (-compile '(def x 3) {})) |
1441 | | - |
1442 | | - ;; optimize a project |
1443 | | - (println (->> (-compile "samples/hello/src" {}) |
1444 | | - (apply add-dependencies {}) |
1445 | | - (apply optimize {:optimizations :simple :pretty-print true}))) |
1446 | 1394 | ) |
1447 | 1395 |
|
1448 | 1396 | ;; Output |
|
1972 | 1920 |
|
1973 | 1921 | :else (output-deps-file opts disk-sources)))) |
1974 | 1922 |
|
1975 | | -(comment |
1976 | | - |
1977 | | - ;; output unoptimized alone |
1978 | | - (output-unoptimized {} "goog.provide('test');\ngoog.require('cljs.core');\nalert('hello');\n") |
1979 | | - ;; output unoptimized with all dependencies |
1980 | | - (apply output-unoptimized {} |
1981 | | - (add-dependencies {} |
1982 | | - "goog.provide('test');\ngoog.require('cljs.core');\nalert('hello');\n")) |
1983 | | - ;; output unoptimized with external library |
1984 | | - (apply output-unoptimized {} |
1985 | | - (add-dependencies {:libs ["closure/library/third_party/closure"]} |
1986 | | - "goog.provide('test');\ngoog.require('cljs.core');\ngoog.require('goog.dom.query');\n")) |
1987 | | - ;; output unoptimized and write deps file to 'out/test.js' |
1988 | | - (output-unoptimized {:output-to "out/test.js"} |
1989 | | - "goog.provide('test');\ngoog.require('cljs.core');\nalert('hello');\n") |
1990 | | - ) |
1991 | | - |
1992 | | - |
1993 | 1923 | (defn get-upstream-deps* |
1994 | 1924 | "returns a merged map containing all upstream dependencies defined |
1995 | 1925 | by libraries on the classpath." |
|
2706 | 2636 | (:foreign-libs opts))) |
2707 | 2637 | (process-js-modules opts) |
2708 | 2638 | (:options @compiler-env))] |
2709 | | - (swap! compiler-env (fn [cenv] |
2710 | | - (-> cenv |
2711 | | - ;; we need to also track the whole top level - this is to support |
2712 | | - ;; cljs.analyze/analyze-deps, particularly in REPL contexts - David |
2713 | | - (merge {:js-dependency-index (deps/js-dependency-index opts)}) |
2714 | | - (update-in [:node-module-index] (fnil into #{}) |
2715 | | - (if (= target :nodejs) |
2716 | | - (map str node-required) |
2717 | | - (map str (keys top-level))))))) |
| 2639 | + (swap! compiler-env |
| 2640 | + (fn [cenv] |
| 2641 | + (-> cenv |
| 2642 | + ;; we need to also track the whole top level - this is to support |
| 2643 | + ;; cljs.analyze/analyze-deps, particularly in REPL contexts - David |
| 2644 | + (merge {:js-dependency-index (deps/js-dependency-index opts)}) |
| 2645 | + (update-in [:options] merge opts) |
| 2646 | + (update-in [:node-module-index] (fnil into #{}) |
| 2647 | + (if (= target :nodejs) |
| 2648 | + (map str node-required) |
| 2649 | + (map str (keys top-level))))))) |
2718 | 2650 | opts)) |
2719 | 2651 |
|
2720 | 2652 | (defn output-bootstrap [{:keys [target] :as opts}] |
|
2726 | 2658 | (util/mkdirs outfile) |
2727 | 2659 | (spit outfile (slurp (io/resource (str "cljs/bootstrap_" target-str ".js"))))))) |
2728 | 2660 |
|
| 2661 | +(defn compile-inputs |
| 2662 | + "Compile inputs and all of their transitive dependencies including JS modules, |
| 2663 | + libs, and foreign libs. Duplicates the pipeline of build." |
| 2664 | + [inputs opts] |
| 2665 | + (env/ensure |
| 2666 | + (let [sources (-> inputs (add-dependency-sources opts)) |
| 2667 | + opts (handle-js-modules opts sources env/*compiler*) |
| 2668 | + sources (-> (remove (comp #{:seed} :type) sources) |
| 2669 | + deps/dependency-order |
| 2670 | + (compile-sources false opts) |
| 2671 | + (#(map add-core-macros-if-cljs-js %)) |
| 2672 | + (add-js-sources opts) deps/dependency-order |
| 2673 | + (->> (map #(source-on-disk opts %)) doall))] |
| 2674 | + sources))) |
| 2675 | + |
| 2676 | +(defn compile-ns |
| 2677 | + "Compiles a namespace and all of its transitive dependencies. |
| 2678 | + See compile-inputs." |
| 2679 | + [ns opts] |
| 2680 | + (compile-inputs (find-sources ns opts) opts)) |
| 2681 | + |
2729 | 2682 | (defn build |
2730 | 2683 | "Given a source which can be compiled, produce runnable JavaScript." |
2731 | 2684 | ([source opts] |
|
2818 | 2771 | (-> (-find-sources source opts) |
2819 | 2772 | (add-dependency-sources compile-opts))) |
2820 | 2773 | opts (handle-js-modules opts js-sources compiler-env) |
2821 | | - _ (swap! env/*compiler* update-in [:options] merge opts) |
2822 | 2774 | js-sources (-> js-sources |
2823 | 2775 | deps/dependency-order |
2824 | 2776 | (compile-sources compiler-stats compile-opts) |
|
0 commit comments