开发VSCode的扩展时。我们看到了这个导入:
import * as vscode from 'vscode';
并且在package.json
中,我们有
"engines": {
"vscode": "*"
}
我们拥有的依赖项中没有任何地方' vscode'。但是,看起来它可用于扩展。任何解释都将不胜感激。
答案 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覆盖。
您也可以像这样再次覆盖它。
这就是“猴子补丁” 。