首页 > 解决方案 > 未捕获的异常:错误:spawn /Users/dev/Sites/chat/dist_electron/bin/ngrok ENOENT

问题描述

我在我启用的电子应用程序中有此代码contextIsolation

// background.js
'use strict';

import { app, protocol, BrowserWindow } from 'electron';
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib';
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer';
import './server';
const path = require('path');
const isDevelopment = process.env.NODE_ENV !== 'production';

// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
  { scheme: 'app', privileges: { secure: true, standard: true } }
]);

async function createWindow() {
  // Create the browser window.
  const win = new BrowserWindow({
    width: 1200,
    height: 600,
    resizable: false,
    webPreferences: {
      
      // Use pluginOptions.nodeIntegration, leave this alone
      // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
      nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
      enableRemoteModule: false,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js')
    }
  });

  if (process.env.WEBPACK_DEV_SERVER_URL) {
    // Load the url of the dev server if in development mode
    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
    if (!process.env.IS_TEST) win.webContents.openDevTools();
  } else {
    createProtocol('app');
    // Load the index.html when not in development
    win.loadURL('app://./index.html');
  }
}

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) createWindow();
})

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
  if (isDevelopment && !process.env.IS_TEST) {
    // Install Vue Devtools
    try {
      await installExtension(VUEJS_DEVTOOLS);
    } catch (e) {
      console.error('Vue Devtools failed to install:', e.toString());
    }
  }
  createWindow();
})

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
  if (process.platform === 'win32') {
    process.on('message', (data) => {
      if (data === 'graceful-exit') {
        app.quit();
      }
    })
  } else {
    process.on('SIGTERM', () => {
      app.quit();
    });
  }
}



// preload.js script
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('ipcRenderer', {
    send: (channel, data) => {
        const whitelist = ['start-server'];
        if( whitelist.includes(channel) ){
            ipcRenderer.send(channel, data);
        }
    },
    receive: (channel, fn) => {
        const whitelist = ['server-status'];
        if( whitelist.includes(channel) ){
            ipcRenderer.on(channel, (event, ...args) => fn(...args));
        }
    }
});

// server.js
const { ipcMain } = require('electron');
const http = require('http');
const ngrok = require('ngrok');

let server;

ipcMain.on('start-server', async (event, data) =>  {
  console.log(event, data);
  server = http.createServer( (req, res) => {
    res.writeHead(200);
    res.end('Server ok!');
  }).listen(5030);
  const tunnel = await ngrok.connect(5030);
  event.reply('server-status', `server status: ${server}, tunnel link: ${tunnel}`);
});

// vue component
<template>
  <div class="container-fluid p-0">
    <div class="row">
      <div class="col-8 text-center p-0">
        <img class="img-fluid w-100" src="@/assets/file-transfer.jpg">
      </div>
      <div class="col-4">
      
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: 'Home',
  mounted() {
    this.openConnection();
    window.ipcRenderer.receive('server-status', (event, data) => {
      console.log(event, data);
    });
  },
  methods: {
    openConnection() {
      window.ipcRenderer.send('start-server');
    }
  }
}
</script>


我正在尝试在电子应用程序中运行服务器,以便能够使用 ngrok 进行隧道传输,使用 socket.io 进行 p2p 文件共享。问题是,当我尝试在服务模式下运行应用程序时,出现以下错误:

Uncaught Exception:
Error: spawn /Users/dev/Sites/chat/dist_electron/bin/ngrok ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:267:19)
    at onErrorNT (internal/child_process.js:469:16)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)

打开应用程序并立即显示错误消息,但在 vue 组件内未收到控制台日志或消息。我做错了什么?

标签: javascriptnode.jselectron

解决方案


推荐阅读