You seem to believe that namespaces solve a problem that can only be solved using namespaces, but keep in mind that they originate from before ES6 modules were standardized.
Apart from having a more familiar name, theyâre in no way whatsoever better suited to solve the problem of namespacing than modules do.
Example:
Namespaces
things/foo.ts
namespace things {
export class Foo {}
}
things/bar.ts
/// <reference path="foo.ts" />
namespace things {
export class Bar {
constructor(foo: Foo) {}
}
}
things/baz.ts
/// <reference path="foo.ts" />
namespace things {
export class Baz {
constructor(foo: Foo) {}
}
}
app.ts
/// <reference path="things/foo.ts" />
/// <reference path="things/bar.ts" />
/// <reference path="things/baz.ts" />
export class App {
constructor(foo: things.Foo, bar: things.Bar, baz: things.Baz) {}
}
Modules
things/foo.ts
export class Foo {}
things/bar.ts
import { Foo } from './foo';
export class Bar {
constructor(foo: Foo) {}
}
things/baz.ts
import { Foo } from './foo';
export class Baz {
constructor(foo: Foo) {}
}
things/index.ts
export * from './foo';
export * from './bar';
export * from './baz';
app.ts
import * as things from './things/index';
export class App {
constructor(foo: things.Foo, bar: things.Bar, baz: things.Baz) {}
}
The above is just one of the many possible flavors of how you can do namespacing in modules. This example puts the responsibility of naming the namespace with the consumer and leaves you with the freedom to import things directly as well.
Alternatively, you can âforceâ your fellow team mates to stick to the namespace like so:
things/index.ts
import { Foo } from './foo';
import { Bar } from './bar';
import { Baz } from './baz';
export const things = { Foo, Bar, Baz };
app.ts
import { things } from './things/index';
export class App {
constructor(foo: things.Foo, bar: things.Bar, baz: things.Baz) {}
}
Or if you donât mind the extra boilerplate in order to keep the object a true module object:
things/index-exports.ts
export * from './foo';
export * from './bar';
export * from './baz';
things/index.ts
export * as things from './index-exports';
Conclusion
The module examples I gave you are just some of the many things you can do with modules. The good thing is theyâre native, and thus natively supported by any tool or framework.
Youâll get VS Code intellisense and auto import suggestions, auto update refactorings, and you get none of this with namespaces: youâll have to write those /// references yourself by hand and keep them up to date by hand.
And you donât have to wonder whether it will work with Aurelia (or anything else for that matter).
For the record: I havenât tried and I donât know of anyone who has. Youâd have to try. I donât see why not, but again, I havenât tried.
But when youâre talking about a large youâre probably also talking about an expensive project with high stakes. Do you want something that is robust, standardized, and by default supported by the entire post-ES6 ecosystem or do you want a legacy feature that happens to look and feel a bit more familiar?