Skip to content

Namespace pollution

Juho Teperi edited this page Aug 4, 2017 · 7 revisions

By default, the Google Closure compiler and, by extension, the ClojureScript compiler assume that they control the global Javascript namespace. When using external JavaScript libraries in conjunction with :optimizations simple or :optimizations :advanced, this can cause problems, as the short names the compiler chooses for JavaScript functions often collide with those used in JavaScript libraries.

For example, with advanced optimizations, Closure picks two-letter combinations like window.fb and window.dt, clobbering functions defined in popular frameworks. This results in hard-to-trace JavaScript errors. What's more, these problems can appear seemingly out of the blue as the result of unrelated changes which accidentally affect Closure's naming scheme.

Not that this is not problem when all code in the project is processed by the Closure compiler. However, external libraries, including many libraries provided by Cljsjs, suffer from this issue, whether included as an external <script> tag or using the foreign-libs parameter.

Solution

:output-wrapper is enabled default for optimized builds since version 2.1.

When working with boot-cljs, the solution is to set the :output-wrapper compiler option to true. For example, your main.edn may look like this:

{:require  [app.core]
 :init-fns [app.core/main]
 :compiler-options {:optimizations :advanced
                    :output-wrapper true}}

See the Google Closure FAQ item and the ClojureScript wiki for more details.

Note that currently :output-wrapper true cannot be used with :optimizations :whitespace (ticket).

Clone this wiki locally