簡體   English   中英

導入 ES6 模塊前定義全局變量

[英]Define global variable before importing ES6 module

我最近在 NodeJS 項目中從 CommonJS 切換到 ES6 模塊。 我面臨的挑戰之一是在導入我的模塊之一之前定義一個全局變量。 我曾經在我的主文件中使用 CommonJS 來做到這一點:


const path = require('path');

global.appRoot = path.resolve(__dirname);

const myObj = require('./my-object-file');

其中 my my-object-file使用global.appRoot

使用 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.jsglobal.appRoot未定義。

這里發生了什么?

導入模塊是否在我的代碼中的任何內容之前調用?

我該如何解決這個問題(知道我絕對希望能夠將路徑定義為可在我的模塊中訪問的全局變量)?

導入模塊是否在我的代碼中的任何內容之前調用?

是的,所有模塊導入都會在導入模塊中的任何代碼運行之前解決。

但是,導入的模塊也是按順序執行的,所以如果你這樣做

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

然后setupGlobals模塊代碼在my-object-file之前執行。 所以它會在什么時候工作

// 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
}

我喜歡貝爾吉的回答:

import appRoot from './globals';

然后,任何想要訪問的文件都可以訪問appRoot並保留模塊化。

但是,除了這種方法之外,我在評論中的建議是,與其在導入之前設置全局變量,不如從模塊中導出一個函數並調用該函數,將其傳遞給所需的路徑。 這是將初始化參數從父模塊傳遞給模塊而不使用全局變量的通用方法。

而且,我建議您使用import.meta.url解決方法來創建__dirname的等效__dirname作為大綱here 您對path.resolve()所做的只是讓您獲得當前工作目錄,它不一定是__dirname因為它取決於此模塊的加載方式是否相同。 此外,如果您只想要等效的 cwd,則無論如何都可以在子模塊中使用process.cwd() 這是 ESM 模塊中__filename__dirname的等效__filename

// 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);

然后,導入模塊初始化函數(有時稱為模塊構造函數)並調用模塊構造函數:

從 './my-object-file' 導入 myObjConstructor; const myObj = myObjConstructor(__dirname);

然后,在 my-object-file 中,您導出一個函數,當該函數被調用時,您使用傳入的__dirname初始化您的模塊並返回myObj

所以,在my-object-file

function init(__dirname) {
   // do whatever you want for module initialization
   // using __dirname

   return yourObj;
}

export { init as default };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM