Move client-side extension code out of patch

This commit is contained in:
Asher 2019-10-23 13:12:11 -05:00
parent f1b38e4e48
commit eea9c1618c
No known key found for this signature in database
GPG Key ID: D63C1EF81242354A
3 changed files with 69 additions and 47 deletions

View File

@ -174,14 +174,14 @@ Our changes include:
- Allow multiple extension directories (both user and built-in). - Allow multiple extension directories (both user and built-in).
- Modify the loader, websocket, webview, service worker, and asset requests to - Modify the loader, websocket, webview, service worker, and asset requests to
use the URL of the page as a base (and TLS if necessary for the websocket). use the URL of the page as a base (and TLS if necessary for the websocket).
- Send client-side telemetry through the server and get the initial log level - Send client-side telemetry through the server.
from the server. - Add an upload service along with a file prefix to ignore for temporary files
- Add an upload service for use in editor windows and the explorer along with a created during upload.
file prefix to ignore for temporary files created during upload.
- Make changing the display language work. - Make changing the display language work.
- Make hiding or toggling the menu bar possible.
- Make it possible for us to load code on the client. - Make it possible for us to load code on the client.
- Modify the build process to include our code. - Make extensions work in the browser.
- Fix getting permanently disconnected when you sleep or hibernate for a while.
- Make it possible to automatically update the binary.
## License ## License

View File

@ -510,62 +510,27 @@ index 49a8e254fd..99d233aed5 100644
throw new Error(`Cannot load URI: '${module}', must be of file-scheme`); throw new Error(`Cannot load URI: '${module}', must be of file-scheme`);
} }
diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts
index afd82468c0..67d938e9ab 100644 index afd82468c0..289145be54 100644
--- a/src/vs/workbench/api/worker/extHostExtensionService.ts --- a/src/vs/workbench/api/worker/extHostExtensionService.ts
+++ b/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts
@@ -9,6 +9,10 @@ import { AbstractExtHostExtensionService } from 'vs/workbench/api/common/extHost @@ -9,6 +9,9 @@ import { AbstractExtHostExtensionService } from 'vs/workbench/api/common/extHost
import { endsWith } from 'vs/base/common/strings'; import { endsWith } from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterceptor'; import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterceptor';
+import { joinPath } from 'vs/base/common/resources'; +import { joinPath } from 'vs/base/common/resources';
+import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
+import { fromTar } from 'vs/server/node_modules/@coder/requirefs/out/requirefs'; +import { loadCommonJSModule } from 'vs/server/src/browser/worker';
+import { Client } from 'vs/server/node_modules/@coder/node-browser/out/client/client';
class WorkerRequireInterceptor extends RequireInterceptor { class WorkerRequireInterceptor extends RequireInterceptor {
@@ -41,7 +45,48 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { @@ -41,7 +44,14 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService {
await this._fakeModules.install(); await this._fakeModules.install();
} }
- protected async _loadCommonJSModule<T>(module: URI, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<T> { - protected async _loadCommonJSModule<T>(module: URI, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<T> {
+ protected async _loadCommonJSModule<T>(module: URI | IExtensionDescription, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<T> { + protected async _loadCommonJSModule<T>(module: URI | IExtensionDescription, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<T> {
+ if (!URI.isUri(module) && module.extensionKind !== 'web') { + if (!URI.isUri(module) && module.extensionKind !== 'web') {
+ const fetchUri = URI.from({ + return loadCommonJSModule(module, activationTimesBuilder, this._nodeProxy, this._logService, this._fakeModules.getModule('vscode', module.extensionLocation));
+ scheme: self.location.protocol.replace(':', ''),
+ authority: self.location.host,
+ path: `${self.location.pathname.replace(/\/static.*\/out\/vs\/workbench\/services\/extensions\/worker\/extensionHostWorkerMain.js$/, '')}/tar`,
+ query: `path=${encodeURIComponent(module.extensionLocation.path)}`,
+ });
+ const response = await fetch(fetchUri.toString(true));
+ if (response.status !== 200) {
+ throw new Error(`Failed to download extension '${module.extensionLocation.path}'`);
+ }
+ const client = new Client(this._nodeProxy, { logger: this._logService });
+ const init = await client.handshake();
+ const buffer = new Uint8Array(await response.arrayBuffer());
+ const rfs = fromTar(buffer);
+ (<any>self).global = self;
+ rfs.provide('vscode', this._fakeModules.getModule('vscode', module.extensionLocation));
+ Object.keys(client.modules).forEach((key) => {
+ const mod = (client.modules as any)[key];
+ if (key === 'process') {
+ (<any>self).process = mod;
+ (<any>self).process.env = init.env;
+ return;
+ }
+
+ rfs.provide(key, mod);
+ switch (key) {
+ case 'buffer':
+ (<any>self).Buffer = mod.Buffer;
+ break;
+ case 'timers':
+ (<any>self).setImmediate = mod.setImmediate;
+ break;
+ }
+ });
+ return rfs.require('.');
+ } + }
+ +
+ if (!URI.isUri(module)) { + if (!URI.isUri(module)) {
@ -574,7 +539,7 @@ index afd82468c0..67d938e9ab 100644
module = module.with({ path: ensureSuffix(module.path, '.js') }); module = module.with({ path: ensureSuffix(module.path, '.js') });
const response = await fetch(module.toString(true)); const response = await fetch(module.toString(true));
@@ -57,7 +102,7 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { @@ -57,7 +67,7 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService {
const _exports = {}; const _exports = {};
const _module = { exports: _exports }; const _module = { exports: _exports };
const _require = (request: string) => { const _require = (request: string) => {

57
src/browser/worker.ts Normal file
View File

@ -0,0 +1,57 @@
import { URI } from "vs/base/common/uri";
import { IExtensionDescription } from "vs/platform/extensions/common/extensions";
import { ILogService } from "vs/platform/log/common/log";
import { Client } from "vs/server/node_modules/@coder/node-browser/out/client/client";
import { fromTar } from "vs/server/node_modules/@coder/requirefs/out/requirefs";
import { ExtensionActivationTimesBuilder } from "vs/workbench/api/common/extHostExtensionActivator";
import { IExtHostNodeProxy } from "./extHostNodeProxy";
export const loadCommonJSModule = async <T>(
module: IExtensionDescription,
activationTimesBuilder: ExtensionActivationTimesBuilder,
nodeProxy: IExtHostNodeProxy,
logService: ILogService,
vscode: any,
): Promise<T> => {
const fetchUri = URI.from({
scheme: self.location.protocol.replace(":", ""),
authority: self.location.host,
path: `${self.location.pathname.replace(/\/static.*\/out\/vs\/workbench\/services\/extensions\/worker\/extensionHostWorkerMain.js$/, "")}/tar`,
query: `path=${encodeURIComponent(module.extensionLocation.path)}`,
});
const response = await fetch(fetchUri.toString(true));
if (response.status !== 200) {
throw new Error(`Failed to download extension "${module.extensionLocation.path}"`);
}
const client = new Client(nodeProxy, { logger: logService });
const init = await client.handshake();
const buffer = new Uint8Array(await response.arrayBuffer());
const rfs = fromTar(buffer);
(<any>self).global = self;
rfs.provide("vscode", vscode);
Object.keys(client.modules).forEach((key) => {
const mod = (client.modules as any)[key];
if (key === "process") {
(<any>self).process = mod;
(<any>self).process.env = init.env;
return;
}
rfs.provide(key, mod);
switch (key) {
case "buffer":
(<any>self).Buffer = mod.Buffer;
break;
case "timers":
(<any>self).setImmediate = mod.setImmediate;
break;
}
});
try {
activationTimesBuilder.codeLoadingStart();
return rfs.require(".");
} finally {
activationTimesBuilder.codeLoadingStop();
}
};