【发布时间】:2016-03-17 12:36:16
【问题描述】:
为了在模块之间共享数据,通常的模式是将数据封装到一个公共模块中,然后将其导入其他模块中。
在我的例子中,要共享的数据是一个记录器,需要在使用前进行初始化。我在应用程序的入口点调用init()。
// main.js
let logger = require('@my/logger');
logger.init({...});
let xxx = require('./moduleX');
let yyy = require('./moduleY');
在其他模块中,可以使用初始化的logger:
// moduleX.js
let logger = require('@my/logger');
const log = logger('moduleX');
function x() {
log.debug('some msg');
}
以上代码在 node.js 中运行良好。但是如果我更改为 ES6 模块语法,它就不起作用了,因为 ES6 模块导入被提升了。
// main.js
import {logger} from '@my/logger';
logger.init({...}); // this line is run after import moduleX
import {x} from './moduleX';
// moduleX.js
import {logger} from '@my/logger';
const log = logger('moduleX'); // logger is not initialized !
export function x() {
log.debug('some msg');
}
使用 ES6 模块,我如何初始化一些数据并将它们共享给其他模块?
有一个类似的question,但答案不适合我的情况。
更新:
一些答案建议将访问共享数据的代码放入函数中,以便在模块加载时不会立即调用代码。但是如果我真的需要在模块加载期间访问它怎么办?我更新了我的代码来演示用例——如果不将 log 作为模块范围 const,在每个函数中调用 logger(name) 就太简单了。
【问题讨论】:
-
为什么不直接创建另一个文件
initializeLogger.js并在其中调用logger.init并将该文件导入main.js? -
@PaoloMoretti 我想过这种方式,但它需要另一个文件,对我来说看起来不够简洁。但是,这似乎是解决它的唯一方法。你能写一个答案让我接受吗?
-
在调用
logger(…)之前记录器需要进行什么初始化?不是只有log.debug(…)需要等待吗? -
@Bergi 输出目标、应用程序名称等。您可能会说对于记录器没有必要这样做。我要求一种通用模式来处理这种需求:初始化一个对象并将其共享给每个模块。
-
@aleung:嗯,您链接的“类似问题”似乎已经回答了这个问题。但我在下面写了一个明确的答案。
标签: javascript module ecmascript-6