我想知道是否有可能以某种方式仍然从模块内部访问 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)
}
最后,在我使用的代码中,我可以像这样导入我的 config.js 文件
import * as Config from "./Config.js";
console.log(Config.DatabaseHosts) // Gives me the correct "overridden" value on my dev environment
目前我一直在使用 babel 将我的代码全部转译回 CommonJS,我想这就是我如何能够混合和匹配导入/导出语法,并且仍然像我上面所做的那样引用 module.exports。
我的问题是,如何在纯 ES6 模块中复制此模式,而不需要使用 babel 进行转译,而我无法从模块本身修改 module.exports ?
ESM 不允许有条件导出。
为了使用 dynamic import 从另一个模块(其说明符派生自环境变量)修改导出的值(在
try...catch
语句中,以便失败的尝试不会在顶层抛出异常),您可以修改导出的结构,以便将它们作为对象的属性公开。下面是一个可重现的示例来演示:
./package.json
:
{
"name": "so-77465699",
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "NODE_ENV=Dev node main.js",
"prod": "NODE_ENV=production node main.js"
},
"license": "MIT"
}
./Dev.Config.js
:
export const Config = {
DatabaseHosts: ["localhost"],
DatabasePort: 5500,
};
export default Config;
./Config.js
:
export const Config = {
DatabaseName: "myDbName",
DatabasePort: 3000,
DatabaseHosts: ["174.292.292.32"],
MaxWebRequest: 50,
MaxImageRequests: 50,
WebRequestTimeout: 30,
};
export default Config;
try {
// Import a module specifier based on
// the value of the NODE_ENV environemnt variable.
// Destructure and rename the default export:
const { default: envConfig } = await import(
`./${process.env.NODE_ENV}.Config.js`
);
// Iterate the keys and values, updating the existing Config object:
for (const [key, value] of Object.entries(envConfig)) {
Config[key] = value;
}
} catch (cause) {
console.log(`Error overriding config with local values: ${cause}`);
}
./main.js
:
// Import named export
import { Config } from "./Config.js";
// Alternatively, since it's also the default export:
// import { default as Config } from "./Config.js";
// Or, using syntax sugar:
// import Config from "./Config.js";
console.log(Config.DatabaseHosts);
在终端中:
% node --version
v20.9.0
% npm run dev
> [email protected] dev
> NODE_ENV=Dev node main.js
[ 'localhost' ]
% npm run prod
> [email protected] prod
> NODE_ENV=production node main.js
Error overriding config with local values: Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/node/so-77465699/production.Config.js' imported from /Users/node/so-77465699/Config.js
[ '174.292.292.32' ]