Multiple ClojureScript files on same page

て烟熏妆下的殇ゞ 提交于 2019-12-23 12:18:13

问题


I have a project that is using Jasmine to test the JavaScript. I am trying to switch to using ClojureScript for the front end. My project.clj is like

(defproject myproject "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [org.clojure/clojurescript"0.0-1889"]
                 [org.clojure/google-closure-library-third-party "0.0-2029"]
                 [domina "1.0.0"]
                 [hiccups "0.2.0"]]
  :plugins [[lein-cljsbuild "0.3.3"]]
  :cljsbuild {
              :builds [{
                        :source-paths ["src/clojurescript"]
                        :compiler {
                                   :output-to "public/javascripts/main.js"
                                   :optimizations :whitespace
                                   :pretty-print true}}
                       {
                        :source-paths ["spec/clojurescript"]
                        :compiler {
                                   :output-to "spec/javascripts/mainSpec.js"
                                   :optimizations :whitespace
                                   :pretty-print true}}]})

So all the .cljs files in src/clojurescript get compiled to main.js and all the .cljs in spec/clojurescript get compiled to mainSpec.js. When I load the Jasmine page, both the .js files are loaded but the tests aren't run. In the console I get an Error: Namespace "goog.debug.Error" already declared. Both the .js files have the same ~30k lines of google closure code at the top which is causing the error. If I delete this code from mainSpec.js it runs fine. Is there any way to tell cljsbuild to leave this code off the spec file?


回答1:


As Jared314 and Zubair pointed out, the problem you're encountering is caused by trying to include two clojurescript compilation outputs in the same page. Clojurescript/Google Closure expect to do a 'whole-world' compile, that is, the compiler expects that all of the code for the entire page is passed to the compiler so that it can optimise it, rename functions, and ultimately spit out a single javascript file. It's not designed to produce multiple output files that work together.

The 'correct' way to solve your problem is to produce two outputs that are used in isolation: a main.js file for running your application, and a spec.js file that include all the code in main plus the code in spec for testing. You can do this by setting up your project something like this:

:cljsbuild {
          :builds [{
                    :source-paths ["src/clojurescript"]
                    :compiler {:output-to "public/javascripts/main.js"}}
                   {
                    :source-paths ["src/clojurescript" "spec/clojurescript"]
                    :compiler {:output-to "spec/javascripts/spec.js"}}]})

Your jasmine page should refer to spec.js but not main.js - referring to both is the cause of your error.




回答2:


The issue is both builds are compiled with the Google Closure library included, hence the "already declared" error. You can try using :optimizations :advanced, in the :compiler options, to reduce, or eliminate, the duplicate code.

But, if you still run into the same issue, you might want to compile the src and spec together for the mainSpec.js build.



来源:https://stackoverflow.com/questions/18987333/multiple-clojurescript-files-on-same-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!