bhauman / lein-figwheel

Figwheel builds your ClojureScript code and hot loads it into the browser as you are coding!
Eclipse Public License 1.0
2.88k stars 209 forks source link

Using figwheel in environment with pre-existing/conflicting goog #592

Closed vivid-inc closed 7 years ago

vivid-inc commented 7 years ago

Seeing if the front-end UI of an Atlassian Confluence macro can be re-written in ClojureScript (success so far!), and now we are at the point where we are ready to integrate figwheel to speed development and jack up the fun-factor. (Thanks for making it, BTW :) )

Our current best-educated-guess as to how to structure the delivery of resources to the browser is thus. When the front-end UI is loaded and run, Confluence serves its various resources from port 2990, including the main JS file compiled from CLJS. Now, this file served by Confluence is actually soft-linked on the filesystem to cljs-build's / figwheel's :output-to file, and its content probably looks familiar:

var CLOSURE_UNCOMPILED_DEFINES = {}; if(typeof goog == "undefined") document.write('<script src="http://localhost:3449/js/compiled/out/goog/base.js"></script>'); document.write('<script src="http://localhost:3449/js/compiled/out/cljs_deps.js"></script>');

So Confluence publishes a JS script that in writes directives into the HTML document that in turn triggers the browser to load those resources from figwheel (Achieved with :asset-path "http://localhost:3449/js/compiled/out" .)

We are running into problems when loading the Confluence page and inserting our macro. A first problem is that goog seems to already be defined elsewhere by Confluence. Therefore the condition in the 2nd line won't cause good/base.js to be loaded. The already-defined goog appears to differ from the one that figwheel would like to load. Anyways, I can force some brand of forward progress by deleting the condition so that base.js is always loaded, and that leads us to a next set of problems, reported in the JS console:

Uncaught TypeError: goog.userAgent.isVersionOrHigher is not a function at browserfeature.js:55

Uncaught TypeError: goog.string.contains is not a function at Object.goog.labs.userAgent.util.matchUserAgent (util.js:93) at Object.goog.labs.userAgent.browser.matchFirefox_ (browser.js:72) at product.js:109

Uncaught Error: Namespace "goog.i18n.bidi" already declared. at Object.goog.provide (base.js:305) at bidi.js:23

Uncaught TypeError: goog.string.contains is not a function at Object.goog.labs.userAgent.util.matchUserAgent (util.js:93) (ELIDED) at file_reloading.cljs?rel=1502268219078:277

Uncaught TypeError: goog.string.contains is not a function (ELIDED) at dataset.js:45

Uncaught TypeError: goog.string.regExpEscape is not a function (ELIDED) at figwheel$client$fill_url_template (client.cljs?rel=1502268220988:407) at client.cljs?rel=1502268220988:454

Each of these errors seem to originate in sources files included near the bottom of cljs_deps.js, where the first dependency on figwheel occurs, namely:

goog.addDependency("../figwheel/client/utils.js", ['figwheel.client.utils'], ['goog.userAgent.product', 'goog.string', 'cljs.core', 'goog.string.StringBuffer', 'cljs.pprint', 'goog.async.Deferred', 'clojure.string', 'cljs.reader']);

Also, there is a smarter approach to integrate figwheel, we are all ears ^_^

bhauman commented 7 years ago

So there will be a problem if a different version of goog is already present on the page. If you have no control over that then I would just use lein cljsbuild and compile in a mode other than :optimizations :none. And also use :output-wrapper true. This is the simplest path for sure and quite possibly the only path.

You could try to match versions with the existing google Closure compiler, (by walking back through versions of ClojureScript/Figwheel until you find one that matches the one that already exists) but even if you match it it may not work at all.

A better solution would be to be able to alter the goog name for your current project. I really doubt that is possible right now. You may want to ask if that is possible in the Clojurians #clojurescript Slack channel.

vivid-inc commented 7 years ago

Thanks for responding. Well, with :optimizations set to something other than nil or set to :none, we will be unable to enjoy Figwheel. I'll act on all of your recommendations. Cheers!