From 17be1dc7b0dfeb2e6cd68968b7f0cc66400982e5 Mon Sep 17 00:00:00 2001 From: Juho Teperi Date: Wed, 26 Oct 2016 13:37:11 +0300 Subject: [PATCH] Parse require calls from JS files using Closure --- build.boot | 3 ++- src/cljsjs/closure.clj | 40 ++++++++++++++++++++++++++++++++++++++++ src/cljsjs/npm/build.clj | 1 + 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/cljsjs/closure.clj diff --git a/build.boot b/build.boot index b097cfb..21371a7 100644 --- a/build.boot +++ b/build.boot @@ -1,5 +1,6 @@ (set-env! - :dependencies '[[cheshire "5.6.3"]] + :dependencies '[[cheshire "5.6.3"] + [com.google.javascript/closure-compiler-unshaded "v20160911"]] :source-paths #{"src"}) (require '[cljsjs.npm.build :refer [package]]) diff --git a/src/cljsjs/closure.clj b/src/cljsjs/closure.clj new file mode 100644 index 0000000..3fe41b0 --- /dev/null +++ b/src/cljsjs/closure.clj @@ -0,0 +1,40 @@ +(ns cljsjs.closure + (:require [clojure.java.io :as io]) + (:import [com.google.javascript.jscomp CompilerPass NodeTraversal + CompilerOptions SourceFile NodeTraversal$Callback JSModule] + [com.google.javascript.rhino Node])) + +(defn is-require? [n] + (and (= 2 (.getChildCount n)) + (.. n getFirstChild (matchesQualifiedName "require")) + (.. n getSecondChild isString))) + +(defn is-npm-require? [module-name] + false) + +(defn finder [requires] + (reify NodeTraversal$Callback + (shouldTraverse ^boolean [this t n parent] + true) + (visit ^void [this t n parent] + (if (is-require? n) + (swap! requires conj (.. n getSecondChild getString))) + nil))) + +(defn process-pass [compiler requires] + (reify CompilerPass + (process [this _ root] + (NodeTraversal/traverseEs6 compiler root (finder requires))))) + +(defn find-requires [f] + (let [requires (atom []) + module (doto (JSModule. "$singleton$") + (.add (SourceFile/fromFile f))) + closure-compiler (com.google.javascript.jscomp.Compiler.) + pass (process-pass closure-compiler requires)] + (doseq [input (.getInputs module)] + (.process pass nil (.getAstRoot input closure-compiler))) + @requires)) + +(comment + (find-requires (io/file "node_modules/react/lib/React.js"))) diff --git a/src/cljsjs/npm/build.clj b/src/cljsjs/npm/build.clj index 5d80ad4..045d4d7 100644 --- a/src/cljsjs/npm/build.clj +++ b/src/cljsjs/npm/build.clj @@ -2,6 +2,7 @@ (:require [cheshire.core :as json] [clojure.java.io :as io] [clojure.string :as string] + [cljsjs.closure :as closure] [boot.util :as util] [boot.core :as boot] [boot.task.built-in :as built-in]))