使用 JavaScript
本主題介紹 Visual Studio Code 支援的一些高階 JavaScript 功能。透過使用 TypeScript 語言服務,VS Code 可以為 JavaScript 提供智慧補全(IntelliSense)以及型別檢查。
IntelliSense
Visual Studio Code 的 JavaScript IntelliSense 提供了智慧程式碼補全、引數資訊、引用搜索以及許多其他高階語言功能。我們的 JavaScript IntelliSense 由 TypeScript 團隊開發的 JavaScript 語言服務 提供支援。雖然對於大多數 JavaScript 專案來說,IntelliSense 無需任何配置即可正常工作,但您可以透過 JSDoc 或配置 jsconfig.json
專案檔案,讓 IntelliSense 變得更加有用。
有關 JavaScript IntelliSense 工作原理的詳細資訊,包括基於型別推斷、JSDoc 註釋、TypeScript 宣告以及混合使用 JavaScript 和 TypeScript 專案,請參閱 JavaScript 語言服務文件。
當型別推斷無法提供所需資訊時,可以使用 JSDoc 註釋明確提供型別資訊。本文件介紹了當前支援的 JSDoc 註釋。
除了物件、方法和屬性外,JavaScript IntelliSense 視窗還為您檔案中的符號提供基本的單詞補全。
型別定義與自動型別獲取
對 JavaScript 庫和框架的 IntelliSense 功能是由 TypeScript 型別宣告(typings)檔案提供支援的。型別宣告檔案是用 TypeScript 編寫的,因此它們可以表示引數和函式的資料型別,從而讓 VS Code 能夠以高效能的方式提供豐富的 IntelliSense 體驗。
許多流行的庫都附帶了型別定義檔案,因此您可以自動獲得它們的 IntelliSense。對於不包含型別定義的庫,VS Code 的“自動型別獲取”功能將自動為您安裝社群維護的型別定義檔案。
自動型別獲取需要 npmjs(Node.js 包管理器),它包含在 Node.js 執行時中。在這張圖中,您可以看到 IntelliSense,包括流行庫 lodash 的方法簽名、引數資訊和方法文件。
對於專案中 package.json
列出的包,或您匯入到 JavaScript 檔案中的包,Visual Studio Code 會自動下載和管理其型別宣告檔案。
{
"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.json
檔案。您需要這樣做,以防止一個專案中的原始碼出現在另一個專案的 IntelliSense 中。
下圖展示了一個包含 client
和 server
資料夾的專案,顯示了兩個獨立的 JavaScript 專案:
編寫 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/**/*"]
}
最佳實踐且最不容易出錯的方法是,使用帶單個 src
資料夾的 include
屬性。請注意,exclude
和 include
中的檔案路徑是相對於 jsconfig.json
的位置。
更多資訊,請參閱完整的 jsconfig.json 文件。
遷移到 TypeScript
可以同時擁有 TypeScript 和 JavaScript 混合專案。要開始遷移到 TypeScript,請將您的 jsconfig.json
檔案重新命名為 tsconfig.json
,並將 allowJs
屬性設定為 true
。更多資訊,請參閱從 JavaScript 遷移。
注意:
jsconfig.json
與tsconfig.json
檔案相同,只是將allowJs
設定為 true。請參閱此處的tsconfig.json
文件以檢視其他可用選項。
對 JavaScript 進行型別檢查
VS Code 允許您在常規 JavaScript 檔案中利用 TypeScript 的一些高階型別檢查和錯誤報告功能。這是捕獲常見程式設計錯誤的好方法。這些型別檢查還為 JavaScript 啟用了一些令人興奮的快速修復功能,包括**新增缺失的匯入**和**新增缺失的屬性**。
TypeScript 可以在 .js
檔案中推斷型別,就像在 .ts
檔案中一樣。當無法推斷型別時,可以使用 JSDoc 註釋來指定它們。您可以在檢查 JavaScript 檔案型別中閱讀更多關於 TypeScript 如何使用 JSDoc 進行 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.json
或 tsconfig.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.json
或 tsconfig.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: Select TypeScript Version** 命令進行檢查。您必須在編輯器中開啟一個 .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
,您會看到一些關於使用全域性變數的錯誤:
第 2 行
-屬性 'webkitNotifications' 不存在於型別 'Window' 上。
第 2 行
-找不到名稱 'CAN_NOTIFY'。
第 3 行
-屬性 'webkitNotifications' 不存在於型別 'Window' 上。
如果您想繼續使用 // @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。您可以輕鬆地將 Babel 整合到您的工作流程中,方法是將以下配置新增到您的 tasks.json
檔案(位於工作區的 .vscode
資料夾下)。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 and JavaScript Language Features** (vscode.typescript-language-features) 來實現,該擴充套件也提供 JavaScript 語言支援。
要停用 JavaScript/TypeScript 支援,請轉到擴充套件檢視(⇧⌘X (Windows, Linux Ctrl+Shift+X)),篩選內建擴充套件(在 **...** **更多操作**下拉選單中選擇**顯示內建擴充套件**),然後輸入 'typescript'。選擇 **TypeScript and JavaScript Language Features** 擴充套件並按**停用**按鈕。VS Code 內建擴充套件無法解除安裝,只能停用,並且可以隨時重新啟用。
部分 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 功能。
哪些功能會受到影響?
以下是在部分模式下被停用或功能受限的不完整功能列表:
- 所有開啟的檔案都被視為單個專案的一部分。
- 您的
jsconfig
或tsconfig
中的配置選項(如target
)將不被遵循。 - 只報告語法錯誤。語義錯誤——例如訪問未知屬性或向函式傳遞錯誤型別——不會被報告。
- 針對語義錯誤的快速修復被停用。
- 符號只能在當前檔案中解析。從其他檔案匯入的任何符號都將被視為
any
型別。 - 諸如**轉到定義**和**查詢所有引用**等命令將僅在開啟的檔案中工作,而不是在整個專案中。這也意味著您在
node_modules
下安裝的任何包中的符號將無法解析。 - 工作區符號搜尋將只包括當前開啟檔案中的符號。
- 自動匯入被停用。
- 重新命名被停用。
- 許多重構功能被停用。
在 vscode.dev
和 github.dev
上還停用了其他一些功能:
- 目前不支援自動型別獲取。
檢查您是否處於部分模式
要檢查當前檔案是使用部分模式 IntelliSense 還是專案範圍 IntelliSense,請將滑鼠懸停在狀態列中的 JavaScript
或 TypeScript
語言狀態項上:
如果當前檔案處於部分模式,狀態項將顯示“部分模式”。