Nested namespaces vs. ES modules

二次信任 提交于 2021-01-29 15:53:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!