问题
With traditional JavaScript namespacing techniques I am able to create a nested logical grouping, even over multiple files. How should I replace that with ES modules alias import.
Consider the case where I want all my code in a CompanyName namespace, then group by products and within a product I may have a group of shared functions and these could be grouped by topic (very common in many languages like Java, C# etc.). F.e.
CompanyName = {
ProductName1: {
Shared: {
Database: {
enumerateDatabases: function() {
....
}
...
}
}
},
ProductName2: {
....
}
}
If I understand correctly ES modules allow me to use exactly one alias to create a namespace, f.e.
import * as CompanyName from ...
An alias like CompanyName only is certainly not specific enough. An alias like
import * as CompanyNameProductName1SharedDatabase from...
is almost unreadable and a simple alias like
import * as Database from...
may quickly become ambiguous and I would have to go with aliases like
import * as MyDatabase from...
import * as YourDatabase from...
Does that mean there is no way of grouping code as shown above? Or should I go with a mixture of both techniques?
回答1:
If I understand correctly ES modules allow me to use exactly one alias to create a namespace
Yes, aliases must be simple identifiers, there is no nesting. Notice that CompanynameProductname1SharedDatabase
isn't that bad compared to Companyname.Productname1.Shared.Database
- even in other languages you wouldn't write the whole package name every time, but give it a reasonable alias. Maybe even with abbreviations like CPSDb
.
A simple alias like
import * as Database from...
may quickly become ambiguous
No, it should not. It's quite unlikely that Product2 would need to import Product1's database. You would only need to disambiguate if you really have multiple databases in the same module.
Just choose reasonable aliases for the current module. That might mean using different aliases depending on where you are importing it, and that's fine:
// src/productname1/shared/index.js
import * as Database from './database.js';
// src/backend/init.js
import * as Productname1SharedDatabase from '/productname1/shared/database.js';
Also notice that it's rather uncommon in JS to use namespace imports at all, they're only used when you import many bindings from a module and need to disambiguate them from other modules. You'll see
import { enumerateDatabase } from './database.js';
much more often, and it's clear already that an enumerateDatabase
function would be found in the database module. Notice that there are no implicit bindings in JavaScript: if you forgot where an identifier came from, you will always find its (import) declaration in the current file so you can easily look it up. Additionally, your IDE will help you by showing where the name resolves to.
回答2:
The way you would do it would be
const enumerateDatabases = function() {
....
}
export {
enumerateDatabases
}
and
import {enumerateDatabases as aliasForEnumDbs} from 'xx.js';
来源:https://stackoverflow.com/questions/63042535/nested-namespaces-vs-es-modules