![](/img/trans.png)
[英]Javascript ES6 - wait for module to complete execution before importing function or variable in a different .js file
[英]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.js
為global.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.