现已推出!阅读 10 月份的新功能和修复。

使用 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 窗口还为文件中的符号提供基本单词补全。

类型和自动类型获取

JavaScript 库和框架的 IntelliSense 由 TypeScript 类型声明(类型)文件提供支持。类型声明文件是用 TypeScript 编写的,因此它们可以表达参数和函数的数据类型,从而使 VS Code 能够以高性能的方式提供丰富的 IntelliSense 体验。

许多流行的库都附带类型文件,因此您可以自动获得它们的 IntelliSense。对于不包含类型的库,VS Code 的 自动类型获取 将自动为您安装社区维护的类型文件。

自动类型获取需要 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 包管理器)来安装和管理类型声明(类型)文件。要确保自动类型获取正常工作,首先确保您的机器上安装了 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 targetES6,并且 exclude 属性排除了 node_modules 文件夹。您可以将此代码复制粘贴到您的 jsconfig.json 文件中。

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

exclude 属性告诉语言服务哪些文件不是您源代码的一部分。如果 IntelliSense 速度很慢,请将文件夹添加到 exclude 列表中(如果 VS Code 检测到缓慢的代码补全,它会提示您执行此操作)。您可能希望将构建过程生成的文件(例如 dist 目录)exclude 掉。这些文件会导致建议出现两次,并会降低 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 可以像在 .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.jsontsconfig.json 项目一部分的 JavaScript 文件启用类型检查。

您可以使用文件顶部的 // @ts-nocheck 注释选择将单个文件排除在类型检查之外。

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

您还可以使用 JavaScript 文件中错误行之前的 // @ts-ignore 注释禁用单个错误。

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.devgithub.dev 上使用 JavaScript 或 TypeScript 代码,并且 VS Code 正在浏览器中运行。
  • 您从虚拟文件系统(例如使用 GitHub 存储库 扩展时)打开一个文件。
  • 项目当前正在加载。加载完成后,您将开始为它获得项目范围的 IntelliSense。

在这些情况下,VS Code 的 IntelliSense 将以部分模式运行。部分模式尽力为您打开的任何 JavaScript 或 TypeScript 文件提供 IntelliSense,但功能有限,无法提供任何跨文件 IntelliSense 功能。

哪些功能受到影响?

以下是部分模式下被禁用或功能有限的功能的不完整列表

  • 所有打开的文件都被视为单个项目的一部分。
  • 您的 jsconfigtsconfig 中的配置选项(例如 target)不会被尊重。
  • 仅报告语法错误。 语义错误(例如访问未知属性或向函数传递错误类型)不会报告。
  • 语义错误的快速修复已禁用。
  • 符号只能在当前文件中解析。 从其他文件导入的任何符号都将被视为 any 类型。
  • 转到定义查找所有引用等命令将仅适用于打开的文件,而不是整个项目。 这也意味着您在 node_module 下安装的任何包中的符号将无法解析。
  • 工作区符号搜索将仅包括当前打开文件中的符号。
  • 自动导入已禁用。
  • 重命名已禁用。
  • 许多重构已禁用。

vscode.devgithub.dev 上的一些附加功能已禁用

检查您是否处于部分模式

要检查当前文件是否使用部分模式 IntelliSense 而不是项目范围的 IntelliSense,请将鼠标悬停在状态栏中的 JavaScriptTypeScript 语言状态项上

Partial mode status item

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