I have a code base that uses the google-closure style modules goog.provide
and classes, etc.
I want to modernize this code base but it's roughly 15k lines of code and I was hoping a tool could help me.
These tools are broken, I tried many things to get them to work but they just wont. It's a lost cause. https://github.com/angular/clutz https://github.com/DreierF/closure-es6-converter
I think If I had a tool to update the closure classes and modules to the ES6 variants, I could do everything else by hand.
This tool works to update to a modern ES6 class syntax, but notably doesn't update the closure modules. https://github.com/lebab/lebab
Would this tool allow me to convert closure modules to es6 modules? Or does it only produce a minified output. https://webpack.js.org/plugins/closure-webpack-plugin/#usage-example
There are 2 documents you should read about this:
ES6 modules and Closure interop
and
Migrating from goog.modules to ES6 modules
Some highlights from each:
ES6 modules can use goog.require like goog.modules to reference Closure files:
const math = goog.require('goog.math'); export const MY_CONSTANT = math.sum(1, 1, 2, 3, 5, 8, 13, 21);
The Closure Library has the function
goog.declareModuleId(/** string */ id)
, which, when called in an ES6 module, associates the ES6 module with a goog.module-like id (e.g. something that can begoog.require'd
,goog.module.getd
,goog.forwardDeclared
, andgoog.requireTyped
, and does not create any global symbols). goog.requires for these symbols will return the entire module object, as if bound by import * as.goog.declareModuleId('example.es6'); export const MY_CONSTANT = 'Hello!';
And
Closure module default exports Closure modules can have a "default" export via exports = value;. When using this syntax the module's exports become the default export. This is frequently used with modules that export a single class.
goog.module('my.Class'); class Class {} // Default export. goog.require for this module returns this class. exports = Class;
What about migrating Closure modules that call declareLegacyNamespace? goog.module.declareLegacyNamespace is not supported in ES6 modules. It breaks a fundamental principle of modules: that modules do not create global values. Its purpose was to allow migration from goog.provide to Closure modules. We do not support it when moving to ES6 modules.
It is recommended you migrate all goog.provided files that are relying on the declareLegacyNamespace call to Closure or ES6 modules first, or at the very least have them call goog.module.get in a goog.scope to get references to modules. If this is not possible and migration of the Closure module is still desired, you'll need to follow similar steps to migrating a Closure module with default exports, except your *_shim.js file will call declareLegacyNamespace. You will only be able to delete this file once all the goog.provide files have migrated.