如何有条件地修改 ES6 Javascript 模块的导出

问题描述 投票:0回答:1

我想知道是否有可能以某种方式仍然从模块内部访问 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 ?

javascript node.js babeljs es6-modules
1个回答
0
投票

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' ]

© www.soinside.com 2019 - 2024. All rights reserved.