forge icon indicating copy to clipboard operation
forge copied to clipboard

"type": "module" in package.json for Vite templates

Open cherewaty opened this issue 1 year ago • 14 comments

Pre-flight checklist

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

Electron Forge version

7.3.0

Electron version

29.0.1

Operating system

macOS 14.3.1

Last known working Electron Forge version

No response

Expected behavior

I wanted to try out the newly stable @remix-run/dev Vite plugin in combination with electron-forge. I initialized a new project with the create-electron-app vite-typescript template, then started layering on pieces like dev and build scripts in package.json.

Actual behavior

I got remix vite:dev working with an isolated vite.remix.config.ts, but then remix vite:build ran into SyntaxError: Cannot use import statement outside a module. Adding "type": "module" to my-app's package.json seemed to fix the problem, but then electron-forge scripts started failing.

Steps to reproduce

For vite-typescript template:

  • npm init [email protected] my-app -- --template=vite-typescript
  • Add "type": "module" to package.json.
  • npm start
An unhandled rejection has occurred inside Forge:
Error: Must use import to load ES Module: /my-app/forge.config.ts
require() of ES modules is not supported.
require() of /my-app/forge.config.ts from /my-app/node_modules/@electron-forge/core/dist/util/forge-config.js is an ES module file as it is a .ts file whose nearest parent package.json contains "type": "module" which defines all .ts files in that package scope as ES modules.
Instead change the requiring code to use import(), or remove "type": "module" from /my-app/package.json

For vite template:

  • npm init [email protected] my-app -- --template=vite
  • Add "type": "module" to package.json.
  • npm start
An unhandled rejection has occurred inside Forge:
Error [ERR_REQUIRE_ESM]: require() of ES Module /my-app/forge.config.js from /my-app/node_modules/@electron-forge/core/dist/util/forge-config.js not supported.
forge.config.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead either rename forge.config.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in /my-app/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).
at exports.default (/my-app/node_modules/@electron-forge/core/dist/util/forge-config.js:140:26)
at async /my-app/node_modules/@electron-forge/core/dist/api/start.js:44:35
at async Task.task (/my-app/node_modules/@electron-forge/tracer/dist/index.js:58:20)
at async Task.run (/my-app/node_modules/listr2/dist/index.cjs:978:11)
at async /my-app/node_modules/p-map/index.js:57:22

Additional information

Seems related to https://github.com/electron/forge/issues/3439, and does not appear to be solved with https://github.com/electron/forge/pull/3468

This is likely causing friction still with SvelteKit as well.

cherewaty avatar Feb 23 '24 01:02 cherewaty

#3468 did not fix my issue #3439 unfortunately.

joezappie avatar Feb 25 '24 18:02 joezappie

I just went through this. Change forge.config.ts to forge.config.cts. In vite.main.config.ts, change formats from ['cjs'] to ['es']. You will also need to polyfill or get rid of __dirname and require() in main.ts. You. can use https://www.npmjs.com/package/vite-plugin-require to polyfill require. I just got rid of __dirname. Here is my (super professional) sandbox. I was also testing support for TypeScript 5 decorators, which do work.

jdms754 avatar Feb 28 '24 01:02 jdms754

@jdms754, I followed your steps but got this error: Error: Unable to use specified module loaders for ".cts". maybe I'm missing some config?

junagao avatar Feb 29 '24 12:02 junagao

@jdms754 thanks a lot. That's worked!

bqhuyy avatar Feb 29 '24 12:02 bqhuyy

@jdms754 I have started fresh and it worked now. thank you! ❤️

the difference I had was that in the tsconfig.json file I had "module": "es2022" instead of "module": "nodenext".

junagao avatar Feb 29 '24 14:02 junagao

What about when one wants to use moduleResolution bundler? moduleResolution NodeNext isn't technically correct given that forge uses vite/webpack to build the project.

RobertWHurst avatar Apr 13 '24 08:04 RobertWHurst

I just went through this. Change forge.config.ts to forge.config.cts. In vite.main.config.ts, change formats from ['cjs'] to ['es']. You will also need to polyfill or get rid of __dirname and require() in main.ts. You. can use https://www.npmjs.com/package/vite-plugin-require to polyfill require. I just got rid of __dirname. Here is my (super professional) sandbox. I was also testing support for TypeScript 5 decorators, which do work.

Thanks! And for those who are looking for a quick replacement of __dirname, this seems to be working for me

import * as url from 'node:url';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
// use __dirname now

jgresham avatar Apr 16 '24 17:04 jgresham

@joezappie any luck on figuring this out? I was also confused by why your gh issue xxx was closed when it does not appear ESM has been addressed with the vite-typescript template as in v7.4 I still see commonjs in tsconfig and the build > lib > format as 'cjs' in the vite config. Thanks in advance if there is any help you can provide me based on your own troubleshooting and research!

GitMurf avatar Apr 20 '24 00:04 GitMurf

I have not had any luck in getting esm to work in main yet. I ended up just using electron-vite for my current project instead. Hopefully I can switch back to forge in the near future once this is supported.

joezappie avatar Apr 20 '24 00:04 joezappie