Electron Forge + SerialPort 本机依赖项打包不起作用

问题描述 投票:0回答:1

我正在为 Meshtastic 开发一个开源固件更新应用程序 (https://github.com/medentem/electron-flasher/)。该应用程序是与 Vite for Electron 捆绑在一起的 ReactJS/TS 应用程序。当在 OSX (

electron-forge start
) 上本地运行时,它运行完美,并且本机依赖项(串行端口和驱动器列表)似乎被正确引用。但是,在捆绑 OSX 应用程序进行分发 (
electron-forge make
) 后,生成的应用程序启动时会出现以下错误:

Uncaught Exception:
Error: Cannot find module 'serialport'
Require stack:
- /Users/medentem/Dev/electron-flasher/out/electron-flasher-darwin-arm64/electron-flasher.app/Contents/Resources/app.asar/.vite/build/main.js
- 
at Module._resolveFilename (node:internal/modules/cjs/loader:1232:15)
at s._resolveFilename (node:electron/js2c/browser_init:2:124038)
at Module._load (node:internal/modules/cjs/loader:1058:27)
at c._load (node:electron/js2c/node_init:2:17025)
at Module.require (node:internal/modules/cjs/loader:1318:19)
at require (node:internal/modules/helpers:179:18)
at Object.<anonymous> (/Users/medentem/Dev/electron-flasher/out/electron-flasher-darwin-arm64/electron-flasher.app/Contents/Resources/app.asar/.vite/build/main.js:1:214)
at Module._compile (node:internal/modules/cjs/loader:1484:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1564:10)
at Module.load (node:internal/modules/cjs/loader:1295:32)

我确认

serialport
drivelist
包在 vite 中配置为外部(参见 https://github.com/medentem/electron-flasher/blob/main/vite.main.config.ts),以及
electron-forge
配置
AutoUnpackNativesPlugin
以确保两个包都被重建并包含在 asar 包之外。但这似乎不起作用。

我还尝试使用

electron-builder
生成 OSX 应用程序,但在这种情况下,该应用程序甚至不会启动。

预先感谢您的帮助!

electron vite electron-builder electron-forge
1个回答
0
投票

经过很多个小时的尝试和失败,我能够获得正确的配置来构建项目。

主要学习内容:

  1. 使用 forge 和 vite 时,构建输出必须位于 .vite 文件夹中。
  2. 电子本身应该列在
    external
    汇总选项中。
  3. 渲染器配置需要一个
    base
    路径才能正确解析路径。
  4. 使用
    emptyOutDir
    配置值是......冒险的,因为它取决于 forge 构建包的顺序。我发现在
    vite.main.config.ts
    配置中关闭它是有效的,否则新的子目录在构建后就会被吹走。

这是配置的快照 - 有关最新配置,请查看问题中链接的存储库。

vite.main.config.ts

import { defineConfig } from "vite";
import { builtinModules } from "node:module";

export default defineConfig({
  build: {
    sourcemap: true,
    outDir: ".vite", // Output directory set to .vite
    lib: {
      entry: "src/main.ts",
      formats: ["cjs"],
    },
    rollupOptions: {
      external: ["electron", ...builtinModules, "serialport", "drivelist"],
    },
  },
});

vite.preload.config.ts

import { defineConfig } from "vite";
import { builtinModules } from "node:module";

export default defineConfig({
  build: {
    sourcemap: true,
    outDir: ".vite/preload", // Output directory set to .vite
    emptyOutDir: true,
    lib: {
      entry: "src/preload.ts",
      formats: ["cjs"],
    },
    rollupOptions: {
      external: ["electron", ...builtinModules],
      output: {
        entryFileNames: "[name].js",
      },
    },
  },
});

vite.renderer.config.ts

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  base: "./",
  build: {
    sourcemap: true,
    outDir: ".vite/renderer", // Output directory set to .vite
    emptyOutDir: true,
  },
});

forge.config.ts

import type { ForgeConfig } from "@electron-forge/shared-types";
import { AutoUnpackNativesPlugin } from "@electron-forge/plugin-auto-unpack-natives";
import { MakerSquirrel } from "@electron-forge/maker-squirrel";
import { MakerZIP } from "@electron-forge/maker-zip";
import { MakerDeb } from "@electron-forge/maker-deb";
import { MakerDMG } from "@electron-forge/maker-dmg";
import { MakerRpm } from "@electron-forge/maker-rpm";
import { VitePlugin } from "@electron-forge/plugin-vite";
import { FusesPlugin } from "@electron-forge/plugin-fuses";
import { FuseV1Options, FuseVersion } from "@electron/fuses";

const config: ForgeConfig = {
  packagerConfig: {
    asar: true,
    ignore: [/\/\.(?!vite)/],
  },
  makers: [
    new MakerSquirrel({}),
    new MakerZIP({}, ["darwin"]),
    new MakerRpm({}),
    new MakerDeb({}),
    new MakerDMG(),
  ],
  rebuildConfig: {
    force: true,
    onlyModules: ["serialport", "drivelist"],
  },
  plugins: [
    new AutoUnpackNativesPlugin({}),
    new VitePlugin({
      // `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc.
      // If you are familiar with Vite configuration, it will look really familiar.
      build: [
        {
          // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`.
          entry: "src/main.ts",
          config: "vite.main.config.ts",
          target: "main",
        },
        {
          entry: "src/preload.ts",
          config: "vite.preload.config.ts",
          target: "preload",
        },
      ],
      renderer: [
        {
          name: "main_window",
          config: "vite.renderer.config.ts",
        },
      ],
    }),
    // Fuses are used to enable/disable various Electron functionality
    // at package time, before code signing the application
    new FusesPlugin({
      version: FuseVersion.V1,
      [FuseV1Options.RunAsNode]: false,
      [FuseV1Options.EnableCookieEncryption]: true,
      [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
      [FuseV1Options.EnableNodeCliInspectArguments]: false,
      [FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
      [FuseV1Options.OnlyLoadAppFromAsar]: true,
    }),
  ],
};

export default config;
© www.soinside.com 2019 - 2024. All rights reserved.