Skip to content

Commit f3dc029

Browse files
authored
refactor: move npm.ts to main process (#1341)
1 parent 4fb0022 commit f3dc029

14 files changed

Lines changed: 133 additions & 53 deletions

File tree

src/ambient.d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import {
55
BlockableAccelerator,
66
EditorValues,
77
FiddleEvent,
8+
IPackageManager,
89
MessageOptions,
910
OutputEntry,
11+
PMOperationOptions,
1012
RunResult,
1113
SelectedLocalVersion,
1214
TestRequest,
@@ -66,6 +68,10 @@ declare global {
6668
type: 'toggle-monaco-option',
6769
listener: (path: string) => void,
6870
): void;
71+
addModules(
72+
{ dir, packageManager }: PMOperationOptions,
73+
...names: Array<string>
74+
): Promise<string>;
6975
app: App;
7076
appPaths: Record<string, string>;
7177
arch: string;
@@ -76,13 +82,21 @@ declare global {
7682
name?: string,
7783
): Promise<LoadedFiddleTheme>;
7884
getAvailableThemes(): Promise<Array<LoadedFiddleTheme>>;
85+
getIsPackageManagerInstalled(
86+
packageManager: IPackageManager,
87+
ignoreCache?: boolean,
88+
): Promise<boolean>;
7989
getTemplate(version: string): Promise<EditorValues>;
8090
getTemplateValues: (name: string) => Promise<EditorValues>;
8191
getTestTemplate(): Promise<EditorValues>;
8292
isDevMode: boolean;
8393
macTitlebarClicked(): void;
8494
monaco: typeof MonacoType;
8595
openThemeFolder(): Promise<void>;
96+
packageRun(
97+
{ dir, packageManager }: PMOperationOptions,
98+
command: string,
99+
): Promise<string>;
86100
platform: string;
87101
pushOutputEntry(entry: OutputEntry): void;
88102
readThemeFile(name?: string): Promise<LoadedFiddleTheme | null>;

src/interfaces.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,10 @@ export interface MessageOptions {
178178
detail?: string;
179179
buttons?: string[];
180180
}
181+
182+
export type IPackageManager = 'npm' | 'yarn';
183+
184+
export interface PMOperationOptions {
185+
dir: string;
186+
packageManager: IPackageManager;
187+
}

src/ipc-events.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ export enum IpcEvents {
4747
READ_THEME_FILE = 'READ_THEME_FILE',
4848
GET_THEME_PATH = 'GET_THEME_PATH',
4949
IS_DEV_MODE = 'IS_DEV_MODE',
50+
NPM_ADD_MODULES = 'NPM_ADD_MODULES',
51+
NPM_IS_PM_INSTALLED = 'NPM_IS_PM_INSTALLED',
52+
NPM_PACKAGE_RUN = 'NPM_PACKAGE_RUN',
5053
}
5154

5255
export const ipcMainEvents = [
@@ -72,6 +75,9 @@ export const ipcMainEvents = [
7275
IpcEvents.READ_THEME_FILE,
7376
IpcEvents.GET_THEME_PATH,
7477
IpcEvents.IS_DEV_MODE,
78+
IpcEvents.NPM_ADD_MODULES,
79+
IpcEvents.NPM_IS_PM_INSTALLED,
80+
IpcEvents.NPM_PACKAGE_RUN,
7581
];
7682

7783
export const WEBCONTENTS_READY_FOR_IPC_SIGNAL =

src/main/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { setupDevTools } from './devtools';
1818
import { setupDialogs } from './dialogs';
1919
import { onFirstRunMaybe } from './first-run';
2020
import { ipcMainManager } from './ipc';
21+
import { setupNpm } from './npm';
2122
import { listenForProtocolHandler, setupProtocolHandler } from './protocol';
2223
import { shouldQuit } from './squirrel';
2324
import { setupTemplates } from './templates';
@@ -55,6 +56,7 @@ export async function onReady() {
5556
setupContent();
5657
setupThemes();
5758
setupIsDevMode();
59+
setupNpm();
5860

5961
processCommandLine(argv);
6062
}
Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import { exec } from '../utils/exec';
2-
3-
export type IPackageManager = 'npm' | 'yarn';
1+
import { IpcMainEvent } from 'electron';
42

5-
export interface PMOperationOptions {
6-
dir: string;
7-
packageManager: IPackageManager;
8-
}
3+
import { IPackageManager, PMOperationOptions } from '../interfaces';
4+
import { IpcEvents } from '../ipc-events';
5+
import { exec } from '../utils/exec';
6+
import { ipcMainManager } from './ipc';
97

108
let isNpmInstalled: boolean | null = null;
119
let isYarnInstalled: boolean | null = null;
@@ -24,7 +22,7 @@ export async function getIsPackageManagerInstalled(
2422
return isYarnInstalled;
2523

2624
const command =
27-
window.ElectronFiddle.platform === 'win32'
25+
process.platform === 'win32'
2826
? `where.exe ${packageManager}`
2927
: `which ${packageManager}`;
3028

@@ -84,3 +82,27 @@ export function packageRun(
8482
): Promise<string> {
8583
return exec(dir, `${packageManager} run ${command}`);
8684
}
85+
86+
export async function setupNpm() {
87+
ipcMainManager.handle(
88+
IpcEvents.NPM_ADD_MODULES,
89+
(
90+
_: IpcMainEvent,
91+
{ dir, packageManager }: PMOperationOptions,
92+
...names: Array<string>
93+
) => addModules({ dir, packageManager }, ...names),
94+
);
95+
ipcMainManager.handle(
96+
IpcEvents.NPM_IS_PM_INSTALLED,
97+
(_: IpcMainEvent, packageManager: IPackageManager, ignoreCache?: boolean) =>
98+
getIsPackageManagerInstalled(packageManager, ignoreCache),
99+
);
100+
ipcMainManager.handle(
101+
IpcEvents.NPM_PACKAGE_RUN,
102+
(
103+
_: IpcMainEvent,
104+
{ dir, packageManager }: PMOperationOptions,
105+
command: string,
106+
) => packageRun({ dir, packageManager }, command),
107+
);
108+
}

src/preload/preload.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ export async function setupFiddleGlobal() {
5858
}
5959
}
6060
},
61+
addModules({ dir, packageManager }, ...names) {
62+
return ipcRenderer.invoke(
63+
IpcEvents.NPM_ADD_MODULES,
64+
{ dir, packageManager },
65+
...names,
66+
);
67+
},
6168
app: null as any, // will be set in main.tsx
6269
appPaths: await ipcRenderer.invoke(IpcEvents.GET_APP_PATHS),
6370
arch: process.arch,
@@ -73,6 +80,13 @@ export async function setupFiddleGlobal() {
7380
getAvailableThemes() {
7481
return ipcRenderer.invoke(IpcEvents.GET_AVAILABLE_THEMES);
7582
},
83+
getIsPackageManagerInstalled(packageManager, ignoreCache) {
84+
return ipcRenderer.invoke(
85+
IpcEvents.NPM_IS_PM_INSTALLED,
86+
packageManager,
87+
ignoreCache,
88+
);
89+
},
7690
getTemplate: (version: string) =>
7791
ipcRenderer.invoke(IpcEvents.GET_TEMPLATE, version),
7892
getTemplateValues: (name: string) => {
@@ -87,6 +101,13 @@ export async function setupFiddleGlobal() {
87101
async openThemeFolder() {
88102
await ipcRenderer.invoke(IpcEvents.OPEN_THEME_FOLDER);
89103
},
104+
packageRun({ dir, packageManager }, command) {
105+
return ipcRenderer.invoke(
106+
IpcEvents.NPM_PACKAGE_RUN,
107+
{ dir, packageManager },
108+
command,
109+
);
110+
},
90111
platform: process.platform,
91112
pushOutputEntry(entry) {
92113
ipcRenderer.send(IpcEvents.OUTPUT_ENTRY, entry);

src/renderer/components/settings-execution.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
} from '@blueprintjs/core';
1313
import { observer } from 'mobx-react';
1414

15-
import { IPackageManager } from '../npm';
15+
import { IPackageManager } from '../../interfaces';
1616
import { AppState } from '../state';
1717

1818
export enum SettingItemType {

src/renderer/runner.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,13 @@ import { Installer } from '@electron/fiddle-core';
66
import {
77
FileTransform,
88
InstallState,
9+
PMOperationOptions,
910
RunResult,
1011
RunnableVersion,
1112
} from '../interfaces';
1213
import { PackageJsonOptions } from '../utils/get-package';
1314
import { maybePlural } from '../utils/plural-maybe';
1415
import { Bisector } from './bisect';
15-
import {
16-
PMOperationOptions,
17-
addModules,
18-
getIsPackageManagerInstalled,
19-
packageRun,
20-
} from './npm';
2116
import { AppState } from './state';
2217
import { getVersionState } from './versions';
2318

@@ -267,7 +262,9 @@ export class Runner {
267262
pushOutput(`📦 ${strings[0]} current Fiddle...`);
268263

269264
const packageManager = this.appState.packageManager;
270-
const pmInstalled = await getIsPackageManagerInstalled(packageManager);
265+
const pmInstalled = await window.ElectronFiddle.getIsPackageManagerInstalled(
266+
packageManager,
267+
);
271268
if (!pmInstalled) {
272269
let message = `Error: Could not find ${packageManager}. Fiddle requires Node.js and npm or yarn `;
273270
message += `to compile packages. Please visit https://nodejs.org to install `;
@@ -292,7 +289,12 @@ export class Runner {
292289
// Cool, let's run "package"
293290
try {
294291
console.log(`Now creating ${strings[1].toLowerCase()}...`);
295-
pushOutput(await packageRun({ dir, packageManager }, operation));
292+
pushOutput(
293+
await window.ElectronFiddle.packageRun(
294+
{ dir, packageManager },
295+
operation,
296+
),
297+
);
296298
pushOutput(`✅ ${strings[1]} successfully created.`, { isNotPre: true });
297299
} catch (error) {
298300
pushError(`Creating ${strings[1].toLowerCase()} failed.`, error);
@@ -320,7 +322,9 @@ export class Runner {
320322
if (modules && modules.length > 0) {
321323
this.appState.isInstallingModules = true;
322324
const packageManager = pmOptions.packageManager;
323-
const pmInstalled = await getIsPackageManagerInstalled(packageManager);
325+
const pmInstalled = await window.ElectronFiddle.getIsPackageManagerInstalled(
326+
packageManager,
327+
);
324328
if (!pmInstalled) {
325329
let message = `The ${maybePlural(`module`, modules)} ${modules.join(
326330
', ',
@@ -342,7 +346,10 @@ export class Runner {
342346
{ isNotPre: true },
343347
);
344348

345-
const result = await addModules(pmOptions, ...modules);
349+
const result = await window.ElectronFiddle.addModules(
350+
pmOptions,
351+
...modules,
352+
);
346353
pushOutput(result);
347354

348355
this.appState.isInstallingModules = false;
@@ -478,7 +485,7 @@ export class Runner {
478485
public async packageInstall(options: PMOperationOptions): Promise<boolean> {
479486
try {
480487
this.appState.pushOutput(`Now running "npm install..."`);
481-
this.appState.pushOutput(await addModules(options));
488+
this.appState.pushOutput(await window.ElectronFiddle.addModules(options));
482489
return true;
483490
} catch (error) {
484491
this.appState.pushError('Failed to run "npm install".', error);

src/renderer/state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
GenericDialogOptions,
2222
GenericDialogType,
2323
GistActionState,
24+
IPackageManager,
2425
InstallState,
2526
OutputEntry,
2627
OutputOptions,
@@ -37,7 +38,6 @@ import { Bisector } from './bisect';
3738
import { ELECTRON_DOWNLOAD_PATH, ELECTRON_INSTALL_PATH } from './constants';
3839
import { EditorMosaic } from './editor-mosaic';
3940
import { ELECTRON_MIRROR } from './mirror-constants';
40-
import { IPackageManager } from './npm';
4141
import {
4242
addLocalVersion,
4343
fetchVersions,
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import {
22
addModules,
33
getIsPackageManagerInstalled,
44
packageRun,
5-
} from '../../src/renderer/npm';
5+
} from '../../src/main/npm';
66
import { exec } from '../../src/utils/exec';
7-
import { overrideRendererPlatform, resetRendererPlatform } from '../utils';
7+
import { overridePlatform, resetPlatform } from '../utils';
88
jest.mock('../../src/utils/exec');
99

1010
describe('npm', () => {
@@ -14,10 +14,10 @@ describe('npm', () => {
1414
jest.resetModules();
1515
});
1616

17-
afterEach(() => resetRendererPlatform());
17+
afterEach(() => resetPlatform());
1818

1919
it('returns true if npm installed', async () => {
20-
overrideRendererPlatform('darwin');
20+
overridePlatform('darwin');
2121

2222
(exec as jest.Mock).mockResolvedValueOnce('/usr/bin/fake-npm');
2323

@@ -28,7 +28,7 @@ describe('npm', () => {
2828
});
2929

3030
it('returns true if npm installed', async () => {
31-
overrideRendererPlatform('win32');
31+
overridePlatform('win32');
3232

3333
(exec as jest.Mock).mockResolvedValueOnce('/usr/bin/fake-npm');
3434

@@ -39,7 +39,7 @@ describe('npm', () => {
3939
});
4040

4141
it('returns false if npm not installed', async () => {
42-
overrideRendererPlatform('darwin');
42+
overridePlatform('darwin');
4343

4444
(exec as jest.Mock).mockRejectedValueOnce('/usr/bin/fake-npm');
4545

@@ -67,10 +67,10 @@ describe('npm', () => {
6767
jest.resetModules();
6868
});
6969

70-
afterEach(() => resetRendererPlatform());
70+
afterEach(() => resetPlatform());
7171

7272
it('returns true if yarn installed', async () => {
73-
overrideRendererPlatform('darwin');
73+
overridePlatform('darwin');
7474

7575
(exec as jest.Mock).mockResolvedValueOnce('/usr/bin/fake-yarn');
7676

@@ -81,7 +81,7 @@ describe('npm', () => {
8181
});
8282

8383
it('returns true if yarn installed', async () => {
84-
overrideRendererPlatform('win32');
84+
overridePlatform('win32');
8585

8686
(exec as jest.Mock).mockResolvedValueOnce('/usr/bin/fake-yarn');
8787

@@ -92,7 +92,7 @@ describe('npm', () => {
9292
});
9393

9494
it('returns false if yarn not installed', async () => {
95-
overrideRendererPlatform('darwin');
95+
overridePlatform('darwin');
9696

9797
(exec as jest.Mock).mockRejectedValueOnce('/usr/bin/fake-yarn');
9898

0 commit comments

Comments
 (0)