我想知道是否有可能仍然从模块内部访问ES6模块的模块导出,就像在CommonJS中使用module. exports一样。
为了清楚起见,我有一个js模块(Config.js),我用它来导出所有的配置变量。
export const DatabaseName = "myDbName";
export const DatabasePort = 3000;
export const DatabaseHosts = ["174.292.292.32"];
export const MaxWebRequest = 50;
export const MaxImageRequests = 50;
export const WebRequestTimeout = 30;
etc...
字符串
然后我有一个单独的Dev.Config.js文件,它只包含我的开发环境的覆盖。
export const DatabaseHosts = ["localhost"];
export const DatabasePort = 5500;
型
在我的主Config.js文件中,我在底部有这样的逻辑。
try {
var environmentConfig = `./${process.env.NODE_ENV}.Config.js`;
var localConfig = require(environmentConfig)
module.exports = Object.assign(module.exports, localConfig)
} catch (error) {
console.log("Error overriding config with local values. " + error)
}
型
最后,在我的消费代码中,我可以像这样导入我的js文件,
import * as Config from "./Config.js";
console.log(Config.DatabaseHosts) // Gives me the correct "overridden" value on my dev environment
型
目前,我一直在使用babel将我的代码全部转回到CommonJS中,我想这就是我如何能够混合和匹配导入/导出语法的方式,并且仍然像我上面所做的那样引用模块。
我的问题是,我如何在一个纯ES6模块中复制这个模式,而不需要使用babel转换它,因为我不能从模块本身修改我的模块。
2条答案
按热度按时间zaq34kh61#
ESM不支持条件导出模式。
为了使用dynamic import修改从另一个模块导出的值,该模块的指定符是从环境变量派生的(在
try...catch
语句中,这样失败的尝试就不会在顶层抛出未捕获的异常),您可以修改导出的结构,以便它们作为对象的属性公开。下面是一个可重现的示例来演示:./package.json
:字符串
./Dev.Config.js
:型
./Config.js
:型
./main.js
:型
在终端:
型
gpnt7bae2#
在ES6模块中没有办法动态构建/覆盖exports对象。即使是条件导入也需要顶级的
await
或工具支持。然而,你可以做的是混乱的
let
声明和eval
:字符串
不过我不推荐这样做。只有当你无法改变 * Config.js * 模块的使用方式时,或者当有太多的导出变量使得替代方案不可行时,才使用这种方法。
相反,我建议您创建一个单独的模块来合并配置,尽管这需要拼写两次配置名称:
或者将配置模块改为默认导出对象,这样你就可以任意操作这些对象了,但是你失去了使用命名导入和静态验证的能力。