ClojureScript update from 1.10.439 to 1.11.60

We recently upgraded our ClojureScript version from 1.10.439 to 1.11.60. This is a rather big jump. 1.10.439 was released on Nov 2, 2018, while 1.11.60 was released on Jun 23, 2022. That's almost three and a half years! Although the update went well, there were few things that needed special attention.

Long.fromString instead of Long/fromString

The way how we called the fromString function from goog.math.Long stopped working. We got a compilation error saying that fromString didn't exist.

Here's how we used to require and call the function:

(ns "my.namespace"
  (:require [goog.math.Long]))

(goog.math.Long/fromString "123")

After CLJS upgrade, the compiler threw an error saying that fromString doesn't exist.

We changed the code to this:

(ns "my.namespace"
  (:import [goog.math Long]))

(goog.math.Long.fromString "123")

import + dot works well, and it seems to be also the recommended way, according to the import function examples in the documentation.

language-in: es-next

New Google Closure Library seems to contains JavaScript code that utilizes "Optional catch binding". What this means is that usually, when you catch an error in JavaScript, you bind the error to a variable, like this:

try {
  // something
} catch (error) {
  // the exception is bound to 'error'
}

In the newer JavaScript version (ES10) it's optional to bind the exception to a variable. The following works just fine:

try {
  // something
} catch {
  // no binding
}

Google Closure Library contains JavaScript code that utilizes optional catch binding. Because of that, we got an error "ERROR - [JSC_LANGUAGE_FEATURE] This language feature is only supported for ECMASCRIPT_2019 mode or better: Optional catch binding. ".

The solution is to change the :language-in compiler option to :ecmascript-next. And AFAIK, there's no need to change the :language-out parameter.

The issue has also been discussed in Ask Clojure forum.

Upgrade devtools

The compiler showed a warning about devtoolsusing an undeclared var. This seems to be a bug in ClojureScript.

The warning went away by upgrading devtools to 1.0.6

Change the order in which JS files are required

Okay, now that we fixed all the errors and warnings we saw in development mode, it was time to compile the JS bundle with advanced compilation. This revealed couple more issues.

We use CodeMirror from CLJSJS with XML and Handlebars modes. Apparently, something has changed in the order in which the modules are required.

What we earlier had was this:

(ns code-editor-namespace
  (:require
   [codemirror :as codemirror]
   [cljsjs.codemirror.mode.xml]
   [cljsjs.codemirror.mode.handlebars]
   [cljsjs.codemirror.addon.mode.simple]
   [cljsjs.codemirror.addon.mode.multiplex]

However, this didn't work anymore. The reason was that Handlebars mode requires simple mode, thus, I needed to change the order in which they are required:

(ns code-editor-namespace
  (:require
   [codemirror :as codemirror]

   ;; Load addons first before language modes
   [cljsjs.codemirror.addon.mode.simple]
   [cljsjs.codemirror.addon.mode.multiplex]

   [cljsjs.codemirror.mode.xml]
   [cljsjs.codemirror.mode.handlebars]

The change makes sense. However, what I don't know is why this was working earlier. My guess is that because this appeared in advanced compilation, maybe something has changed in Google Closure Compiler.

goog.object needs to be required before use

Next issue with advanced compilation: goog.object needs to be required in the namespace that uses it. This wasn't the case with the earlier version, but was changed in the ClojureScript 1.10.891 release.

Fix was easy, I just added the requires in the namespaces that didn't have those.

Conclusion

Although a few things needed special attention, I'm suprised that there weren't more of those. As mentioned, the version from which I updated was released more than three and a half years ago!

ClojureScript is heavily using Google Closure Compiler and Google Closure Library. I didn't go through all the changelogs, but my assumption is that many of there "breaking changes" were actually something that were changes in Google Closure instead of changes in ClojureScript itself.