All of this is actually not recommended and red flags per documentation. Moreover it says that:
Multiple files that have the same export namespace Foo { at top-level (don’t think that these are going to combine into one Foo!)
That being said, I also had to preserve namespaced construct when migrating to ES6 modules because some systems don't offer a simple way to suddenly change namespace references like find & replace (MS Power Apps for example) or maybe you are really developing a library and want to preserve the entry point foo
If you had different first part of namespace per file, this would be enought:
(window as any).foo = foo
But having multiple, each file would overwrite previous window.foo
But there are ways what you can do when migrating to modules. With some webpack configuration, namespaces CAN be exposed as a public variables.
/*
Merge foonamespace between multiple files and expose it as a global variable. Otherwise foo namespace stays as module scoped variable.
exports global variable foo (because library.name is foo), and it uses a construct that:
- Copy the return value to a target object if it exists, otherwise create the target object first: Basically copies foo.* to foo object. This turns out to be a merge of namespaces.
- Namespace MUST BE exported.
- export: 'foo' means that instead of having global variable foo.foo.blah I have foo.blah (basically this should be the value whatever namespace starts with)
*/
output: {
...
library: {
name: 'foo', //or [name] if you have namespace same as entry point name
type: 'assign-properties' //or var or window if same namespace doesn't span multiple modules
export: 'foo'
},
}
There are many more ways to expose stuff to global scope (different type values available). Refer to webpack documentation
P.S. A module (having import or export statement) means variables get scoped as a module (rightly so) and that brings these challenges in the first place to preserve namespaced construct. Reference
Modules are executed within their own scope, not in the global scope; this means that variables, functions, classes, etc. declared in a module are not visible outside the module
P.S.2 How does webpack achieve it? The output looks something like:
var __webpack_export_target__ = (foo = typeof foo === "undefined" ? {} : foo);
var __webpack_exports_export__ = __webpack_exports__.foo;
for(var i in __webpack_exports_export__) __webpack_export_target__[i] = __webpack_exports_export__[i];
if(__webpack_exports_export__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
Implication is second level namespace must be unique.