1
votes

When developing extensions for VSCode. We see this import:

import * as vscode from 'vscode';

and in package.json, we have

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

Nowhere in the dependencies we have 'vscode'. But, looks like it is available for extension. Any explanation would be appreciated.

2

2 Answers

2
votes

Imports are resolved by the host environment, in this case VSCode's possibly-modified version of Electron. So when it sees a request for the vscode module, it provides it (internally) rather than looking for an external dependency.

FWIW, a defacto standard is emerging that "raw" module names, like 'vscode', tend to be provided directly by the host environment whereas ones with paths ('./foo') are external. (That's why the src on script type="module" tags is required to have a path, at least for now.)

1
votes

The "engines" section in package.json is not related with module import system.
It's for some native module to know howto compile when npm install.
And can check engine version. eg: you can set engines: {node: >=8}, then node v7 will deny to run your code, but that's not enforce.

VS Code is using vscode-loader as module loader, it's very like require.js, but has many other function for vscode.
The "global" function "require" you called, is override by vscode-loader, not node's native "require".
Same with any other module loader system, vscode-loader allows you to modify the "require" function.

vscode is changing so fast, you can do a simple search with nodeRequire('module').

Currentlly, related code is in src/vs/workbench/api/node/extHost.api.impl.ts file:

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() will call module._load(), but this module._load is already overrided by vscode-loader.
You can also override it again like this.
That is called "Monkey Patch".