簡體   English   中英

在 node.js 中使用外部 javascript 文件而不使用 export 和 require

[英]Using external javascript files in node.js without using export and require

我不喜歡節點中的整個導出/需要的東西,它需要太長時間。 假設我有一個文件 server.js,我想在 whatever.js 中使用函數。 在 html 中,我將其添加到 header 中:

<script src='whatever.js'></script>

然后我就可以在我身體的腳本中使用 whatever.js 的所有功能。

但是在節點中,在 server.js 文件中我會這樣做:

var myobject = require('./whatever.js');

但是我需要將它設置為 myobject,而且我需要將 go 設置為 whatever.js 並手動決定我想要導出的功能。 更不用說輸入 myobject.someFunction() 比 someFunction() 寫起來要長得多,我需要記住我暴露/沒有暴露的內容。

我想要一些我只能 go 的東西:

require('./whatever.js');

並將其全部放在全球范圍內,沒有bs。 就像在好的舊 html/javascript 中一樣。 有沒有辦法在節點中執行此操作?

這樣就可以了,

var fs = require('fs');

eval(fs.readFileSync('whatever.js')+'');
 // here call functions from whatever.js file

(我意識到這是一個舊線程,但想在這里為后代留下一張紙條。)

在 2022 年,有幾種方法可以使用 Node.js 從不同文件執行代碼:

ESM:使用標准的 ECMAScript 模塊

在撰寫本文時,許多節點生態系統(即 npm 上的包)正在過渡到這種范式,並且存在一些相關的成長煩惱(例如__dirname類的東西僅在 CJS 而不是 ESM 中可用,盡管解決方法很簡單)。 對於大多數開發人員來說,最好適應這個標准,因為它超越了 node.js(即在Deno和 web 瀏覽器等其他運行時中實現)並且已經制定多年。

CJS:使用原始的“CommonJS”模塊機制,eg require('./some-script.js')

應該注意,特別是對於 OP,即使使用 CJS 模塊的“預期”方式是導出函數、常量等並顯式導入它們,也可以使用globalThis定義全局 scope 中的所有內容,盡管我不會推薦這個。

// my-script.js
require('./foo.js');
require('./bar.js');
foo(); // This is foo from <...>foo.js
console.log(`bar = ${bar} (in ${__filename})`); // bar = 123 (in <...>my-script.js)

// foo.js
globalThis.foo = function() {
  console.log(`This is foo from ${__filename}`);
}

// bar.js
globalThis.bar = 123;

如果您嘗試省略globalThis. 您會發現主腳本中不再定義foobar ,因為require在“模塊 scope”中“包裝了它們”。

使用eval

根據我的經驗, eval的合法用例很少(請參閱切勿使用 eval()! )。 然而,這個問題中要求的功能正是eval提供的:“運行一些代碼,就好像它是在這里寫的一樣”,你可以從文件中提供它,正如上面 Mehul Prajapati所解釋的

// include.js 
// Defines a global function that works like C's "#include" preprocessor directive
const { readFileSync } = require('fs');
globalThis.include = function(scriptFile) {
  console.warn('!!! EXTREMELY INSECURE !!!');
  eval(readFileSync(scriptFile, 'utf-8'));
};


// main.js
require('./include.js'); // loads global include

// (I sure hope you completely trust these sources)
include('./foo.js');
include('./bar.js');

注意:過去造成我很多困惑的是,存在使用一些相同標識符的競爭標准/約定/API,即require ,它require.js其他支持AMD 的捆綁(異步模塊定義)使用不同的語義。 因此,對於使用 node.js 工具(在本地使用 CJS 模塊)構建 web 應用程序(在 web 瀏覽器中使用 AMD 模塊)的人來說,保持功能直接可能會令人沮喪,特別是如果它是一個Electron應用程序,它可以將 Node.js API 暴露給腳本在渲染器(瀏覽器)中運行。 如果您發現自己對為什么在這種情況下“找不到”模塊感到困惑,請檢查堆棧跟蹤以查看正在調用哪個require (並且您可能必須在globalThis或其他東西上包裝/重命名它們以避免沖突)。

延伸閱讀:

暫無
暫無

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

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