要在模块之间共享数据,通常的模式是将数据封装到一个公共模块中,并将其导入其他模块。
在我的例子中,要共享的数据是一个记录器,需要在使用之前进行初始化。我在应用程序的入口点调用init()。
// main.js
let logger = require('@my/logger');
logger.init({...});
let xxx = require('./moduleX');
let yyy = require('./moduleY');在其他模块中,可以使用初始化的记录器:
// 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模块,我如何初始化一些数据并将它们与其他模块共享?
有一个类似的问题,但答案不适合我的情况。
更新:
一些答案建议将访问共享数据的代码放入函数中,这样就不会在模块加载时立即调用代码。但是,如果我真的需要在加载模块时访问它呢?我更新了我的代码以演示用例--如果不是将logger(name)作为模块作用域const,那么在每个函数中调用log太简单了。
发布于 2015-12-14 03:55:50
最后,我用@PaoloMoretti在他的评论中提到的方式解决这个问题。
在我的应用程序中编写一个模块,为我的应用程序插入记录器:
// logger_init.js
import {logger} from '@my/logger';
logger.init({...});在导入使用记录器的任何其他模块之前,在应用程序的入口点导入初始化模块一次。它保证初始化在加载其他模块之前完成。
// main.js
import './logger_init';
import {x} from '@my/other_module';
import {y} from './module_in_myapp';其他模块可以直接使用初始化的记录器:
// @my/other_module
import {logger} from '@my/logger';
const log = logger('moduleX'); // logger has been initialized
export function x() {
log.debug('some msg');
}依赖树是:
<init>
myapp --+--> logger_init ------------> @my/logger
| <use> ↑
+--> module_in_myapp -----------+
| <use> |
+--> @my/other_module ----------+我之所以不采用添加包装器模块的方式(正如Bergi的回答),因为使用记录器的模块可能是可重用模块,而不是在我的应用程序中。
发布于 2015-12-11 15:14:07
尝试为您的xxx.js和yyy.js模块提供一些入口点,甚至将它们作为函数。
// main.js
import {logger} from '@my/logger';
import * as xxx from './xxx';
logger.init({...});
xxx.run();
// xxx.js
import {logger} from '@my/logger';
export function run () {
logger.debug('In xxx');
}发布于 2015-12-11 15:14:20
您可以让每个依赖于某些初始化例程的模块返回一个函数,该函数可以手动执行以调用其功能,而不是将该功能公开为导入它的直接副作用。例如,在xxx.js中
// xxx.js
export default function (log) {
log('xxx');
}然后将所有初始化操作放在一个条目文件中,并在这些操作完成后调用以上述方式定义的模块:
// main.js
import xxx from './xxx';
import {logger} from '@my/logger';
logger.init({...});
xxx(logger);但是,如果我真的需要在加载模块时访问它呢?
请参阅上文修正的代码示例。将logger实例传递给每个模块导出的函数。
https://stackoverflow.com/questions/34226229
复制相似问题