Thanks Chad. Looking forward to playing with these changes!
Missing from your
wiki page are details on mixing goog.provide/module/require and es6/commonjs. My compilation comprises:
- Closure Library (goog.provide/require, including some files with multiple provide's)
- My legacy code:
goog.provide("my.ns.SomeLegacyScript");
goog.require("my.ns.SomeOtherLegacyScript"); // same as per Closure Library
goog.require("my.ns.SomeNewBridgeModuleWithLegacyNamespace"); // I definitely use this in a few places
const SomeNewModule = goog.require("my.ns.SomeNewModule"); // I think I might also use this in a couple of cases
my.ns.SomeOtherLegacyScript.someFunc();
my.ns.SomeNewBridgeModuleWithLegacyNamespace.someFunc();
SomeNewModule.someFunc();
- My new "bridge" code accessed from legacy code
goog.module("my.ns.SomeNewBridgeModuleWithLegacyNamespace");
goog.module.declareLegacyNamespace();
const array = goog.require("goog.Array");
const SomeOtherLegacyScript = goog.require("my.ns.SomeOtherLegacyScript");
const SomeNewModule = goog.require("my.ns.SomeNewModule");
array.find(...);
SomeOtherLegacyScript.someFunc();
SomeNewModule.someFunc();
- Entirely new modules which are only used by other modules
goog.module("my.ns.SomeNewModule");
const array = goog.require("goog.Array");
const SomeOtherLegacyScript = goog.require("my.ns.SomeOtherLegacyScript");
const SomeOtherNewModule = goog.require("my.ns.SomeOtherNewModule ");
const YetAnotherNewModule = goog.module.get("my.ns.YetAnotherNewModule"); // e.g. avoiding circular references
const React = require("React"); // in-browser runtime loading of React as a CommonJS module, from a separate JS script (I never got this to work with React, but do use it with EventEmitter2)
array.find(...);
SomeOtherLegacyScript.someFunc();
SomeOtherNewModule.someFunc();
YetAnotherNewModule.someFunc();
and I want to incrementally move towards either ES6 or CommonJS, perhaps ES6 in preference. Are any of these scenarios incompatible with ES6/CommonJS modules?
(If you like, perhaps I can update your Wiki page to have all from/to permutations for module type combinations with code examples a little like the above, and explanations where known for whether it is valid or not?)
As soon as I use "import" or "export" it does module rewriting - what is this, exactly? Does the compiler modify the AST on the fly prior to regular compilation passes, to turn ES6 and CommonJS modules into goog.module using $ converted absolute paths?
What does that mean if you are also using goog.module, goog.require and goog.module.get() in the same file? And can a legacy file goog.require that ES6/CommonJS module using my$ns$... notation?
Presumably module rewriting doesn't happen in whitespace-only mode because it isn't "lower from ES6". I have a PR open related to this (wrapping modules in whitespace mode) and presumably could do the same and enable module rewriting when using ES6 language out via a CompilerOptions property.
I know ES6 modules aren't a priority until browsers support them. But when they do, presumably you're not going to want to serve up every module as a separate HTTP request, so only-concatenated (whitespace only) development would still need module rewriting?
(We use whitespace mode extensively for rapid development. With our own Java wrapper classes which add "watch" and caching of filesystem data, a 30+ second advanced compilation takes <500ms in whitespace only + module wrapping mode, warm run).