【问题标题】:How VSCode injects "vscode" engine into the extensions?VSCode 如何将“vscode”引擎注入到扩展中?
【发布时间】:2018-01-17 11:35:23
【问题描述】:

在为 VSCode 开发扩展时。我们看到了这个导入:

import * as vscode from 'vscode';

package.json,我们有

"engines": {
  "vscode": "*"
}

在我们的依赖项中没有“vscode”。但是,看起来它可以用于扩展。任何解释将不胜感激。

【问题讨论】:

    标签: javascript visual-studio-code vscode-extensions


    【解决方案1】:

    导入由宿主环境解析,在本例中是 VSCode 可能修改过的 Electron 版本。因此,当它看到对 vscode 模块的请求时,它会(内部)提供它,而不是寻找外部依赖项。

    FWIW,一个事实上的标准正在出现,“原始”模块名称,如'vscode',往往由主机环境直接提供,而带有路径('./foo')的模块名称是外部的。 (这就是为什么script type="module" 标签上的src 需要有路径,至少现在是这样。)

    【讨论】:

    • 谢谢!所以,我发现了这个:github.com/Microsoft/vscode-loader 你觉得他们在用这个吗?
    • 完全有可能,VSCode 是开源的……但我也不知道。
    【解决方案2】:

    package.json 中的“引擎”部分与模块导入系统无关。
    npm install时,一些原生模块知道如何编译。
    并且可以检查引擎版本。 eg:你可以设置engines: {node: >=8},然后node v7会拒绝运行你的代码,但这不是强制的。

    VS Code 使用vscode-loader 作为模块加载器,它很像require.js,但对于vscode 还有很多其他功能。
    您调用的“全局”函数“require”被 vscode-loader 覆盖,而不是节点的本机“require”。
    与任何其他模块加载器系统相同,vscode-loader 允许您修改“require”函数。

    vscode 变化如此之快,你可以用nodeRequire('module') 做一个简单的搜索。

    目前,相关代码在src/vs/workbench/api/node/extHost.api.impl.ts文件中:

    const node_module = <any>require.__$__nodeRequire('module');
    const original = node_module._load;
    node_module._load = function load(request: string, parent: any, isMain: any) {
        if (request !== 'vscode') {
            return original.apply(this, arguments);
        }
        .....
        .....
        // and finally, return apiImpl, the "vscode" object
    }
    

    require() 将调用 module._load(),但是这个 module._load 已经被 vscode-loader 覆盖了。
    您也可以像这样再次覆盖它。
    那就是“猴子补丁”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-09
      • 1970-01-01
      • 1970-01-01
      • 2018-04-17
      • 1970-01-01
      相关资源
      最近更新 更多