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

Vite Plugin with ESM support for main #3439

Closed
3 tasks done
joezappie opened this issue Dec 12, 2023 · 18 comments
Closed
3 tasks done

Vite Plugin with ESM support for main #3439

joezappie opened this issue Dec 12, 2023 · 18 comments

Comments

@joezappie
Copy link

joezappie commented Dec 12, 2023

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.2.0

Electron version

v28.0.0

Operating system

Windows 10 22H2

Last known working Electron Forge version

N/A

Expected behavior

I see that V28 brings ESM support (Hooray!). I'd like to switch my projects over but I'm having issues getting the Vite template to build. I successfully got a normal electron-forge app to build but using the vite template I cannot as it still converts it to cjs.

Actual behavior

Vite converts main.js to cjs, in which it then errors out because the package.json has been updated to include "type": "module".

App threw an error during load
ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and 'C:\Users\joeja\projects\deleteme-vite\pack
age.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
    at file:///C:/Users/joeja/projects/deleteme-vite/.vite/build/main.js:1:22
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

Steps to reproduce

  1. yarn create electron-app test-esm-vite --template=vite
  2. Add "type": "module", to package.json
  3. Change forge.config.js to export default
  4. Change the header of src/index.js to:
import { app, BrowserWindow } from "electron";
import path from "path";
import * as url from "url";

import { handleSquirrelEvent } from "./squirrel.js";

const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
  1. Add an esm squirrel event handler that works with import: ./squirrel.js
  2. Change vite.*.config.mjs to vite.*.config.js
  3. Update forge.config.js paths for plugin-vite to remove .mjs

Additional information

Looking through the vite plugin code, there is still a reference stating that Electron doesn't support ESM which is no longer true. Can this be updated?

Line 76 in file: https://github.com/electron/forge/blob/main/packages/plugin/vite/src/ViteConfig.ts

         build: {
            lib: entry
              ? {
                  entry,
                  // Electron can only support cjs.
                  formats: ['cjs'],
                  fileName: () => '[name].js',
                }
              : undefined,

I tried overriding this in my defineConfig({}) but haven't had any luck:

{
            // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`.
            entry: "src/main.js",
            formats: ["es"],
            config: "vite.main.config.js",
          },

I know this is an on going effort to update everything. I'd figure I'd bring it to attention since the code now says something that's untrue and because I can't figure out what the work around to override this.

@joezappie
Copy link
Author

joezappie commented Dec 12, 2023

I found that I can override that setting in vite.main.config.js:

// https://vitejs.dev/config
export default defineConfig({
  resolve: {
    ...
  },
  build: {
    lib: {
      formats: ["es"],
    },
  },
});

I have another issue now though, as in esm __dirname is not available. This is needed to specify the index.html path and the preload file. I changed it to:

const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
...
mainWindow.loadFile(path.join(dirname, "index.html"));

However, Vite replaces import.meta.url with self.location and then Vite errors out ReferenceError: self is not defined.

If I replace them with relative paths, it loads the files but warns it wants an absolute path for preload.js.

Guessing some sort of MAIN_WINDOW_PRELOAD_VITE_ENTRY and MAIN_WINDOW_VITE_ENTRY will need to be generated outside of Vite similar to how the webpack plugin works?

@sparecycles
Copy link

+1.

Thanks for your investigation!

I wonder if you tried import.meta.resolve(...)? It's both more to the point and perhaps vite doesn't try to mess with it?

I'm brought here trying to use both @sveltejs/vite-plugin-svelte which is esm-only, (and so it requires "type": "module" in package.json), and this is tripping me up.

I think I can slap an dist-electron/package.json in with { "type": "commonjs" } as a work-around but it feels a bit horrid. 😉

@Sahasrara
Copy link

The combination of svelte + vite + electron + forge doesn't seem to work unless we have ESM support.

@caoxiemeihao
Copy link
Member

The combination of svelte + vite + electron + forge doesn't seem to work unless we have ESM support.

You can try to this 👉 #3309

The next version of Vite plugin will be use "type"="module" by default, coming soon...

@Sahasrara
Copy link

Is this something that's planned? I'm hoping to use Forge with Svelte + Vite (not SvelteKit).

@sparecycles
Copy link

The "horrid" workaround I suggested seems to be working for me. I've got vite+forge+tailwind+typescript+svelte+melt+workers+import("node:module").register (node20, electron29-alpha) working fine.

@joezappie
Copy link
Author

Aweome! I haven't had a chance to try your suggestion but I'm starting a new project tomorrow and might mess around with it more. Hopefully the official support comes soon but good to know its coming by default soon!

@caoxiemeihao caoxiemeihao linked a pull request Feb 3, 2024 that will close this issue
5 tasks
@caoxiemeihao caoxiemeihao removed a link to a pull request Feb 3, 2024
5 tasks
@caoxiemeihao
Copy link
Member

Fixed by #3468

@adidahiya
Copy link

thanks @caoxiemeihao! any ideas when #3468 might land in a release?

@jerrygreen
Copy link

Wait so I will be able to actually use "type": "module" in my package.json? I need that, too.

Kinda want to use with SvelteKit, – but it only supports esm projects.

@joezappie
Copy link
Author

joezappie commented Feb 25, 2024

Was this supposed to be fixed in the 7.3.0 release? This issue was closed, but even with running a fresh install npm init electron-app@latest my-new-app -- --template=vite, its still using CJS for main and "type":"module" is not in the package.json.

Edit - Hmm yeah, looking through the current code, it doesnt look like theres any changes to the template to use esm and not cjs for main. It still uses mjs files for the config and main.config references formats: ['cjs'], still. Can this issue be reopened?

@joezappie
Copy link
Author

@caoxiemeihao sorry to ping you, but just curious where this issue stands?

@GitMurf
Copy link

GitMurf commented Apr 19, 2024

Any update here? I cannot get esm / type: module to work with forge / vite / typescript.

@sparecycles
Copy link

Strange that this issue is closed, as it appears @caoxiemeihao is still working on it: #3572

@caoxiemeihao
Copy link
Member

caoxiemeihao commented Apr 22, 2024

Strange that this issue is closed, as it appears @caoxiemeihao is still working on it: #3572

v7.3.0 can be implemented through user modification to support ESModule, which is not constrained by @electron-forge/plugin-vite.

#3572 is just making some changes to the template, not a major upgrade.

@sparecycles
Copy link

sparecycles commented Apr 22, 2024

@caoxiemeihao yep, I confirmed this today via these application-side changes

https://github.com/sparecycles/vite-svelte-tailwind-electron/compare/forge-7.3.0..forge-7.3.0-esm and then
https://github.com/sparecycles/vite-svelte-tailwind-electron/compare/forge-7.3.0-rewrite..forge-7.3.0-rewrite-esm-support

@joezappie

I think it's worth trying to apply the extendMainConfig({...}), extendPreloadConfig({...}), extendRendererConfig({...}) from my rewrite of vite.base.config.ts methods to existing templates to see if it "just works", (but I don't intend to support this long-term, nor do I have the resources to debug on a wide variety of platforms at the moment.)

See #3506 (comment)

(EDIT: preload.ts might need to be cjs still... broken)

@caoxiemeihao
Copy link
Member

caoxiemeihao commented Apr 26, 2024

@sparecycles You gave me some inspiration and I updated the API design for migration to 7.3.0+.


BTW, It can support { "type": "module" }. But if you want use the esm, must be make some changes.

- const { app } = reuiqire('electroon');
+ import { app } from 'electron';

@progmars
Copy link

progmars commented Nov 24, 2024

This is still confusing. In the main branch vite template, there still seems to be a mix with mjs and require; no pure js and type=module.

I tried to modify it all manually based on the template, but vite still ended up generating main.js file with require and failed to run it because of package type=module.

While building, vite generates a warning

The CJS build of Vite's Node API is deprecated. See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.

and with VITE_CJS_TRACE=true I see that it comes from node_modules\vite\index.cjs. Why is Electron Forge still triggering cjs and not ESM Vite process?

What is the best way to create ESM-enabled vite project (without Typescript)?

Tried to update devDependencies to electron/forge#main, it required ts-node, which I installed, but then I could not run npm start anymore:

'electron-forge' is not recognized as an internal or external command,
operable program or batch file.

I guess, something differs a lot in main or I don't know how to install main branch in node_modules properly.

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

No branches or pull requests

8 participants