在导入ES6模块之前定义全局变量



我最近在NodeJS项目中从CommonJS切换到了ES6模块。我面临的挑战之一是在导入模块之前定义一个全局变量。我曾经在我的主文件中使用CommonJS来做这件事


const path = require('path');
global.appRoot = path.resolve(__dirname);
const myObj = require('./my-object-file');

其中我的CCD_ 1使用CCD_。

使用ES6,我尝试了以下操作:

import path from 'path';
global.appRoot = path.resolve(path.resolve());
import myObj from './my-object-file';

其中my-object-file.js为:

export default {
root: global.appRoot
}

但我在my-object-file.js中得到了global.appRoot的未定义。

这是怎么回事?

导入模块是否在我的代码中的任何内容之前调用?

我该如何解决这个问题(知道我绝对希望能够将路径定义为可在模块中访问的全局变量(?

导入模块是否在我的代码中调用之前?

是的,在导入模块中的任何代码运行之前,都会解析所有模块导入。

然而,导入的模块也按顺序执行,因此如果您执行

import './setupGlobals';
import myObj from './my-object-file';

setupGlobals模块代码在my对象文件之前执行。所以什么时候起作用

// setupGlobals.mjs
import path from 'path';    
global.appRoot = path.resolve(path.resolve());

我绝对希望能够将路径定义为可在我的模块中访问的全局变量

不,你真的不想那样做。明确声明您的依赖关系,而不是在任何地方创建全局变量!

如果您有一个单独的模块来定义全局变量,只需将export作为这些变量,而不是将值放在global对象上:

// globals.mjs
import path from 'path';    
const appRoot = path.resolve(path.resolve());
export { appRoot as default }

然后,您可以在任何模块中声明性地使用这个全局常量:

// my-object-file.js:
import appRoot from './globals';
export default {
root: appRoot
}

我喜欢Bergi的答案:

import appRoot from './globals';

然后,任何想要访问的文件都可以访问appRoot,并且可以保留模块性。

但是,除了这种方法之外,我在评论中的建议是,与其在导入之前设置全局,不如从模块中导出一个函数并调用该函数,将其传递给所需的路径。这是一种从父模块向模块传递初始化参数的通用方法,无需使用全局变量。

并且,我建议您使用import.meta.url解决方案来创建等效的my-object-file0作为这里的大纲。您对path.resolve()所做的只是获得当前工作目录,它不一定是__dirname,因为这取决于如何加载此模块,以确定它们是否相同。此外,如果你只是想要等价的cwd,你可以在你的子模块中使用process.cwd()。以下是ESM模块中__filename__dirname的等效值。

// create __dirname and __filename equivalents in ESM module
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

然后,导入模块初始化函数(有时称为模块构造函数(并调用模块构造函数:

从"导入myObjConstructor/我的对象文件';const myObj=myObjConstructor(__dirname(;

然后,在我的对象文件中,导出一个函数,当调用该函数时,使用传入的__dirname初始化模块,并返回myObj

因此,my-object-file:内部

function init(__dirname) {
// do whatever you want for module initialization
// using __dirname
return yourObj;
}
export { init as default };

相关内容

  • 没有找到相关文章

最新更新