在 VSCode 扩展中找不到命令

Posted

技术标签:

【中文标题】在 VSCode 扩展中找不到命令【英文标题】:Command not found in VSCode extension 【发布时间】:2018-09-07 02:42:35 【问题描述】:

我正在尝试创建一个 VSCode 扩展。这个扩展提供了两个命令,别管它们的实现:

export function activate(context: ExtensionContext) 

    const provider = new ContentProvider();
    const providerRegistrations = Disposable.from(
        workspace.registerTextDocumentContentProvider(ContentProvider.scheme, provider)
    );

    // Open the dynamic document, and shows it in the next editor
    const openMyExtensionCommandRegistration = commands.registerTextEditorCommand('extension.openMyExtension', editor => 
        // Activate the extension and do something
    );

    const useMyExtensionCommandRegistration = commands.registerTextEditorCommand('extension.useMyExtension', editor => 
        // Do something
    );

    context.subscriptions.push(
        provider,
        openMyExtensionCommandRegistration,
        useMyExtensionCommandRegistration,
        providerRegistrations
    );

这是我的package.json 文件的一部分:

"activationEvents": [
        "onCommand:extension.openMyExtension"
    ],
    "main": "./out/extension",
    "contributes": 
        "commands": [
            
                "command": "extension.openMyExtension",
                "title": "Open my extension",
                "category": "MyExtension"
            ,
            
                "command": "extension.useMyExtension",
                "title": "Do something with my extension",
                "category": "MyExtension"
            
        ],

应该激活我的扩展的第一个命令有效。它出现在命令面板中,并在调用时实际执行它应该执行的操作。

然而,第二个命令尽管出现在命令面板中,但在调用时会引发以下错误消息:

command 'extension.useMyExtension' not found

我觉得很奇怪,我的第一个命令可以正常工作,但第二个命令却不行,因为代码非常相似。任何想法为什么?

请注意,我显然更改了一些变量名,我仔细检查了真实代码中的拼写错误。

【问题讨论】:

registerTextEditorCommand 更改为registerCommand 时是否检查过它是否有效?我只是对此感到好奇。你的代码在我看来也不错。 我仍在调查究竟是什么导致了这个问题,但总而言之,应该将 TypeScript 编译成 javascript 的命令在我的机器上不起作用。我通过查看 JavaScript 生成的源代码发现了这一点。 您可以尝试为每个命令创建两个不同的扩展,看看是否可行?如果单个扩展中的多个命令没有引起任何问题,这将给出一个想法。 我可以通过手动编译 Typescript 源代码(通过在我的根文件夹中运行 tsc -p ./)来解决这个问题。调试时应该自动运行此命令,但是我仍然无法找到为什么在我的机器上不是这样。 @Eldy 我刚刚遇到了完全相同的问题(我的 extension.ts 文件在按下 F5 时没有被重建)并且我看到了一个错误,即找不到新注册的命令。运行tsc -p ./ 也为我解决了这个问题!感谢您分享您的解决方案。 【参考方案1】:

您的问题与此问题类似:https://github.com/Microsoft/vscode/issues/25026

【讨论】:

【参考方案2】:

由于我的评论对某人有所帮助,因此我想将其发布为答案以使其更具知名度:

我可以通过手动编译 Typescript 源(通过在我的根文件夹中运行 tsc -p ./)来解决这个问题。调试时应该自动运行此命令,但是我仍然无法找到为什么在我的机器上不是这样。

【讨论】:

这对我有用,但是要从 vs-code 编译/调试,解决方案是使用 npm config set ignore-scripts false 启用 npm 脚本【参考方案3】:

您需要将所有已注册的命令添加到 package.json 中的 activationEvents 列表中,以便它们在调用时可用。像这样更新你的 package.json:


    ...
    "activationEvents": [
        "onCommand:extension.openMyExtension",
        "onCommand:extension.useMyExtension"
    ]
    ...

您可以在官方VSCode Documentation找到更多关于激活事件的详细信息。

【讨论】:

【参考方案4】:

我遇到了同样的问题。一切都配置正确,但结果是我的 package.json 缺少一个依赖项。这导致扩展加载失败,因此在运行时未正确注册命令。

要找出您的代码有什么问题,请打开帮助 > 切换开发人员工具并在控制台中查找错误。

【讨论】:

开发者工具让我上路了。谢谢! 我在控制台中看不到任何错误,并且我遇到了相同的问题命令未注册,扩展在调试时工作正常,但在发布时不工作 唯一对我有用的解决方案。【参考方案5】:

我的问题是我将 Cmder 作为我的 VS Code 终端运行。当我开始调试时,构建永远不会完成 - 您可以从底部工具栏监视正在运行的任务。当我查看正在运行的任务时,我看到了:

执行任务:npm run watch

VS Code 正在尝试运行监视脚本,但它从未完成 - 我猜这里存在一些语法问题。

无论如何,虽然编译确实有效,但我建议改为运行 watch 脚本,以便您的扩展在每次文件更改时重新编译:

npm run watch

您现在应该可以通过F5 在您的扩展主机中运行您的扩展,而无需不断地重新编译。 (不过,您仍然需要重新加载主机)

【讨论】:

【参考方案6】:

我正在为任何可能出于与我相同的原因而遇到此行为的人添加此答案,因为我花了很长时间才意识到发生了什么。

我使用 PowerShell 作为我的默认终端,并将我的配置文件配置为将新 shell 的路径(使用 Set-Location)设置为特定文件夹,以便于我正在进行的其他开发工作。

当按下 F5 启动我的扩展时,VS Code 试图从这个目录而不是我的项目目录运行编译命令,这当然失败了。

一旦我意识到要查看 C:\Users\\AppData\Roaming\npm-cache\_logs 文件,这个失败就很明显了。

我从我的 PowerShell 配置文件中删除了路径设置,并且 VS Code 扩展构建按预期工作。

【讨论】:

【参考方案7】:

您尚未激活扩展程序:

"activationEvents": [
    "onCommand:extension. useMyExtension"
],

【讨论】:

【参考方案8】:

万一有人犯了和我一样的错误……

所以如果编译成功,但是提示找不到命令,请检查:

    在扩展调试窗口中,检查来自Help > Toggle Developer Tools(来自@Bart Theeten)的控制台日志。您没有注意到的 JS 错误的可能性很高。

    是否所有命令都添加到package.json

"contributes": 
    "commands": [ ... ]

    命令是否注册
context.subscriptions.push(
    vscode.commands.registerCommand('command_name', callbackFunc)
);
    最后,检查生产包设置

我的扩展是用 Typescript 制作的,并由 Webpack + ts-loader 捆绑。我介绍了一个有趣的条件加载模块功能,它需要来自动态路径(如/module/<version>)的模块。这会产生几个有趣的问题:

首先是错误的__dirname__filename 全局变量,仅在使用 webpack 打包 NodeJS 应用程序时才会发生(我得到了 /__dirname 值)。我必须将webpack.config.js 设置为:

module.exports = 
  node: false

禁用 webpack nodeJS 全局模拟。 (reference)

其次,我们容易忘记的模块路径限制:

绝对路径导入可能不起作用,相对路径也不能超出您在某处设置的范围??‍♀️。示例:

// tsconfig.json

  "compilerOptions": 
    "outDir": "lib"
  ,
  "include": ["src"]

// src/index.ts
require('../external/test')

require 路径将被 ts-loader 和 webpack 处理,它无法识别这个模块路径,除非你使用路径别名告诉它们这些文件的位置。

并且动态导入路径不能是动态的编译后

require(`./$dir/module`) // may not work
import(`./$dir/module`)  // may not work

好吧,原因是编译器加载器可能会对路径进行一些处理,如果它是一个简单的静态字符串,它可以用正确的字符串替换它,但如果它是一个运行时值,它就不能。对不起,我很容易忘记这一点,因为它是一种函数语法!

你知道更糟糕的是什么吗?更糟糕的情况是我得到了对我有用但对其他人无效的路径。因为 hack 引入了只存在于我的环境中的绝对路径……所以,我不得不说尽量避免使用绝对路径。

【讨论】:

【参考方案9】:

我使用vsce package 构建了我的扩展,并通过 vsix 文件安装了它。

我遇到了同样的问题,并通过在“.vscode/extensions/EXTENSION_NAME”文件夹中运行 npm install 来修复它。 EXTENSION_NAME 是扩展名。

我在a github issue找到了解决方案

【讨论】:

对我不起作用。此外,请注意,.vscode/extensions/EXTENSION_NAME 不是项目工作区中的目录,而是全局 vscode 扩展目录。在 Linux 上是 ~/.vscode/extensions/EXTENSION_NAME 为什么不像他们在问题中推荐的那样,在你的包中包含node_modules

以上是关于在 VSCode 扩展中找不到命令的主要内容,如果未能解决你的问题,请参考以下文章

打字稿在vscode中找不到名称'test'

Linux系统中找不到Vscode中code命令的解决办法

Linux系统中找不到Vscode中code命令的解决办法

在 VScode 中找不到 @angular/fire/firestore 模块错误

laravel 在 php 5.5 中找不到 mcrypt 扩展

在 Visual Studio Code 中找不到 Flutter Inspector / Toggle Debug Paint