mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Replaces the webpack+ts-loader based bundler for Electron's 8 internal
init bundles (browser, renderer, worker, sandboxed_renderer,
isolated_renderer, node, utility, preload_realm) with a plain esbuild
driver under build/esbuild/. GN template now lives at
build/esbuild/esbuild.gni and is invoked via a new 'bundle' npm script.
Per-target configs move from build/webpack/webpack.config.<target>.js to
small data-only files under build/esbuild/configs/. ProvidePlugin's
global/Buffer/process/Promise capture moves to inject-shims under
build/esbuild/shims/. The wrapper-webpack-plugin try/catch and
___electron_webpack_init__ wrappers are applied as textual pre/postamble
inside the driver so shell/common/node_util.cc's CompileAndCall error
handling still works.
The old BUILDFLAG DefinePlugin pass is replaced with a small onLoad
regex that rewrites BUILDFLAG(NAME) to (true|false) using the
GN-generated buildflags.h. AccessDependenciesPlugin (used by
gen-filenames.ts to populate filenames.auto.gni) is replaced with
esbuild's built-in metafile via a new '--print-graph' flag.
A few source files needed small fixes to work under esbuild's
stricter CJS/ESM interop:
- lib/browser/api/net.ts and lib/utility/api/net.ts mixed ESM
'export function' with 'exports.x = ...' assignments, which
esbuild treats as an ambiguous module. Switched to a single
'module.exports = {}' with a getter for the dynamic 'online'
property.
- lib/common/timers-shim.ts is untouched; lib/common/init.ts no
longer mutates the imported timers namespace (timers.setImmediate
= wrap(...)). Under webpack the mutation applied to the bundled
shim and was invisible to user apps; the refactor stores the
wrapped values in local consts instead.
Drops webpack, webpack-cli, ts-loader, null-loader, and
wrapper-webpack-plugin from devDependencies. Adds esbuild.
Sequential build time for the 8 bundles drops from ~22s (webpack) to
~480ms (esbuild).
103 lines
3.1 KiB
TypeScript
103 lines
3.1 KiB
TypeScript
// Drop-in replacement for timers-browserify@1.4.2.
|
|
// Provides the Node.js 'timers' API surface for renderer/web bundles
|
|
// without relying on window.postMessage (which the newer timers-browserify 2.x
|
|
// polyfill uses and can interfere with Electron IPC).
|
|
|
|
const immediateIds: Record<number, boolean> = {};
|
|
let nextImmediateId = 0;
|
|
|
|
// --- DOM timer wrappers ------------------------------------------------
|
|
// Wrap the global setTimeout/setInterval so we return Timeout objects that
|
|
// expose ref/unref/close matching the Node.js API shape.
|
|
|
|
class Timeout {
|
|
_id: ReturnType<typeof globalThis.setTimeout>;
|
|
_clearFn: (id: ReturnType<typeof globalThis.setTimeout>) => void;
|
|
|
|
constructor (id: ReturnType<typeof globalThis.setTimeout>, clearFn: (id: ReturnType<typeof globalThis.setTimeout>) => void) {
|
|
this._id = id;
|
|
this._clearFn = clearFn;
|
|
}
|
|
|
|
unref () {}
|
|
ref () {}
|
|
|
|
close () {
|
|
this._clearFn.call(globalThis, this._id);
|
|
}
|
|
}
|
|
|
|
export const setTimeout = function (...args: Parameters<typeof globalThis.setTimeout>): Timeout {
|
|
return new Timeout(globalThis.setTimeout(...args), globalThis.clearTimeout);
|
|
};
|
|
|
|
export const setInterval = function (...args: Parameters<typeof globalThis.setInterval>): Timeout {
|
|
return new Timeout(globalThis.setInterval(...args), globalThis.clearInterval);
|
|
};
|
|
|
|
export const clearTimeout = function (timeout: Timeout | undefined) {
|
|
if (timeout) timeout.close();
|
|
};
|
|
|
|
export const clearInterval = clearTimeout;
|
|
|
|
// --- Legacy enroll/unenroll (Node < 11 API, preserved for compatibility) ------
|
|
|
|
interface EnrollableItem {
|
|
_idleTimeoutId?: ReturnType<typeof setTimeout>;
|
|
_idleTimeout?: number;
|
|
_onTimeout?: () => void;
|
|
}
|
|
|
|
export const enroll = function (item: EnrollableItem, msecs: number) {
|
|
clearTimeout(item._idleTimeoutId);
|
|
item._idleTimeout = msecs;
|
|
};
|
|
|
|
export const unenroll = function (item: EnrollableItem) {
|
|
clearTimeout(item._idleTimeoutId);
|
|
item._idleTimeout = -1;
|
|
};
|
|
|
|
export const active = function (item: EnrollableItem) {
|
|
clearTimeout(item._idleTimeoutId);
|
|
|
|
const msecs = item._idleTimeout;
|
|
if (msecs !== undefined && msecs >= 0) {
|
|
item._idleTimeoutId = setTimeout(function onTimeout () {
|
|
if (item._onTimeout) item._onTimeout();
|
|
}, msecs);
|
|
}
|
|
};
|
|
|
|
export const _unrefActive = active;
|
|
|
|
// --- setImmediate / clearImmediate -------------------------------------
|
|
// Prefer the native implementations when available. Fall back to a
|
|
// nextTick-based shim that avoids window.postMessage.
|
|
|
|
const clearImmediateFallback = function (id: number) {
|
|
delete immediateIds[id];
|
|
};
|
|
|
|
export const setImmediate = typeof globalThis.setImmediate === 'function'
|
|
? globalThis.setImmediate
|
|
: function (fn: (...args: unknown[]) => void, ...rest: unknown[]) {
|
|
const id = nextImmediateId++;
|
|
|
|
immediateIds[id] = true;
|
|
|
|
Promise.resolve().then(function onMicrotask () {
|
|
if (immediateIds[id]) {
|
|
fn(...rest);
|
|
clearImmediateFallback(id);
|
|
}
|
|
});
|
|
|
|
return id;
|
|
};
|
|
|
|
export const clearImmediate = typeof globalThis.clearImmediate === 'function'
|
|
? globalThis.clearImmediate
|
|
: clearImmediateFallback;
|