fix: support esm entrypoint to utility process (#40047)

This commit is contained in:
Samuel Attard 2023-09-29 14:38:37 -07:00 committed by GitHub
parent d6c8ff2e70
commit 371e83a8d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 3 deletions

View file

@ -1,5 +1,7 @@
import { pathToFileURL } from 'url';
import { ParentPort } from '@electron/internal/utility/parent-port';
const Module = require('module') as NodeJS.ModuleInternal;
const v8Util = process._linkedBinding('electron_common_v8_util');
const entryScript: string = v8Util.getHiddenValue(process, '_serviceStartupScript');
@ -34,5 +36,14 @@ parentPort.on('removeListener', (name: string) => {
});
// Finally load entry script.
process._firstFileName = Module._resolveFilename(entryScript, null, false);
Module._load(entryScript, Module, true);
const { loadESM } = __non_webpack_require__('internal/process/esm_loader');
const mainEntry = pathToFileURL(entryScript);
loadESM(async (esmLoader: any) => {
try {
await esmLoader.import(mainEntry.toString(), undefined, Object.create(null));
} catch (err) {
// @ts-ignore internalBinding is a secret internal global that we shouldn't
// really be using, so we ignore the type error instead of declaring it in types
internalBinding('errors').triggerUncaughtException(err);
}
});

View file

@ -5,6 +5,7 @@ import { BrowserWindow, MessageChannelMain, utilityProcess } from 'electron/main
import { ifit } from './lib/spec-helpers';
import { closeWindow } from './lib/window-helpers';
import { once } from 'node:events';
import { pathToFileURL } from 'node:url';
const fixturesPath = path.resolve(__dirname, 'fixtures', 'api', 'utility-process');
const isWindowsOnArm = process.platform === 'win32' && process.arch === 'arm64';
@ -78,6 +79,12 @@ describe('utilityProcess module', () => {
expect(code).to.equal(1);
});
it('emits \'exit\' when there is uncaught exception in ESM', async () => {
const child = utilityProcess.fork(path.join(fixturesPath, 'exception.mjs'));
const [code] = await once(child, 'exit');
expect(code).to.equal(1);
});
it('emits \'exit\' when process.exit is called', async () => {
const exitCode = 2;
const child = utilityProcess.fork(path.join(fixturesPath, 'custom-exit.js'), [`--exitCode=${exitCode}`]);
@ -97,6 +104,23 @@ describe('utilityProcess module', () => {
});
});
describe('esm', () => {
it('is launches an mjs file', async () => {
const fixtureFile = path.join(fixturesPath, 'esm.mjs');
const child = utilityProcess.fork(fixtureFile, [], {
stdio: 'pipe'
});
await once(child, 'spawn');
expect(child.stdout).to.not.be.null();
let log = '';
child.stdout!.on('data', (chunk) => {
log += chunk.toString('utf8');
});
await once(child, 'exit');
expect(log).to.equal(pathToFileURL(fixtureFile) + '\n');
});
});
describe('pid property', () => {
it('is valid when child process launches successfully', async () => {
const child = utilityProcess.fork(path.join(fixturesPath, 'empty.js'));

View file

@ -0,0 +1,2 @@
console.log(import.meta.url);
process.exit(0);

View file

@ -0,0 +1 @@
nonExistingFunc(); // eslint-disable-line no-undef