Use electron net directly in shared process (#227553)

* Use electron net directly in shared process

* add built file

* introduce shared electron-node layer

* remove electron-utility layer

* fix (overlook): move back cli files to node
This commit is contained in:
Sandeep Somavarapu 2024-09-04 16:26:43 +02:00 committed by GitHub
parent 2aa1f2896c
commit 01fcf004a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 79 additions and 21 deletions

View File

@ -12,19 +12,19 @@ import { createImportRuleListener } from './utils';
const REPO_ROOT = path.normalize(path.join(__dirname, '../'));
interface ConditionalPattern {
when?: 'hasBrowser' | 'hasNode' | 'test';
when?: 'hasBrowser' | 'hasNode' | 'hasElectron' | 'test';
pattern: string;
}
interface RawImportPatternsConfig {
target: string;
layer?: 'common' | 'worker' | 'browser' | 'electron-sandbox' | 'node' | 'electron-main';
layer?: 'common' | 'worker' | 'browser' | 'electron-sandbox' | 'node' | 'electron-node' | 'electron-main';
test?: boolean;
restrictions: string | (string | ConditionalPattern)[];
}
interface LayerAllowRule {
when: 'hasBrowser' | 'hasNode' | 'test';
when: 'hasBrowser' | 'hasNode' | 'hasElectron' | 'test';
allow: string[];
}
@ -79,13 +79,14 @@ export = new class implements eslint.Rule.RuleModule {
return this._optionsCache.get(options)!;
}
type Layer = 'common' | 'worker' | 'browser' | 'electron-sandbox' | 'node' | 'electron-main';
type Layer = 'common' | 'worker' | 'browser' | 'electron-sandbox' | 'node' | 'electron-node' | 'electron-main';
interface ILayerRule {
layer: Layer;
deps: string;
isBrowser?: boolean;
isNode?: boolean;
isElectron?: boolean;
}
function orSegment(variants: Layer[]): string {
@ -98,11 +99,13 @@ export = new class implements eslint.Rule.RuleModule {
{ layer: 'browser', deps: orSegment(['common', 'browser']), isBrowser: true },
{ layer: 'electron-sandbox', deps: orSegment(['common', 'browser', 'electron-sandbox']), isBrowser: true },
{ layer: 'node', deps: orSegment(['common', 'node']), isNode: true },
{ layer: 'electron-main', deps: orSegment(['common', 'node', 'electron-main']), isNode: true },
{ layer: 'electron-node', deps: orSegment(['common', 'node', 'electron-node']), isNode: true, isElectron: true },
{ layer: 'electron-main', deps: orSegment(['common', 'node', 'electron-node', 'electron-main']), isNode: true, isElectron: true },
];
let browserAllow: string[] = [];
let nodeAllow: string[] = [];
let electronAllow: string[] = [];
let testAllow: string[] = [];
for (const option of options) {
if (isLayerAllowRule(option)) {
@ -110,6 +113,8 @@ export = new class implements eslint.Rule.RuleModule {
browserAllow = option.allow.slice(0);
} else if (option.when === 'hasNode') {
nodeAllow = option.allow.slice(0);
} else if (option.when === 'hasElectron') {
electronAllow = option.allow.slice(0);
} else if (option.when === 'test') {
testAllow = option.allow.slice(0);
}
@ -137,9 +142,13 @@ export = new class implements eslint.Rule.RuleModule {
restrictions.push(...nodeAllow);
}
if (layerRule.isElectron) {
restrictions.push(...electronAllow);
}
for (const rawRestriction of rawRestrictions) {
let importPattern: string;
let when: 'hasBrowser' | 'hasNode' | 'test' | undefined = undefined;
let when: 'hasBrowser' | 'hasNode' | 'hasElectron' | 'test' | undefined = undefined;
if (typeof rawRestriction === 'string') {
importPattern = rawRestriction;
} else {
@ -149,6 +158,7 @@ export = new class implements eslint.Rule.RuleModule {
if (typeof when === 'undefined'
|| (when === 'hasBrowser' && layerRule.isBrowser)
|| (when === 'hasNode' && layerRule.isNode)
|| (when === 'hasElectron' && layerRule.isElectron)
) {
restrictions.push(importPattern.replace(/\/\~$/, `/${layerRule.deps}/**`));
testRestrictions.push(importPattern.replace(/\/\~$/, `/test/${layerRule.deps}/**`));

View File

@ -92,9 +92,14 @@
"common",
"browser"
],
"electron-main": [
"electron-node": [
"common",
"node"
],
"electron-main": [
"common",
"node",
"electron-node"
]
}
],
@ -630,6 +635,7 @@
{
// imports that are allowed in all files of layers:
// - node
// - electron-node
// - electron-main
"when": "hasNode",
"allow": [
@ -648,7 +654,6 @@
"cookie",
"crypto",
"dns",
"electron",
"events",
"fs",
"fs/promises",
@ -687,6 +692,15 @@
"zlib"
]
},
{
// imports that are allowed in all files of layers:
// - electron-node
// - electron-main
"when": "hasElectron",
"allow": [
"electron"
]
},
{
// imports that are allowed in all /test/ files
"when": "test",

View File

@ -109,7 +109,7 @@ exports.code = [
createModuleDescription('vs/code/electron-main/main'),
createModuleDescription('vs/code/node/cli'),
createModuleDescription('vs/code/node/cliProcessMain', ['vs/code/node/cli']),
createModuleDescription('vs/code/node/sharedProcess/sharedProcessMain'),
createModuleDescription('vs/code/electron-node/sharedProcess/sharedProcessMain'),
createModuleDescription('vs/code/electron-sandbox/processExplorer/processExplorerMain')
];

View File

@ -78,7 +78,7 @@ const serverResourceIncludes = [
];
const serverResourceExcludes = [
'!out-build/vs/**/{electron-sandbox,electron-main}/**',
'!out-build/vs/**/{electron-sandbox,electron-main,electron-node}/**',
'!out-build/vs/editor/standalone/**',
'!out-build/vs/workbench/**/*-tb.png',
'!**/test/**'

View File

@ -87,7 +87,7 @@ const vscodeWebResources = [
...vscodeWebResourceIncludes,
// Excludes
'!out-build/vs/**/{node,electron-sandbox,electron-main}/**',
'!out-build/vs/**/{node,electron-sandbox,electron-main,electron-node}/**',
'!out-build/vs/editor/standalone/**',
'!out-build/vs/workbench/**/*-tb.png',
'!out-build/vs/code/**/*-dev.html',

View File

@ -235,6 +235,22 @@ const RULES = [
'@types/node' // no node.js
]
},
// Electron (node)
{
target: '**/vs/**/electron-node/**',
allowedTypes: [
...CORE_TYPES,
// --> types from electron.d.ts that duplicate from lib.dom.d.ts
'Event',
'Request'
],
disallowedTypes: [
'ipcMain' // not allowed, use validatedIpcMain instead
],
disallowedDefinitions: [
'lib.dom.d.ts' // no DOM
]
},
// Electron (main)
{
target: '**/vs/**/electron-main/**',

View File

@ -257,6 +257,24 @@ const RULES: IRule[] = [
]
},
// Electron (node)
{
target: '**/vs/**/electron-node/**',
allowedTypes: [
...CORE_TYPES,
// --> types from electron.d.ts that duplicate from lib.dom.d.ts
'Event',
'Request'
],
disallowedTypes: [
'ipcMain' // not allowed, use validatedIpcMain instead
],
disallowedDefinitions: [
'lib.dom.d.ts' // no DOM
]
},
// Electron (main)
{
target: '**/vs/**/electron-main/**',

View File

@ -53,7 +53,7 @@ import { ProtocolMainService } from '../../platform/protocol/electron-main/proto
import { ITunnelService } from '../../platform/tunnel/common/tunnel.js';
import { TunnelService } from '../../platform/tunnel/node/tunnelService.js';
import { IRequestService } from '../../platform/request/common/request.js';
import { RequestMainService } from '../../platform/request/electron-main/requestMainService.js';
import { RequestService } from '../../platform/request/electron-node/requestService.js';
import { ISignService } from '../../platform/sign/common/sign.js';
import { SignService } from '../../platform/sign/node/signService.js';
import { IStateReadService, IStateService } from '../../platform/state/node/state.js';
@ -211,7 +211,7 @@ class CodeMain {
services.set(ILifecycleMainService, new SyncDescriptor(LifecycleMainService, undefined, false));
// Request
services.set(IRequestService, new SyncDescriptor(RequestMainService, undefined, true));
services.set(IRequestService, new SyncDescriptor(RequestService, undefined, true));
// Themes
services.set(IThemeMainService, new SyncDescriptor(ThemeMainService));

View File

@ -102,7 +102,6 @@ import { LogService } from '../../../platform/log/common/logService.js';
import { ISharedProcessLifecycleService, SharedProcessLifecycleService } from '../../../platform/lifecycle/node/sharedProcessLifecycleService.js';
import { RemoteTunnelService } from '../../../platform/remoteTunnel/node/remoteTunnelService.js';
import { ExtensionsProfileScannerService } from '../../../platform/extensionManagement/node/extensionsProfileScannerService.js';
import { RequestChannelClient } from '../../../platform/request/common/requestIpc.js';
import { ExtensionRecommendationNotificationServiceChannelClient } from '../../../platform/extensionRecommendations/common/extensionRecommendationsIpc.js';
import { INativeHostService } from '../../../platform/native/common/native.js';
import { NativeHostService } from '../../../platform/native/common/nativeHostService.js';
@ -118,6 +117,7 @@ import { SharedProcessRawConnection, SharedProcessLifecycle } from '../../../pla
import { getOSReleaseInfo } from '../../../base/node/osReleaseInfo.js';
import { getDesktopEnvironment } from '../../../base/common/desktopEnvironmentInfo.js';
import { getCodeDisplayProtocol, getDisplayProtocol } from '../../../base/node/osDisplayProtocolInfo.js';
import { RequestService } from '../../../platform/request/electron-node/requestService.js';
class SharedProcessMain extends Disposable implements IClientConnectionFilter {
@ -270,7 +270,7 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter {
]);
// Request
const requestService = new RequestChannelClient(mainProcessService.getChannel('request'));
const requestService = new RequestService(configurationService, environmentService, logService, loggerService);
services.set(IRequestService, requestService);
// Checksum

View File

@ -12,7 +12,7 @@ function getRawRequest(options: IRequestOptions): IRawRequestFunction {
return net.request as any as IRawRequestFunction;
}
export class RequestMainService extends NodeRequestService {
export class RequestService extends NodeRequestService {
override request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> {
return super.request({ ...(options || {}), getRawRequest, isChromiumNetwork: true }, token);

View File

@ -169,7 +169,7 @@ export class SharedProcess extends Disposable {
this.utilityProcess.start({
type: 'shared-process',
entryPoint: 'vs/code/node/sharedProcess/sharedProcessMain',
entryPoint: 'vs/code/electron-node/sharedProcess/sharedProcessMain',
payload: this.createSharedProcessConfiguration(),
execArgv
});

View File

@ -111,7 +111,7 @@ function ensureIsArray(a) {
const testModules = (async function () {
const excludeGlob = '**/{node,electron-sandbox,electron-main}/**/*.test.js';
const excludeGlob = '**/{node,electron-sandbox,electron-main,electron-node}/**/*.test.js';
let isDefaultModules = true;
let promise;

View File

@ -114,7 +114,7 @@ function ensureIsArray(a) {
const testModules = (async function () {
const excludeGlob = '**/{node,electron-sandbox,electron-main}/**/*.test.js';
const excludeGlob = '**/{node,electron-sandbox,electron-main,electron-node}/**/*.test.js';
let isDefaultModules = true;
let promise;

View File

@ -56,7 +56,7 @@ Options:
const TEST_GLOB = '**/test/**/*.test.js';
const excludeGlobs = [
'**/{browser,electron-sandbox,electron-main}/**/*.test.js',
'**/{browser,electron-sandbox,electron-main,electron-node}/**/*.test.js',
'**/vs/platform/environment/test/node/nativeModules.test.js', // native modules are compiled against Electron and this test would fail with node.js
'**/vs/base/parts/storage/test/node/storage.test.js', // same as above, due to direct dependency to sqlite native module
'**/vs/workbench/contrib/testing/test/**' // flaky (https://github.com/microsoft/vscode/issues/137853)

View File

@ -58,7 +58,7 @@ Options:
const TEST_GLOB = '**/test/**/*.test.js';
const excludeGlobs = [
'**/{browser,electron-sandbox,electron-main}/**/*.test.js',
'**/{browser,electron-sandbox,electron-main,electron-node}/**/*.test.js',
'**/vs/platform/environment/test/node/nativeModules.test.js', // native modules are compiled against Electron and this test would fail with node.js
'**/vs/base/parts/storage/test/node/storage.test.js', // same as above, due to direct dependency to sqlite native module
'**/vs/workbench/contrib/testing/test/**' // flaky (https://github.com/microsoft/vscode/issues/137853)