Browse Source

build: ensure that electron/lib/browser can only use browser or common imports (#24512)

* build: ensure that electron/lib/browser can only use browser or common imports

* chore: fix linting
Samuel Attard 4 years ago
parent
commit
b02748e607

+ 6 - 1
build/webpack/webpack.config.base.js

@@ -76,6 +76,8 @@ module.exports = ({
     entry = path.resolve(electronRoot, 'lib', target, 'init.js');
   }
 
+  const electronAPIFile = path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts');
+
   return ({
     mode: 'development',
     devtool: false,
@@ -88,7 +90,10 @@ module.exports = ({
     resolve: {
       alias: {
         '@electron/internal': path.resolve(electronRoot, 'lib'),
-        electron: path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts'),
+        electron$: electronAPIFile,
+        'electron/main$': electronAPIFile,
+        'electron/renderer$': electronAPIFile,
+        'electron/common$': electronAPIFile,
         // Force timers to resolve to our dependency that doesn't use window.postMessage
         timers: path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
       },

+ 21 - 0
lib/browser/.eslintrc.json

@@ -0,0 +1,21 @@
+{
+  "rules": {
+    "no-restricted-imports": [
+      "error",
+      {
+        "paths": [
+          "electron",
+          "electron/renderer"
+        ],
+        "patterns": [
+          "./*",
+          "../*",
+          "@electron/internal/isolated_renderer/*",
+          "@electron/internal/renderer/*",
+          "@electron/internal/sandboxed_worker/*",
+          "@electron/internal/worker/*"
+        ]
+      }
+    ]
+  }
+}

+ 1 - 1
lib/browser/api/app.ts

@@ -1,7 +1,7 @@
 import * as fs from 'fs';
 import * as path from 'path';
 
-import { deprecate, Menu } from 'electron';
+import { deprecate, Menu } from 'electron/main';
 import { EventEmitter } from 'events';
 
 const bindings = process._linkedBinding('electron_browser_app');

+ 2 - 2
lib/browser/api/auto-updater/auto-updater-win.ts

@@ -1,6 +1,6 @@
-import { app } from 'electron';
+import { app } from 'electron/main';
 import { EventEmitter } from 'events';
-import * as squirrelUpdate from './squirrel-update-win';
+import * as squirrelUpdate from '@electron/internal/browser/api/auto-updater/squirrel-update-win';
 
 class AutoUpdater extends EventEmitter {
   updateAvailable: boolean = false;

+ 1 - 1
lib/browser/api/base-window.ts

@@ -1,5 +1,5 @@
 import { EventEmitter } from 'events';
-import type { BaseWindow as TLWT } from 'electron';
+import type { BaseWindow as TLWT } from 'electron/main';
 const { BaseWindow } = process._linkedBinding('electron_browser_base_window') as { BaseWindow: typeof TLWT };
 
 Object.setPrototypeOf(BaseWindow.prototype, EventEmitter.prototype);

+ 2 - 2
lib/browser/api/browser-window.ts

@@ -1,5 +1,5 @@
-import { BaseWindow, WebContents, Event, BrowserView, TouchBar } from 'electron';
-import type { BrowserWindow as BWT } from 'electron';
+import { BaseWindow, WebContents, Event, BrowserView, TouchBar } from 'electron/main';
+import type { BrowserWindow as BWT } from 'electron/main';
 const { BrowserWindow } = process._linkedBinding('electron_browser_window') as { BrowserWindow: typeof BWT };
 
 Object.setPrototypeOf(BrowserWindow.prototype, BaseWindow.prototype);

+ 1 - 1
lib/browser/api/crash-reporter.ts

@@ -1,4 +1,4 @@
-import { app, deprecate } from 'electron';
+import { app, deprecate } from 'electron/main';
 
 const binding = process._linkedBinding('electron_browser_crash_reporter');
 

+ 2 - 2
lib/browser/api/dialog.ts

@@ -1,5 +1,5 @@
-import { app, BrowserWindow } from 'electron';
-import { OpenDialogOptions, OpenDialogReturnValue, MessageBoxOptions, SaveDialogOptions, SaveDialogReturnValue, MessageBoxReturnValue, CertificateTrustDialogOptions } from 'electron/main';
+import { app, BrowserWindow } from 'electron/main';
+import type { OpenDialogOptions, OpenDialogReturnValue, MessageBoxOptions, SaveDialogOptions, SaveDialogReturnValue, MessageBoxReturnValue, CertificateTrustDialogOptions } from 'electron/main';
 const dialogBinding = process._linkedBinding('electron_browser_dialog');
 
 const DialogType = {

+ 1 - 1
lib/browser/api/menu-item-roles.ts

@@ -1,4 +1,4 @@
-import { app, BrowserWindow, WebContents, MenuItemConstructorOptions } from 'electron';
+import { app, BrowserWindow, WebContents, MenuItemConstructorOptions } from 'electron/main';
 
 const isMac = process.platform === 'darwin';
 const isWindows = process.platform === 'win32';

+ 2 - 2
lib/browser/api/menu-item.ts

@@ -1,5 +1,5 @@
-import * as roles from './menu-item-roles';
-import { Menu, Event, BrowserWindow, WebContents } from 'electron';
+import * as roles from '@electron/internal/browser/api/menu-item-roles';
+import { Menu, Event, BrowserWindow, WebContents } from 'electron/main';
 
 let nextCommandId = 0;
 

+ 2 - 2
lib/browser/api/menu.ts

@@ -1,5 +1,5 @@
-import { BaseWindow, MenuItem, webContents, Menu as MenuType, BrowserWindow, MenuItemConstructorOptions } from 'electron';
-import { sortMenuItems } from './menu-utils';
+import { BaseWindow, MenuItem, webContents, Menu as MenuType, BrowserWindow, MenuItemConstructorOptions } from 'electron/main';
+import { sortMenuItems } from '@electron/internal/browser/api/menu-utils';
 
 const v8Util = process._linkedBinding('electron_common_v8_util');
 const bindings = process._linkedBinding('electron_browser_menu');

+ 1 - 1
lib/browser/api/net-log.ts

@@ -1,6 +1,6 @@
 // TODO(deepak1556): Deprecate and remove standalone netLog module,
 // it is now a property of session module.
-import { app, session } from 'electron';
+import { app, session } from 'electron/main';
 
 const startLogging: typeof session.defaultSession.netLog.startLogging = async (path, options) => {
   if (!app.isReady()) return;

+ 2 - 2
lib/browser/api/net.ts

@@ -1,7 +1,7 @@
 import * as url from 'url';
 import { Readable, Writable } from 'stream';
-import { app } from 'electron';
-import { ClientRequestConstructorOptions, UploadProgress } from 'electron/main';
+import { app } from 'electron/main';
+import type { ClientRequestConstructorOptions, UploadProgress } from 'electron/main';
 const {
   isValidHeaderName,
   isValidHeaderValue,

+ 1 - 1
lib/browser/api/power-monitor.ts

@@ -1,5 +1,5 @@
 import { EventEmitter } from 'events';
-import { app } from 'electron';
+import { app } from 'electron/main';
 
 const {
   createPowerMonitor,

+ 1 - 1
lib/browser/api/protocol.ts

@@ -1,4 +1,4 @@
-import { app, session } from 'electron';
+import { app, session } from 'electron/main';
 
 // Global protocol APIs.
 const protocol = process._linkedBinding('electron_browser_protocol');

+ 1 - 1
lib/browser/api/screen.ts

@@ -1,6 +1,6 @@
 'use strict';
 
-import { createLazyInstance } from '../utils';
+import { createLazyInstance } from '@electron/internal/browser/utils';
 const { EventEmitter } = require('events');
 const { Screen, createScreen } = process._linkedBinding('electron_common_screen');
 

+ 1 - 1
lib/browser/api/system-preferences.ts

@@ -1,5 +1,5 @@
 import { EventEmitter } from 'events';
-import { deprecate } from 'electron';
+import { deprecate } from 'electron/main';
 const { systemPreferences, SystemPreferences } = process._linkedBinding('electron_browser_system_preferences');
 
 // SystemPreferences is an EventEmitter.

+ 1 - 1
lib/browser/api/views/image-view.ts

@@ -1,4 +1,4 @@
-import { View } from 'electron';
+import { View } from 'electron/main';
 
 const { ImageView } = process._linkedBinding('electron_browser_image_view');
 

+ 1 - 1
lib/browser/api/web-contents-view.ts

@@ -1,4 +1,4 @@
-import { View } from 'electron';
+import { View } from 'electron/main';
 
 const { WebContentsView } = process._linkedBinding('electron_browser_web_contents_view');
 

+ 14 - 14
lib/browser/api/web-contents.ts

@@ -1,14 +1,14 @@
-import { app, ipcMain, session, deprecate } from 'electron';
-import type { MenuItem, MenuItemConstructorOptions, WebContentsInternal } from 'electron';
+import { app, ipcMain, session, deprecate } from 'electron/main';
+import type { MenuItem, MenuItemConstructorOptions } from 'electron/main';
 
 import * as url from 'url';
 import * as path from 'path';
-import { internalWindowOpen } from '../guest-window-manager';
-import { NavigationController } from '../navigation-controller';
-import { ipcMainInternal } from '../ipc-main-internal';
-import * as ipcMainUtils from '../ipc-main-internal-utils';
-import { parseFeatures } from '../../common/parse-features-string';
-import { MessagePortMain } from '../message-port-main';
+import { internalWindowOpen } from '@electron/internal/browser/guest-window-manager';
+import { NavigationController } from '@electron/internal/browser/navigation-controller';
+import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
+import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils';
+import { parseFeatures } from '@electron/internal/common/parse-features-string';
+import { MessagePortMain } from '@electron/internal/browser/message-port-main';
 import { EventEmitter } from 'events';
 
 // session is not used here, the purpose is to make sure session is initalized
@@ -122,7 +122,7 @@ const defaultPrintingSetting = {
 
 // JavaScript implementations of WebContents.
 const binding = process._linkedBinding('electron_browser_web_contents');
-const { WebContents } = binding as { WebContents: { prototype: WebContentsInternal } };
+const { WebContents } = binding as { WebContents: { prototype: Electron.WebContentsInternal } };
 
 Object.setPrototypeOf(WebContents.prototype, EventEmitter.prototype);
 
@@ -203,7 +203,7 @@ for (const method of webFrameMethods) {
   };
 }
 
-const waitTillCanExecuteJavaScript = async (webContents: WebContentsInternal) => {
+const waitTillCanExecuteJavaScript = async (webContents: Electron.WebContentsInternal) => {
   if (webContents.getURL() && !webContents.isLoadingMainFrame()) return;
 
   return new Promise((resolve) => {
@@ -483,7 +483,7 @@ WebContents.prototype._init = function () {
   this.setMaxListeners(0);
 
   // Dispatch IPC messages to the ipc module.
-  this.on('-ipc-message' as any, function (this: WebContentsInternal, event: any, internal: boolean, channel: string, args: any[]) {
+  this.on('-ipc-message' as any, function (this: Electron.WebContentsInternal, event: any, internal: boolean, channel: string, args: any[]) {
     if (internal) {
       addReplyInternalToEvent(event);
       ipcMainInternal.emit(channel, event, ...args);
@@ -508,7 +508,7 @@ WebContents.prototype._init = function () {
     }
   });
 
-  this.on('-ipc-message-sync' as any, function (this: WebContentsInternal, event: any, internal: boolean, channel: string, args: any[]) {
+  this.on('-ipc-message-sync' as any, function (this: Electron.WebContentsInternal, event: any, internal: boolean, channel: string, args: any[]) {
     addReturnValueToEvent(event);
     if (internal) {
       addReplyInternalToEvent(event);
@@ -546,7 +546,7 @@ WebContents.prototype._init = function () {
   });
 
   // The devtools requests the webContents to reload.
-  this.on('devtools-reload-page', function (this: WebContentsInternal) {
+  this.on('devtools-reload-page', function (this: Electron.WebContentsInternal) {
     this.reload();
   });
 
@@ -569,7 +569,7 @@ WebContents.prototype._init = function () {
 
     // Create a new browser window for the native implementation of
     // "window.open", used in sandbox and nativeWindowOpen mode.
-    this.on('-add-new-contents' as any, (event: any, webContents: WebContentsInternal, disposition: string,
+    this.on('-add-new-contents' as any, (event: any, webContents: Electron.WebContentsInternal, disposition: string,
       userGesture: boolean, left: number, top: number, width: number, height: number, url: string, frameName: string,
       referrer: string, rawFeatures: string, postData: string) => {
       if ((disposition !== 'foreground-tab' && disposition !== 'new-window' &&

+ 1 - 1
lib/browser/chrome-extension-shim.ts

@@ -2,7 +2,7 @@
 // BrowserWindow-based extensions stuff to the new native-backed extensions
 // API.
 
-import { app, session, BrowserWindow, deprecate } from 'electron';
+import { app, session, BrowserWindow, deprecate } from 'electron/main';
 
 app.whenReady().then(function () {
   const addExtension = function (srcDirectory: string) {

+ 2 - 1
lib/browser/default-menu.ts

@@ -1,4 +1,5 @@
-import { shell, Menu } from 'electron';
+import { Menu } from 'electron/main';
+import { shell } from 'electron/common';
 
 const v8Util = process._linkedBinding('electron_common_v8_util');
 

+ 1 - 1
lib/browser/devtools.ts

@@ -1,4 +1,4 @@
-import { dialog, Menu } from 'electron';
+import { dialog, Menu } from 'electron/main';
 import * as fs from 'fs';
 import * as url from 'url';
 

+ 1 - 1
lib/browser/ipc-main-impl.ts

@@ -1,5 +1,5 @@
 import { EventEmitter } from 'events';
-import { IpcMainInvokeEvent } from 'electron';
+import { IpcMainInvokeEvent } from 'electron/main';
 
 export class IpcMainImpl extends EventEmitter {
   private _invokeHandlers: Map<string, (e: IpcMainInvokeEvent, ...args: any[]) => void> = new Map();

+ 1 - 1
lib/browser/navigation-controller.ts

@@ -1,4 +1,4 @@
-import { ipcMainInternal } from './ipc-main-internal';
+import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
 import type { WebContents, LoadURLOptions } from 'electron/main';
 import { EventEmitter } from 'events';
 

+ 1 - 1
lib/browser/remote/objects-registry.ts

@@ -1,6 +1,6 @@
 'use strict';
 
-import { WebContents } from 'electron';
+import { WebContents } from 'electron/main';
 
 const v8Util = process._linkedBinding('electron_common_v8_util');
 

+ 5 - 5
lib/browser/remote/server.ts

@@ -1,9 +1,9 @@
-import * as electron from 'electron';
+import * as electron from 'electron/main';
 import { EventEmitter } from 'events';
-import objectsRegistry from './objects-registry';
-import { ipcMainInternal } from '../ipc-main-internal';
-import { isPromise, isSerializableObject, deserialize, serialize } from '../../common/type-utils';
-import type { MetaTypeFromRenderer, ObjectMember, MetaType, ObjProtoDescriptor } from '../../common/remote/types';
+import objectsRegistry from '@electron/internal/browser/remote/objects-registry';
+import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
+import { isPromise, isSerializableObject, deserialize, serialize } from '@electron/internal/common/type-utils';
+import type { MetaTypeFromRenderer, ObjectMember, MetaType, ObjProtoDescriptor } from '@electron/internal/common/remote/types';
 
 const v8Util = process._linkedBinding('electron_common_v8_util');
 const eventBinding = process._linkedBinding('electron_browser_event');

+ 16 - 16
lib/browser/rpc-server.ts

@@ -1,24 +1,24 @@
-import * as electron from 'electron';
+import { app } from 'electron/main';
+import type { IpcMainInvokeEvent, WebContents } from 'electron/main';
+import { clipboard, crashReporter } from 'electron/common';
 import * as fs from 'fs';
-import { ipcMainInternal } from './ipc-main-internal';
-import * as ipcMainUtils from './ipc-main-internal-utils';
-import * as guestViewManager from './guest-view-manager';
-import * as typeUtils from '../common/type-utils';
-import { IpcMainInvokeEvent } from 'electron/main';
+import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
+import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils';
+import * as guestViewManager from '@electron/internal/browser/guest-view-manager';
+import * as typeUtils from '@electron/internal/common/type-utils';
 
 const eventBinding = process._linkedBinding('electron_browser_event');
-const clipboard = process._linkedBinding('electron_common_clipboard');
 
-const emitCustomEvent = function (contents: electron.WebContents, eventName: string, ...args: any[]) {
+const emitCustomEvent = function (contents: WebContents, eventName: string, ...args: any[]) {
   const event = eventBinding.createWithSender(contents);
 
-  electron.app.emit(eventName, event, contents, ...args);
+  app.emit(eventName, event, contents, ...args);
   contents.emit(eventName, event, ...args);
 
   return event;
 };
 
-const logStack = function (contents: electron.WebContents, code: string, stack: string) {
+const logStack = function (contents: WebContents, code: string, stack: string) {
   if (stack) {
     console.warn(`WebContents (${contents.id}): ${code}`, stack);
   }
@@ -54,7 +54,7 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_CLIPBOARD_SYNC', function (event: IpcM
     throw new Error(`Invalid method: ${method}`);
   }
 
-  return typeUtils.serialize((electron.clipboard as any)[method](...typeUtils.deserialize(args)));
+  return typeUtils.serialize((clipboard as any)[method](...typeUtils.deserialize(args)));
 });
 
 if (BUILDFLAG(ENABLE_DESKTOP_CAPTURER)) {
@@ -118,21 +118,21 @@ ipcMainInternal.on('ELECTRON_BROWSER_PRELOAD_ERROR', function (event: ElectronIn
 });
 
 ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_GET_LAST_CRASH_REPORT', () => {
-  return electron.crashReporter.getLastCrashReport();
+  return crashReporter.getLastCrashReport();
 });
 
 ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_GET_UPLOADED_REPORTS', () => {
-  return electron.crashReporter.getUploadedReports();
+  return crashReporter.getUploadedReports();
 });
 
 ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_GET_UPLOAD_TO_SERVER', () => {
-  return electron.crashReporter.getUploadToServer();
+  return crashReporter.getUploadToServer();
 });
 
 ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_SET_UPLOAD_TO_SERVER', (event: IpcMainInvokeEvent, uploadToServer: boolean) => {
-  return electron.crashReporter.setUploadToServer(uploadToServer);
+  return crashReporter.setUploadToServer(uploadToServer);
 });
 
 ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_GET_CRASHES_DIRECTORY', () => {
-  return electron.crashReporter.getCrashesDirectory();
+  return crashReporter.getCrashesDirectory();
 });