使用 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 的 Automatic Type Acquisition(自动类型获取)将自动为你安装社群维护的类型定义文件。
自动类型获取需要用到 npmjs(Node.js 包管理器),它包含在 Node.js 运行时中。在此图中,你可以看到针对流行 lodash 库的 IntelliSense,包括方法签名、参数信息和方法文档。

对于项目中 package.json 中列出的包或者你导入到 JavaScript 文件中的包,Visual Studio Code 会自动下载和管理其类型声明文件。
{
"dependencies": {
"lodash": "^4.17.0"
}
}
或者,你也可以在 jsconfig.json 中显式列出要为其获取类型声明文件的包。
{
"typeAcquisition": {
"include": ["jquery"]
}
}
大多数常见的 JavaScript 库都自带声明文件,或者提供有可用的类型声明文件。
修复自动类型获取的“未安装 npm”警告
自动类型获取使用 Node.js 包管理器 npm 来安装和管理类型声明(typings)文件。为确保自动类型获取正常工作,请首先确保你的机器上已安装 npm。
从终端或命令提示符运行 npm --version,以快速检查 npm 是否已安装且可用。
npm 随 Node.js 运行时一起安装,可从 Nodejs.org 下载。安装当前的 LTS(长期支持)版本,npm 可执行文件将默认添加到你的系统路径中。
如果你已安装 npm 但仍看到警告消息,可以通过 js/ts.tsserver.npm.path 设置显式告知 VS Code npm 的安装位置。应将其设置为机器上 npm 可执行文件的完整路径,并且它不必与你用于管理工作区中包的 npm 版本相匹配。js/ts.tsserver.npm.path 需要 TypeScript 2.3.4+。
例如,在 Windows 上,你可以将类似这样的路径添加到你的 settings.json 文件中
{
"js/ts.tsserver.npm.path": "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 启用了一些令人兴奋的快速修复(Quick Fixes),包括添加缺少的导入和添加缺少的属性。

TypeScript 可以像在 .ts 文件中一样推断 .js 文件中的类型。当无法推断类型时,可以使用 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 用于上述代码,你会看到许多关于使用全局变量的错误
Line 2-Property 'webkitNotifications' does not exist on type 'Window'.Line 2-Cannot find name 'CAN_NOTIFY'.Line 3-Property 'webkitNotifications' does not exist on type 'Window'.
如果你想继续使用 // @ts-check 但确信这些并不是应用程序的实际问题,则必须让 TypeScript 了解这些全局变量。
{
"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 文件转换为带有 Source Maps 的可读 ES5 JavaScript。通过将以下配置添加到你的 tasks.json 文件(位于工作区的 .vscode 文件夹下),你可以轻松地将 Babel 集成到你的工作流中。group 设置使此任务成为默认的 Task: Run Build Task 手势。isBackground 告诉 VS Code 在后台继续运行此任务。要了解更多信息,请转到任务 (Tasks)。
{
"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) (Run Build Task) 命令启动 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_module下安装的任何包中的符号将无法解析。 - 工作区符号搜索将仅包含当前打开的文件中的符号。
- 自动导入已被禁用。
- 重命名已被禁用。
- 许多重构功能已被禁用。
在 vscode.dev 和 github.dev 上还禁用了一些其他功能
- 当前不支持自动类型获取。
检查你是否处于部分模式
要检查当前文件使用的是部分模式 IntelliSense 还是整个项目范围的 IntelliSense,请将鼠标悬停在状态栏中的 JavaScript 或 TypeScript 语言状态项上

如果当前文件处于部分模式,状态项将显示 Partial mode。