VSCode如何注入" vscode"引擎进入扩展?

时间:2018-01-17 11:35:23

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

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

import * as vscode from 'vscode';

并且在package.json中,我们有

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

我们拥有的依赖项中没有任何地方' vscode'。但是,看起来它可用于扩展。任何解释都将不胜感激。

2 个答案:

答案 0 :(得分:2)

导入由主机环境解决,在这种情况下是VSCode可能修改的Electron版本。因此,当它看到vscode模块的请求时,它(内部)提供它而不是寻找外部依赖。

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

答案 1 :(得分:0)

package.json中的“引擎”部分与模块导入系统无关。
这是某个本机模块知道npm install时如何编译的方法。
并可以检查引擎版本。例如:您可以设置engines: {node: >=8},则节点v7将拒绝运行您的代码,但这不是强制性的。

VS Code使用vscode-loader作为模块加载器,非常类似于require.js,但是vscode具有许多其他功能。
vscode-loader会覆盖您调用的“全局”函数“ require”,而不是节点的本机“ 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覆盖。
您也可以像这样再次覆盖它。
这就是“猴子补丁”