HOWTO · JavaScript

如何從另一個 JS 檔案匯入函式

了解如何使用瀏覽器腳本、ECMAScript 模組、Node.js CommonJS 或傳統的 jQuery,從另一個 JavaScript 檔案呼叫函式。

本頁內容

要從另一個 JavaScript 檔案呼叫函式,請根據環境選擇共享方法:經典的 <script> 標籤將函式公開為瀏覽器全域變數,ECMAScript 模組使用 export 和 import,Node.js CommonJS 使用 module.exports 和 require。下面的範例展示了如何連接這些檔案以及每種方法的執行位置。

在瀏覽器中從另一個 JavaScript 檔案呼叫函式

對於使用經典腳本的頁面,在一個檔案中定義函式,並在呼叫它的腳本之前載入該檔案。經典腳本共享頁面的全域範圍,因此第一個檔案可以將函式附加到 window:

  • 在 greeting.js 中,編寫 window.showGreeting = function () { document.querySelector("#message").textContent = "Hello from greeting.js"; };。
  • 在 app.js 中,編寫 document.querySelector("#show").addEventListener("click", window.showGreeting);。

將這些檔案保存在 index.html 旁邊。此頁面按所需順序載入它們,並提供按鈕和訊息元素:

<!doctype html>
<html lang="en">
  <meta charset="utf-8">
  <title>Call a function from another file</title>
  <p id="message">Click the button to show the message.</p>
  <button id="show" type="button">Show greeting</button>
  <script src="greeting.js"></script>
  <script src="app.js"></script>
</html>

當按鈕被點擊時,app.js 中的處理程序會呼叫從 greeting.js 載入的函式。請將定義腳本放在前面;否則,頁面可能會在 window.showGreeting 存在之前嘗試註冊處理程序。這個 html 程式碼區塊是瀏覽器頁面範例,而不是執行階段輸出記錄。

使用 ECMAScript 模組共享函式

當您希望使用明確匯入而不是共享全域變數時,請使用 ECMAScript 模組。將這三個完整檔案保存在同一目錄中。第一個檔案匯出一個函式,第二個檔案匯入它並更新頁面:

  • greeting.js:export function makeGreeting(name) { return \Hello, ${name}!`; }`
  • app.js:import { makeGreeting } from "./greeting.js"; document.querySelector("#message").textContent = makeGreeting("Ada");

將此完整頁面另存為 index.html,放在這些檔案旁邊。在模組執行之前,其訊息元素已經存在:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Share a function with a module</title>
  </head>
  <body>
    <p id="message">The greeting will appear here.</p>
    <script type="module" src="app.js"></script>
  </body>
</html>

保持相對匯入路徑與檔案位置一致。瀏覽器以模組語義載入模組,不會將其中宣告的內容放到 window 上。

請透過本地開發伺服器以 HTTP 方式提供該頁面;直接以 file: URL 開啟它通常會阻止模組載入。這是瀏覽器的託管要求,而不是執行 Node.js 的要求。Node.js 也支援 ECMAScript 模組,並有其自己的套件和副檔名規則。ECMAScript 模組匯出語法對函式和其他值使用同樣的 export 機制。

使用 CommonJS 在 Node.js 中匯入函式

CommonJS 是 Node.js 傳統的模組系統。模組可以將函式賦給 module.exports,另一個檔案可以用 require 取得它。連結的 JavaScript import 與 require 的比較解釋了這些模組系統之間的差異。

這個自包含的 Node.js 範例建立一個輔助檔案,匯入其函式並呼叫它。將程式碼保存為 main.cjs,並在安裝了 Node.js 的終端機中執行 node main.cjs:

const fs = require("node:fs");
const os = require("node:os");
const path = require("node:path");

const folder = fs.mkdtempSync(path.join(os.tmpdir(), "function-demo-"));
try {
  const helperPath = path.join(folder, "math.cjs");
  fs.writeFileSync(helperPath, "module.exports = (a, b) => a + b;\n");
  const add = require(helperPath);
  console.log(`Result: ${add(5, 3)}`);
} finally {
  fs.rmSync(folder, { recursive: true, force: true });
}
Result: 8

輔助檔案匯出一個函式,呼叫方將其作為 require 的回傳值接收;最後的 console.log 呼叫使用這個回傳的函式。.cjs 副檔名使輔助檔案的 CommonJS 格式明確,即使周圍專案使用 ECMAScript 模組也是如此。此範例是為 Node.js 編寫的,不會在瀏覽器頁面中執行。

使用 jQuery 載入 JavaScript 檔案

jQuery 的 $.getScript() 可以按需載入腳本。這是已經使用 jQuery 的頁面的一種傳統替代方法;新程式碼通常使用瀏覽器模組或普通腳本標籤會更清晰。在呼叫方之前載入 jQuery,並等待載入回呼後再使用下載檔案中的函式。

例如,mathUtils.js 可以使用 window.mathUtils = { add: (a, b) => a + b }; 公開一個瀏覽器全域變數。在頁面中,先載入 jQuery,並使用回呼在腳本載入後呼叫函式:

<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script>
  $.getScript("mathUtils.js")
    .done(function () {
      const result = window.mathUtils.add(5, 3);
      $("body").append(`<p>Result: ${result}</p>`);
    })
    .fail(function () {
      $("body").append("<p>The script could not be loaded.</p>");
    });
</script>

請求是非同步的,因此依賴 mathUtils 的程式碼應放在 .done() 內部(或其他完成處理程序中),而不是緊跟在 $.getScript() 之後。對於跨來源 URL,jQuery 可以透過腳本元素載入腳本;瀏覽器通常不要求對此類腳本載入進行 CORS。跨來源的 fetch() 或 XHR 請求則確實需要伺服器用 CORS 允許。腳本載入仍可能被 Content Security Policy 等瀏覽器策略阻止,或者在 URL 無法存取時失敗。有關其載入行為,請參閱 jQuery $.getScript() 文件。