04 November 2021
ClojureScript Team
We’re happy to announce a new release of ClojureScript. If you’re an existing user of ClojureScript please read over the following release notes carefully.
Closure Compiler has been updated to v20210808
Google Closure has been updated to 0.0-20211011-0726fdeb
You should no longer assume that Google Closure Library namespaces can be reached globally because some dependency may have already loaded it. For proper usage of Google Closure Library namespaces, an explicit require is always necessary.
Some ClojureScript libraries assume that because cljs.core
loaded goog.object
,
it would be safe to refer to such definitions directly, i.e. goog.object/get
without the necessary
require. This pattern can be useful in the writing of macros so that users can
elide a require. However, this is now an anti-pattern and will
fail.
Google has slowly been converting various namespaces to the goog.module
format which does not export globally as goog.provide
does. In order to future
proof - ClojureScript now always loads goog.module
in accordance with
Closure’s guidelines as Closure Library may decide to convert any namespace into
a goog.module
at any time and simply drop support for global definition for that
namespace.
To ease the transition for the most common cases, ClojureScript has a new
compiler flag to restore the old behavior - :global-goog-object&array
.
Note the above guidance does not apply to ClojureScript libraries. To understand why, we briefly answer some related questions.
goog.module
?No. Clojure style REPL driven development is best supported by the original Google Closure namespace conventions. By representing namespaces as nested JavaScript objects, we effectively get late bound environments that are semantically close to Clojure’s vars which permit highly interactive development workflows.
Like ES modules, the goog.module
format is simply incompatible with REPL driven
development. In both cases the module is effectively a function closure, precise
redefinition is simply not a part of the design. The complexities and tradeoffs for interactive
development are readily apparent when comparing typical JavaScript "hot-reloading"
workflows and the development experience available to Clojure developers.
goog.provide
?Fortunately Google Closure Compiler is very mature. Unlike currently popular JavaScript
tools it does not need exports to understand what to tree-shake. Closure Compiler
works on objects and their properties. Even if Closure Compiler removed goog.provide
,
we could simply provide our own analogous constructs and Closure Compiler would
still be able to provide all the usual advanced optimizations.
For a complete list of updates in ClojureScript 1.10.891 see Changes.