electron-react-boilerplate / electron-react-boilerplate

A Foundation for Scalable Cross-Platform Apps

Home Page:https://electron-react-boilerplate.js.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Electron 28 breaks build: ERR_UNKNOWN_FILE_EXTENSION – Unknown file extension ".ts" for …

slhck opened this issue · comments

Prerequisites

  • Using npm
  • Using an up-to-date main branch
  • Using latest version of devtools. Check the docs for how to update
  • Tried solutions mentioned in #400
  • For issue in production release, add devtools output of DEBUG_PROD=true npm run build && npm start

Expected Behavior

Updating electron should make the app start.

Current Behavior

I updated Electron to 28.0.0, then ran npm install. Now:

➜ npm start

> start
> ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer


> start:renderer
> cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts

Starting preload.js builder...
Starting Main Process...
<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:1212/
<i> [webpack-dev-server] On Your Network (IPv4): http://192.168.0.119:1212/
<i> [webpack-dev-server] On Your Network (IPv6): http://[fe80::1]:1212/
<i> [webpack-dev-server] Content not from webpack is served from '/Users/werner/Documents/Software/electron-react-boilerplate/public' directory
<i> [webpack-dev-server] 404s will fallback to '/index.html'

> start:main
> cross-env NODE_ENV=development electronmon -r ts-node/register/transpile-only .


> start:preload
> cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.preload.dev.ts

[electronmon] waiting for a change to restart it
App threw an error during load
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /Users/werner/Documents/Software/electron-react-boilerplate/src/main/main.ts
    at new NodeError (node:internal/errors:405:5)
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:80:11)
    at defaultGetFormat (node:internal/modules/esm/get_format:125:36)
    at defaultLoad (node:internal/modules/esm/load:89:20)
    at nextLoad (node:internal/modules/esm/loader:163:28)
    at ESMLoader.load (node:internal/modules/esm/loader:603:26)
    at ESMLoader.moduleProvider (node:internal/modules/esm/loader:457:22)
    at new ModuleJob (node:internal/modules/esm/module_job:64:26)
    at ESMLoader.#createModuleJob (node:internal/modules/esm/loader:480:17)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:434:34)
[electronmon] uncaught exception occured
[electronmon] waiting for any change to restart the app

Steps to Reproduce

See above.

Possible Solution (Not obligatory)

Not sure what the issue is. I know that Node v18.19.0 broke ts-node with a similar error message, see TypeStrong/ts-node#1997

Latest known good version for Electron is 27.1.3.

Context

N/A

Your Environment

  • Node version : v18.19.0
  • electron-react-boilerplate version or branch : main
  • Operating System and version : macOS
  • Link to your project : N/A

@slhck same here. Did you find a solution meanwhile?

No, I don't know enough about the internals... I will post a solution should I find one, but in the meantime I'll stay on the last 27 release.

So the only thing I know is that the error comes from Electron itself, but I can't find any issue with the Electron package referencing that error. It's as if it wasn't passed a compiled JS file, instead trying to load a TS file, and, obviously, failing. So perhaps it's the webpack step that doesn't finish properly? I would think that this is due to the underlying ts-node bug.

@amilajack Any ideas?

Hope this will help somebody until the fix is released, because I've spent more time on this than I expected... This is how I managed to configure the boilerplate with Electron 28

Prerequisites:
Node.js: v18.16.0

Dependencies:
"electron": "^28.1.1",
"electron-builder": "^24.6.4",
"@electron/rebuild": "^3.3.0"

Steps:

  1. Remove ts-node dependency - npm uninstall ts-node

  2. Install tsx package - npm i --save tsx

    Package for TS and ESM compilation, supports both:
    https://www.npmjs.com/package/tsx

  3. In every script defined in "scripts" section of package.json make replace ts-node with node --loader tsx
    For example, my "start" script

    before:
    "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer",
    after:
    "start": "node --loader tsx ./.erb/scripts/check-port-in-use.js && npm run start:renderer",

    For the parts where cross-env is used, you may use NODE_OPTIONS like this:
    "start:main": "cross-env NODE_ENV=development NODE_OPTIONS=\"--loader tsx\" electronmon .",

  4. Repeat step 3 for release/app/package.json

  5. Not sure about this step, but I think this issue appeared after version upgrade. If you see Could not detect abi for version... error, install node-abi version (I have v3.54.0) and add this to package.json resolutions:

    "resolutions": {
      "node-abi": "^3.54.0"
    }
    

Thanks for providing these steps. When I apply them to this repo, I get:

➜ npm start       

> start
> node --loader tsx ./.erb/scripts/check-port-in-use.js && npm run start:renderer


node:internal/process/esm_loader:40
      internalBinding('errors').triggerUncaughtException(
                                ^
Error: tsx must be loaded with --import instead of --loader
The --loader flag was deprecated in Node v20.6.0 and v18.19.0

Maybe you are running on an older version of Node?

That said, applying your suggested changes I still get:

➜ npm start

> start
> node --import tsx ./.erb/scripts/check-port-in-use.js && npm run start:renderer


> start:renderer
> cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts

Starting preload.js builder...
Starting Main Process...
<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:1212/
<i> [webpack-dev-server] On Your Network (IPv4): http://192.168.0.119:1212/
<i> [webpack-dev-server] On Your Network (IPv6): http://[fe80::1]:1212/
<i> [webpack-dev-server] Content not from webpack is served from '/Users/werner/Documents/Software/electron-react-boilerplate/public' directory
<i> [webpack-dev-server] 404s will fallback to '/index.html'

> start:main
> cross-env NODE_ENV=development NODE_OPTIONS="--import tsx" electronmon .


> start:preload
> cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.preload.dev.ts

[electronmon] waiting for a change to restart it
App threw an error during load
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /Users/werner/Documents/Software/electron-react-boilerplate/src/main/main.ts
    at __node_internal_captureLargerStackTrace (node:internal/errors:496:5)
    at new NodeError (node:internal/errors:405:5)
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:80:11)
    at defaultGetFormat (node:internal/modules/esm/get_format:125:36)
    at defaultLoad (node:internal/modules/esm/load:89:20)
    at nextLoad (node:internal/modules/esm/loader:163:28)
    at ESMLoader.load (node:internal/modules/esm/loader:603:26)
    at ESMLoader.moduleProvider (node:internal/modules/esm/loader:457:22)
    at new ModuleJob (node:internal/modules/esm/module_job:64:26)
    at #createModuleJob (node:internal/modules/esm/loader:480:17)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:434:34)
[electronmon] uncaught exception occured
[electronmon] waiting for any change to restart the app

Yes, as I specified before, I'm using older version of Node.js - v18.16.0
I guess you may try to make it work with newer version, but steps will be different.

Also I noticed that your start:renderer script is not using NODE_OPTIONS I mentioned in the step 3 (same for start:preload)

I can confirm that your suggestions work with older versions of Node, where one has to use --loader. It breaks with v18.18 onwards, which also makes tsx ask for the --import option instead of --loader.

And once I use --import, it no longer works. Specifically, the error only affects npm run start:main. I feel like the loader part does not get forwarded properly to electron itself when using these newer Node versions.

Curiously, when I switch to Node v18.19.0, and use the old Electron version (v26.2.1) as shipped with this repo, and I try to use the --import option with tsx, I get:

➜ npm run start:main

> start:main
> cross-env NODE_ENV=development NODE_OPTIONS="--import tsx" electronmon .

[electronmon] waiting for a change to restart it
electron: --import is not allowed in NODE_OPTIONS
[electronmon] app exited with code 9, waiting for change to restart it

I am a bit lost here; I don't know enough about Node's internals, e.g. how hooks work.

Same issue here. Have to stay at v27 for now