Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forge make combined with vite is creating an incomplete asar #3738

Open
3 tasks done
steveoh opened this issue Oct 17, 2024 · 19 comments
Open
3 tasks done

Forge make combined with vite is creating an incomplete asar #3738

steveoh opened this issue Oct 17, 2024 · 19 comments

Comments

@steveoh
Copy link

steveoh commented Oct 17, 2024

Pre-flight checklist

  • I have read the contribution documentation for this project.
  • I agree to follow the code of conduct that this project uses.
  • I have searched the issue tracker for a bug that matches the one I want to file, without success.

Electron Forge version

7.5.0

Electron version

33.0.1

Operating system

windows 11

Last known working Electron Forge version

7.4.0

Expected behavior

npm run make creates an asar file that includes the node_modules and the app can run on windows successfully.

Actual behavior

node_modules aren't present and install fails with ERR_MODULE_NOT_FOUND

Steps to reproduce

  1. npm run make
  2. go to the out folder and find open the nupkg/resources/app.asar file
  3. run npx @electron/asar extract app.asar app
  4. notice there is no node_modules

Additional information

This is only happening on windows as I believe that is the only place that asar is used.
We are using vite instead of webpack.

Image

The main.js file from within the asar in the error message imports the following

import "node:path";
import "node:url";
import "electron";
import "electron-window-state";
import "update-electron-app";
import "./main-DWMHPuxT.js";
import "electron-squirrel-startup";
import "fs";
import "path";
import "url";
import "stream";
import "zlib";

Where electron-window-state and update-electron-app and I assume electron-squirrel-startup are not available to be imported.

@justgo97
Copy link

I'm not sure about 7.5.0 but in earlier versions it was needed to move electron-window-state and any other dependency that isn't getting bundled correctly to devDependencies in package.json, This is a known mismatch between vite and webpack in forge.

@steveoh
Copy link
Author

steveoh commented Oct 17, 2024

This works as expected downgrading to 7.4.0. I'll give this a try but no bundles are getting added to the app.asar file at 7.5.0.

Well now I'm getting a require is not defined error after making the project. :/

@XianZhengquan
Copy link

@steveoh I use electron-log and it works fine after downgrading.

@knice88
Copy link

knice88 commented Oct 29, 2024

I've had this happen to ubuntu as well, but found a way to get the trick:
When you run "npm run make" for the first time, open the @electron-forge/plugin-vite configuration, get the .vite/ folder, and delete the out/ folder; Then turn off the @electron-forge/plugin-vite config and run "npm run make" again to get a complete installer

@AimForNaN
Copy link

Ran into a similar issue with other packages. Found a work-around and modified it to work for me. Seems @electron/packager related.

// forge.config.js

const { spawn } = require('node:child_process');

module.exports = {
	hooks: {
		packageAfterPrune: async (config, build_path) => {
			const vite_config = await import('./vite.preload.config.mjs');
			const external = vite_config?.default?.build?.rollupOptions?.external || [];
			const commands = [
				'install',
				'--no-package-lock',
				'--no-save',
				...external,
			];

			return new Promise((resolve, reject) => {
				npm = spawn('npm', commands, {
					cwd: build_path,
					stdio: 'inherit',
					shell: true,
				});

				npm.on('close', (code) => {
					if (0 === code) {
						resolve();
						return;
					}

					reject(`Process exited with code: ${code}`);
				});

				npm.on('error', reject);
			});
		},
	},
	// ...
};

@hichemfantar
Copy link

hichemfantar commented Nov 3, 2024

same issue here, happens when trying to load a json file

const filePath = path.join(__dirname, "schedule.json");
const data = fs.readFileSync(filePath , "utf-8");

@hichemfantar
Copy link

hichemfantar commented Nov 3, 2024

temp workaround is to disable asar by modifying the following properties in forge.config.ts

const config: ForgeConfig = {
  packagerConfig: {
    asar: false,
  },
  plugins: [
    new FusesPlugin({
      [FuseV1Options.OnlyLoadAppFromAsar]: false,
    }),
  ],
};

@an78mK89fy
Copy link

This error is not related to ASAR. Even if ASAR is disabled, the error is still reported. I think it is a vite plug-in problem. It works normally in 7.4.0

@DrShortStack
Copy link

I'm getting this issue on 7.4.0, I can't find any errors in the logs to understand what's causing it.

@GitMurf
Copy link

GitMurf commented Jan 17, 2025

Still having these same problems with forge 7.6. The docs state (see screenshot below) that native node modules should work "out of the box", which they do not. But also trying any of the "workarounds" is not working either... added to build.rollupOptions.external etc. and still not getting any node_modules included in the package.

This is starting to become very frustrating. Last year spent months figuring out workarounds to make 7.3/7.4 work with vite to properly package the correct node modules... finally got it working, but now to update to the current stable version of electron (v34) need to update forge as well and now everything is broken again with native modules.

Image

I hate to make a negative post but this is becoming a pattern and a real issue any time we have to consider updating anything with electron forge (for vite). cc @erickzhao

@lorenzjosten
Copy link

lorenzjosten commented Jan 19, 2025

I would like to know if I am also affected by the issue at hand. - So that I can put my mind to rest, after having put in far too many hours to get the release build of my project to run with better-sqlite3 marked as an external lib. I have scrolled through docs, forums and bug reports looking for a solution. But I am still stuck.

I am using a MacBook (arm64 with M2 chip). I have setup my project with

create-electron-app . --template=vite-typescript

After running the electron forge package command

yarn run package

and starting the bundled app

open out/test-darwin-arm64/test.app  

I am running into this error:

Image
package.json
{
  "name": "test",
  "productName": "test",
  "version": "1.0.0",
  "description": "My Electron application description",
  "main": ".vite/build/main.js",
  "scripts": {
    "start": "electron-forge start",
    "package": "electron-forge package",
    "make": "electron-forge make",
    "publish": "electron-forge publish"
  },
  "devDependencies": {
    "@electron-forge/cli": "^7.6.0",
    "@electron-forge/maker-deb": "^7.6.0",
    "@electron-forge/maker-rpm": "^7.6.0",
    "@electron-forge/maker-squirrel": "^7.6.0",
    "@electron-forge/maker-zip": "^7.6.0",
    "@electron-forge/plugin-auto-unpack-natives": "^7.6.0",
    "@electron-forge/plugin-fuses": "^7.6.0",
    "@electron-forge/plugin-vite": "^7.6.0",
    "@electron/asar": "^3.2.18",
    "@electron/fuses": "^1.8.0",
    "@types/bootstrap": "^5",
    "@types/electron-squirrel-startup": "^1",
    "@types/node": "^22.10.5",
    "@vitejs/plugin-vue": "^5.2.1",
    "electron": "33.3.1",
    "ts-node": "^10.9.2",
    "typescript": "^5.7.2",
    "vite": "^5.0.12",
    "vue": "^3.5.13",
    "vue-tsc": "^2.2.0"
  },
  "keywords": [],
  "author": {
    "name": "***",
    "email": "***"
  },
  "license": "MIT",
  "packageManager": "[email protected]+sha512.5383cc12567a95f1d668fbe762dfe0075c595b4bfff433be478dbbe24e05251a8e8c3eb992a986667c1d53b6c3a9c85b8398c35a960587fbd9fa3a0915406728",
  "dependencies": {
    "@popperjs/core": "^2.11.8",
    "@types/better-sqlite3": "^7.6.12",
    "apexcharts": "^4.3.0",
    "axios": "^1.7.9",
    "better-sqlite3": "^11.8.1",
    "bootstrap": "^5.3.3",
    "bootstrap-icons": "^1.11.3",
    "electron-squirrel-startup": "^1.0.1",
    "pinia": "^2.3.0",
    "vue-router": "^4.5.0",
    "vue3-apexcharts": "^1.8.0"
  }
}
vite.main.config.ts
import path from 'path';
import { defineConfig } from 'vite';

// https://vitejs.dev/config
export default defineConfig({
    resolve: {
        alias: {
            '@': path.resolve(__dirname, './src')
        }
    },
    build: {
        rollupOptions: {
            external: [
                'better-sqlite3'
            ],
        },
    }
});
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 { 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: {
      unpack: "**/node_modules/better-sqlite3/**/*"
    },
  },
  rebuildConfig: {
    onlyModules: ['better-sqlite3'],
    buildFromSource: true,
    force: true,
  },
  makers: [new MakerSquirrel({}), new MakerZIP({}, ['darwin']), new MakerRpm({}), new MakerDeb({})],
  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;

Note that leaving out the AutoUnpackNatviesPlugin or the rebuildConfig does not change the behaviour. Cheers!

@hichemfantar
Copy link

temp workaround is to disable asar by modifying the following properties in forge.config.ts

const config: ForgeConfig = {
packagerConfig: {
asar: false,
},
plugins: [
new FusesPlugin({
[FuseV1Options.OnlyLoadAppFromAsar]: false,
}),
],
};

again for anyone willing to forgo asar, disabling it fixed everything in my case

@GitMurf
Copy link

GitMurf commented Jan 20, 2025

@lorenzjosten yes the problem is the vite plugin for forge is not packaging any node_modules which means if you use any node native libs like better-sqlite it will not work.

It will work in dev because forge/vite uses the external package config option to know to leverage your local node_modules for those native libs like better-SQLite. But then when packaged for production those required node_modules are missing so everything breaks.

@edymusajev

This comment has been minimized.

@steveoh
Copy link
Author

steveoh commented Jan 20, 2025

I ended up recreating my app from the newest forge template and everything started working again. You might give that a try.

@GitMurf
Copy link

GitMurf commented Jan 20, 2025

I ended up recreating my app from the newest forge template and everything started working again. You might give that a try.

@steveoh a few follow-up questions:

  1. Are you using forge packager for the production package? Because dev mode works fine, the problem is when packaging it for production use.
  2. Are you using asar?
  3. Are you using any node native addons (modules)? For example, sqlite.
  4. Can you open the asar (7zip should work) and see if a node_modules folder is included and if so, what libs are included in it?

I have also tried from scratch from the current 7.6 template and native modules like sqlite do not get packaged (as described in earlier comments).

@an78mK89fy
Copy link

I ended up recreating my app from the newest forge template and everything started working again. You might give that a try.

It's amazing that I worked normally in version 7.4, but I cloned a 7.4 version forge from a previous GitHub project to write the project. At first, it worked normally, but after a period of time, the package results still reported errors. When the 7.5 and 7.6 versions were updated, I tried to solve the problem. Occasionally, the package was fine, but most of the time it was not executed correctly. I have tried using type=module, but there are still problems. The current forge cannot be used out of the box. The simplest temporary solution: When using the package, use the hook to copy package.json to the path after the package, and then use JavaScript to call npm i to download the module. This is my whimsical idea, I haven't tried it yet, and I can't use the computer recently. Please help me try it, lol

@an78mK89fy
Copy link

In addition, it is not just the vite template, even if you do not set up a template or use webpack, this problem may be caused by the package

@eelenkoen-ns
Copy link

eelenkoen-ns commented Jan 22, 2025

@lorenzjosten i've got a similar issue, with another native library (node-rfc), and was able to package succesfully using the following:

I managed to trace the issue and I believe it is indeed related to the vite plugin. If I add the following to my package.json:

"config": {
    "forge": {
      "packagerConfig": {
        "extraResource": [
          "./node_modules/node-rfc"
        ],
        "derefSymlinks": true
      }
    }
  }

It works now as expected. I can even delete the entire forge.config.ts and it still works, so I guess this snippet replaces entirely the forge config, meaning no vite pugin is used.

Originally posted by @mtharrison in #3734

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests