打包应用程序后的电子和 sqlite3 问题

Electron and sqlite3 issue after packaging app

最近我在这里问了很多问题,因为我一直被节点和数据库的不同部分所困扰。

总之,一些背景知识:

我有一个带有 AngularJS 前端的 Electron 应用程序。所以在电子方面,我实际上启动了一个服务于我的 angular 应用程序的快速服务器,它当然可以通过 ipc 与电子通信。我还使用事物的表达方式来做数据库的事情(sqlite3),为 api 定义路由,Angular 可以使用 $http 命中并以这种方式返回数据库结果。当我使用 'npm start' 运行 应用程序时,一切正常。 db/server 方面的代码如下:

var path = require('path');
var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require('body-parser');
var path = require('path');
var sqlite3 = require('sqlite3').verbose();

// Load the db
function createDbFile() {
    // Try to open the db file - if it doesn't exist, create it.
    try {
        var filebuffer = fs.readFileSync(path.join(__dirname, 'app.db'));
    }
    catch (err) {
        if (err.code === 'ENOENT') {
            fs.closeSync(fs.openSync(path.join(__dirname, 'app.db'), 'w'));
        } 
        else {
            throw err;
        }
    }
}

createDbFile();
var db = new sqlite3.Database('app.db');
var check;

db.serialize(function() {
db.run("CREATE TABLE IF NOT EXISTS lorem (info TEXT)");

var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
for (var i = 0; i < 10; i++) {
    stmt.run("Ipsum " + i);
}
stmt.finalize();
});

app.use(express.static(__dirname));
// app.use(bodyParser.json());

app.get('/', function (req, res) {
    res.sendFile(__dirname + 'index.html');
});

app.get('/loading', function (req, res) {
    res.sendFile(__dirname + '/loading.html');
});

app.get('/api/get/all', function (req, res) {    
    db.all("SELECT * FROM lorem", function(err, row) {
    res.json(row);
    });
});

app.post('/api/post/site', function (req, res) {
    // Do stuff here.
});

app.listen(3333);

除此之外,这是我的 main.js 文件,它需要这个 server.js 文件:

const electron = require('electron');
const server = require("./server");
const ipcMain = require('electron').ipcMain;
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;

// Define our global references
let mainWindow,
    loadingScreen,
    windowParams = {
      width: 1000,
      height: 700,
      show: false
    },
    loadingWindowParams = {
      width: 400,
      height: 300,
      show: false,
      frame: false
    };

// Define our loading window whose parent is main
function createLoadingScreen() {
    loadingScreen = new BrowserWindow(Object.assign(loadingWindowParams, {parent: mainWindow}));
    loadingScreen.loadURL('http://localhost:3333/loading');
    loadingScreen.on('closed', () => loadingScreen = null);
    loadingScreen.webContents.on('did-finish-load', () => {
        loadingScreen.show();
    });
}

app.on('ready', () => {
  // Create loading screen
  createLoadingScreen();

  // Create the browser window.
  mainWindow = new BrowserWindow(windowParams);

  // Point to our express server
  mainWindow.loadURL(`http://localhost:3333`);

  // Open the DevTools.
  mainWindow.webContents.openDevTools();

  // Simulate loading to allow angular to initialize, then show main window
  mainWindow.once('ready-to-show', () => {
    if (loadingScreen) {
      setTimeout(function() {
        loadingScreen.close();
        mainWindow.show();
      }, 6000);
    }
  });

  // Close the app after window closed for security purposes
  mainWindow.on('closed', function () {
    mainWindow = null
    app.quit();
  });

  // Handle messages
  ipcMain.on('electron-msg', (event, msg) => {
    switch (msg.type) {
      case 'system':
        mainWindow.webContents.send('electron-msg', 'Message received');
      break;
    }
  });

});

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') {
    app.quit()
  }
});

// Open window again when activated
app.on('activate', function () {
  if (mainWindow === null) {
    // Not currently needed, we quit when window closed
  }
});

// Throw our errors
process.on('uncaughtException', function (err) {
  console.log(err);
});

我遇到的问题是,当我使用 https://github.com/electron-userland/electron-builder 打包我的应用程序时,应用程序正常运行,服务器启动并且 Angular 组件工作正常,但我不能 read/write/create 一个数据库文件,就像我在打包之前可以做的那样。我现在完全不知道去哪里看!

在我的头撞到我的桌子上一段时间后,我几乎无意中设法解决了这个问题。我试图实现一些日志记录以查看打包时是否存在节点模块未被正确识别的问题,当我注意到日志文件没有在我期望的位置创建时 - 它是在外部创建的实际的应用程序目录,因此无法访问。我的数据库文件也发生了同样的事情。

请参阅下面的修复:

var db = new sqlite3.Database(__dirname + '/app.db');

在 db 文件定义中添加 __dirname 解决了这个问题!