🚀 在 VS Code 中

使用 JavaScript

本主題說明 Visual Studio Code 支援的一些進階 JavaScript 功能。透過使用 TypeScript 語言服務,VS Code 可以為 JavaScript 提供智慧完成 (IntelliSense) 以及類型檢查。

IntelliSense

Visual Studio Code 的 JavaScript IntelliSense 提供智慧程式碼完成、參數資訊、參考搜尋和許多其他進階語言功能。我們的 JavaScript IntelliSense 由 TypeScript 團隊開發的 JavaScript 語言服務提供技術支援。雖然 IntelliSense 應該適用於大多數 JavaScript 專案,而無需任何設定,但您可以透過 JSDoc 或設定 jsconfig.json 專案,使 IntelliSense 更加實用。

如需 JavaScript IntelliSense 如何運作的詳細資訊,包括基於類型推斷、JSDoc 註解、TypeScript 宣告以及混合 JavaScript 和 TypeScript 專案,請參閱 JavaScript 語言服務文件

當類型推斷無法提供所需的資訊時,可以使用 JSDoc 註解明確提供類型資訊。本文檔說明目前支援的 JSDoc 註解

除了物件、方法和屬性之外,JavaScript IntelliSense 視窗也為您檔案中的符號提供基本字詞完成。

Typings 和自動類型擷取

JavaScript 程式庫和架構的 IntelliSense 由 TypeScript 類型宣告 (typings) 檔案提供技術支援。類型宣告檔案以 TypeScript 撰寫,因此它們可以表達參數和函式的資料類型,讓 VS Code 能夠以高效能的方式提供豐富的 IntelliSense 體驗。

許多熱門程式庫都隨附 typings 檔案,因此您可以自動取得它們的 IntelliSense。對於不包含 typings 的程式庫,VS Code 的 自動類型擷取 會自動為您安裝社群維護的 typings 檔案。

自動類型擷取需要 npmjs,Node.js 套件管理員,它包含在 Node.js 執行階段中。在此影像中,您可以看到 IntelliSense,包括方法簽章、參數資訊以及熱門 lodash 程式庫的方法文件。

lodash typings

類型宣告檔案由 Visual Studio Code 自動下載和管理,適用於專案 package.json 中列出的套件或您匯入到 JavaScript 檔案中的套件。

{
  "dependencies": {
    "lodash": "^4.17.0"
  }
}

或者,您可以在 jsconfig.json 中明確列出要取得類型宣告檔案的套件。

{
  "typeAcquisition": {
    "include": ["jquery"]
  }
}

最常見的 JavaScript 程式庫都隨附宣告檔案,或提供類型宣告檔案。

修正自動類型擷取的 npm 未安裝警告

自動類型擷取 使用 npm,Node.js 套件管理員,來安裝和管理類型宣告 (typings) 檔案。為了確保自動類型擷取正常運作,請先確保您的電腦上已安裝 npm。

從終端機或命令提示字元執行 npm --version,快速檢查 npm 是否已安裝且可用。

npm 隨附於 Node.js 執行階段一起安裝,可從 Nodejs.org 下載。安裝目前的 LTS (長期支援) 版本,npm 可執行檔預設會新增至您的系統路徑。

如果您已安裝 npm 但仍然看到警告訊息,您可以透過 typescript.npm 設定明確告知 VS Code npm 的安裝位置。這應該設定為您電腦上 npm 可執行檔的完整路徑,而且這不必與您用來管理工作區中套件的 npm 版本相符。typescript.npm 需要 TypeScript 2.3.4+。

例如,在 Windows 上,您可以將如下的路徑新增至您的 settings.json 檔案

{
  "typescript.npm": "C:\\Program Files\\nodejs\\npm.cmd"
}

JavaScript 專案 (jsconfig.json)

目錄中是否存在 jsconfig.json 檔案表示該目錄是 JavaScript 專案的根目錄。jsconfig.json 指定根檔案以及 JavaScript 語言服務提供的語言功能選項。對於常見的設定,不需要 jsconfig.json 檔案,但是,在某些情況下,您會想要新增 jsconfig.json

  • 並非所有檔案都應該在您的 JavaScript 專案中 (例如,您想要排除某些檔案不顯示 IntelliSense)。這種情況在前端和後端程式碼中很常見。
  • 您的工作區包含多個專案內容。在這種情況下,您應該在每個專案的根資料夾中新增 jsconfig.json 檔案。
  • 您正在使用 TypeScript 編譯器來向下層級編譯 JavaScript 原始碼。

jsconfig.json 的位置

若要將我們的程式碼定義為 JavaScript 專案,請在您的 JavaScript 程式碼根目錄建立 jsconfig.json,如下所示。JavaScript 專案是專案的原始檔,不應包含衍生或封裝的檔案 (例如 dist 目錄)。

jsconfig setup

在更複雜的專案中,您可能在工作區內定義了多個 jsconfig.json 檔案。您會想要這樣做,以便一個專案中的原始碼不會出現在另一個專案的 IntelliSense 中。

下面說明一個包含 clientserver 資料夾的專案,顯示兩個不同的 JavaScript 專案

multiple jsconfigs

撰寫 jsconfig.json

以下是 jsconfig.json 檔案的簡單範本,它將 JavaScript target 定義為 ES6,而 exclude 屬性排除 node_modules 資料夾。您可以複製並貼上此程式碼到您的 jsconfig.json 檔案中。

{
  "compilerOptions": {
    "module": "CommonJS",
    "target": "ES6"
  },
  "exclude": ["node_modules", "**/node_modules/*"]
}

exclude 屬性會告知語言服務哪些檔案不是您原始碼的一部分。如果 IntelliSense 速度很慢,請將資料夾新增至您的 exclude 清單 (如果 VS Code 偵測到完成速度緩慢,它會提示您這樣做)。您會想要 exclude 建置程序產生的檔案 (例如 dist 目錄)。這些檔案會導致建議顯示兩次,並減慢 IntelliSense 的速度。

您可以使用 include 屬性明確設定專案中的檔案。如果沒有 include 屬性,則預設為包含包含目錄和子目錄中的所有檔案。當指定 include 屬性時,只會包含這些檔案。

以下是一個具有明確 include 屬性的範例

{
  "compilerOptions": {
    "module": "CommonJS",
    "target": "ES6"
  },
  "include": ["src/**/*"]
}

最佳做法和最不容易出錯的路徑是使用 include 屬性搭配單一 src 資料夾。請注意,excludeinclude 中的檔案路徑相對於 jsconfig.json 的位置。

如需詳細資訊,請參閱完整的 jsconfig.json 文件

移轉至 TypeScript

可以混合使用 TypeScript 和 JavaScript 專案。若要開始移轉至 TypeScript,請將您的 jsconfig.json 檔案重新命名為 tsconfig.json,並將 allowJs 屬性設定為 true。如需詳細資訊,請參閱 從 JavaScript 移轉

注意: jsconfig.jsontsconfig.json 檔案相同,只是 allowJs 設定為 true。請參閱此處的 tsconfig.json 文件以查看其他可用的選項。

類型檢查 JavaScript

VS Code 允許您在常規 JavaScript 檔案中利用 TypeScript 的一些進階類型檢查和錯誤報告功能。這是捕捉常見程式設計錯誤的好方法。這些類型檢查也為 JavaScript 啟用了一些令人興奮的快速修正,包括新增遺失的匯入新增遺失的屬性

Using type checking and Quick Fixes in a JavaScript file

TypeScript 可以在 .js 檔案中推斷類型,與在 .ts 檔案中相同。當無法推斷類型時,可以使用 JSDoc 註解指定類型。您可以閱讀更多關於 TypeScript 如何使用 JSDoc 進行 JavaScript 類型檢查的資訊,請參閱 類型檢查 JavaScript 檔案

JavaScript 的類型檢查是選用的且可選擇加入的。現有的 JavaScript 驗證工具 (例如 ESLint) 可以與新的內建類型檢查功能一起使用。

您可以根據您的需求,透過幾種不同的方式開始進行類型檢查。

每個檔案

在 JavaScript 檔案中啟用類型檢查的最簡單方法是在檔案頂端新增 // @ts-check

// @ts-check
let itsAsEasyAs = 'abc';
itsAsEasyAs = 123; // Error: Type '123' is not assignable to type 'string'

如果您只想在幾個檔案中嘗試類型檢查,但還不想為整個程式碼庫啟用它,則使用 // @ts-check 是一個不錯的方法。

使用設定

若要在不變更任何程式碼的情況下為所有 JavaScript 檔案啟用類型檢查,只需將 "js/ts.implicitProjectConfig.checkJs": true 新增至您的工作區或使用者設定即可。這會為任何不屬於 jsconfig.jsontsconfig.json 專案的 JavaScript 檔案啟用類型檢查。

您可以使用檔案頂端的 // @ts-nocheck 註解,選擇退出個別檔案的類型檢查

// @ts-nocheck
let easy = 'abc';
easy = 123; // no error

您也可以使用錯誤行之前的 // @ts-ignore 註解,停用 JavaScript 檔案中的個別錯誤

let easy = 'abc';
// @ts-ignore
easy = 123; // no error

使用 jsconfig 或 tsconfig

若要為屬於 jsconfig.jsontsconfig.json 一部分的 JavaScript 檔案啟用類型檢查,請將 "checkJs": true 新增至專案的編譯器選項

jsconfig.json:

{
  "compilerOptions": {
    "checkJs": true
  },
  "exclude": ["node_modules", "**/node_modules/*"]
}

tsconfig.json:

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true
  },
  "exclude": ["node_modules", "**/node_modules/*"]
}

這會為專案中的所有 JavaScript 檔案啟用類型檢查。您可以使用 // @ts-nocheck 來停用每個檔案的類型檢查。

JavaScript 類型檢查需要 TypeScript 2.3。如果您不確定目前工作區中作用中的 TypeScript 版本為何,請執行TypeScript: 選取 TypeScript 版本命令來檢查。您必須在編輯器中開啟 .js/.ts 檔案才能執行此命令。如果您開啟 TypeScript 檔案,版本會顯示在右下角。

全域變數和類型檢查

假設您正在處理使用全域變數或非標準 DOM API 的舊版 JavaScript 程式碼

window.onload = function() {
  if (window.webkitNotifications.requestPermission() === CAN_NOTIFY) {
    window.webkitNotifications.createNotification(null, 'Woof!', '🐶').show();
  } else {
    alert('Could not notify');
  }
};

如果您嘗試將 // @ts-check 與上述程式碼一起使用,您會看到許多關於使用全域變數的錯誤

  1. 第 2 行 - 類型 'Window' 上不存在屬性 'webkitNotifications'。
  2. 第 2 行 - 找不到名稱 'CAN_NOTIFY'。
  3. 第 3 行 - 類型 'Window' 上不存在屬性 'webkitNotifications'。

如果您想要繼續使用 // @ts-check,但確信這些不是應用程式的實際問題,則必須讓 TypeScript 知道這些全域變數。

首先,在專案根目錄建立 jsconfig.json

{
  "compilerOptions": {},
  "exclude": ["node_modules", "**/node_modules/*"]
}

然後重新載入 VS Code 以確保變更已套用。jsconfig.json 的存在讓 TypeScript 知道您的 Javascript 檔案是較大專案的一部分。

現在在您的工作區中的某處建立 globals.d.ts 檔案

interface Window {
  webkitNotifications: any;
}

declare var CAN_NOTIFY: number;

d.ts 檔案是類型宣告。在此範例中,globals.d.ts 讓 TypeScript 知道存在全域 CAN_NOTIFY,並且 window 上存在 webkitNotifications 屬性。您可以閱讀更多關於在 TypeScript 文件中撰寫 d.ts 的資訊。d.ts 檔案不會變更 JavaScript 的評估方式,它們僅用於提供更好的 JavaScript 語言支援。

使用工作

使用 TypeScript 編譯器

TypeScript 的主要功能之一是能夠使用最新的 JavaScript 語言功能,並發出可以在尚不了解這些較新功能的 JavaScript 執行階段中執行的程式碼。由於 JavaScript 使用相同的語言服務,因此它現在也可以利用此相同功能。

TypeScript 編譯器 tsc 可以將 JavaScript 檔案從 ES6 向下層級編譯到另一個語言層級。使用所需的選項設定 jsconfig.json,然後使用 –p 引數讓 tsc 使用您的 jsconfig.json 檔案,例如 tsc -p jsconfig.json 以進行向下層級編譯。

閱讀更多關於 jsconfig 文件中向下層級編譯的編譯器選項。

執行 Babel

Babel 轉譯器將 ES6 檔案轉換為具有原始碼對應的可讀 ES5 JavaScript。您可以透過將以下設定新增至您的 tasks.json 檔案 (位於工作區的 .vscode 資料夾下),輕鬆將 Babel 整合到您的工作流程中。group 設定使此工作成為預設的工作:執行建置工作手勢。isBackground 告知 VS Code 讓此工作在背景中持續執行。若要深入瞭解,請前往 工作

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "watch",
      "command": "${workspaceFolder}/node_modules/.bin/babel",
      "args": ["src", "--out-dir", "lib", "-w", "--source-maps"],
      "type": "shell",
      "group": { "kind": "build", "isDefault": true },
      "isBackground": true
    }
  ]
}

新增此設定後,您可以使用 ⇧⌘B (Windows、Linux Ctrl+Shift+B) (執行建置工作) 命令啟動 Babel,它會將 src 目錄中的所有檔案編譯到 lib 目錄中。

提示: 如需 Babel CLI 的說明,請參閱 使用 Babel 中的指示。上面的範例使用 CLI 選項。

停用 JavaScript 支援

如果您偏好使用其他 JavaScript 語言工具 (例如 Flow) 支援的 JavaScript 語言功能,您可以停用 VS Code 的內建 JavaScript 支援。您可以透過停用內建的 TypeScript 語言擴充功能TypeScript 和 JavaScript 語言功能 (vscode.typescript-language-features) 來執行此操作,該擴充功能也提供 JavaScript 語言支援。

若要停用 JavaScript/TypeScript 支援,請前往擴充功能檢視 (⇧⌘X (Windows、Linux Ctrl+Shift+X)) 並篩選內建擴充功能 (在 ... 更多動作下拉式清單中顯示內建擴充功能),然後輸入 'typescript'。選取 TypeScript 和 JavaScript 語言功能擴充功能,然後按下停用按鈕。VS Code 內建擴充功能無法解除安裝,只能停用,並且可以隨時重新啟用。

TypeScript and JavaScript Language Features extension

部分 IntelliSense 模式

VS Code 嘗試為 JavaScript 和 TypeScript 提供專案範圍的 IntelliSense,這使得自動匯入和前往定義等功能成為可能。但是,在某些情況下,VS Code 僅限於處理您目前開啟的檔案,並且無法載入組成 JavaScript 或 TypeScript 專案的其他檔案。

在以下幾種情況下可能會發生這種情況

  • 您正在 vscode.dev 或 github.dev 上使用 JavaScript 或 TypeScript 程式碼,而 VS Code 正在瀏覽器中執行。
  • 您從虛擬檔案系統開啟檔案 (例如,當使用 GitHub Repositories 擴充功能時)。
  • 專案目前正在載入中。載入完成後,您將開始取得專案範圍的 IntelliSense。

在這些情況下,VS Code 的 IntelliSense 將在部分模式下運作。部分模式會盡力為您開啟的任何 JavaScript 或 TypeScript 檔案提供 IntelliSense,但受到限制,並且無法提供任何跨檔案 IntelliSense 功能。

哪些功能受到影響?

以下是不完整的功能清單,這些功能在部分模式下會停用或功能更有限

  • 所有開啟的檔案都視為單一專案的一部分。
  • 不遵守來自您的 jsconfigtsconfig 的設定選項 (例如 target)。
  • 僅報告語法錯誤。語意錯誤 (例如存取未知的屬性或將錯誤的類型傳遞給函式) 不會報告。
  • 語意錯誤的快速修復已停用。
  • 符號只能在目前檔案中解析。從其他檔案匯入的任何符號都將被視為 any 類型。
  • 前往定義尋找所有參考等命令僅適用於開啟的檔案,而不是整個專案。這也表示來自您在 node_module 下安裝的任何套件的符號將不會被解析。
  • 工作區符號搜尋僅包含來自目前開啟檔案的符號。
  • 自動匯入已停用。
  • 重新命名已停用。
  • 許多重構已停用。

某些其他功能在 vscode.devgithub.dev 上已停用

檢查您是否處於部分模式

若要檢查目前檔案是否正在使用部分模式 IntelliSense 而不是專案範圍的 IntelliSense,請將滑鼠游標停留在狀態列中的 JavaScriptTypeScript 語言狀態項目上方

Partial mode status item

如果目前檔案處於部分模式,狀態項目將顯示 部分模式