node:test in combination with Electron Forge Typescript project

275 Views Asked by At

I am working on an Electron App created with the Electron Forge 'Webpack + Typescript' template project.

Everything is working fine but now I wanted to add unit-test using node:test.

I got my test working but only if i add "type": "module", to my package.json. Otherwise running the test says:

> {myproject}@0.0.1 test
> glob -c  "node --loader tsx --no-warnings --test" "tests/**/*.ts"

{myrepo}\tests\server-log\parse-lines.ts:1
  import assert from 'assert/strict';
  ^^^^^^

  SyntaxError: Cannot use import statement outside a module

But when I then do npm run start to start the Electron app, I get:

✖ Loading configuration                                                                                                                              
  › Must use import to load ES Module: {myrepo}\forge.config.ts                   
  require() of ES…                                                                                                                                   
◼ Preparing native dependencies                                                                                                                      
◼ Running generateAssets hook                                                                                                                        

An unhandled rejection has occurred inside Forge:
Error: Must use import to load ES Module: {myrepo}\forge.config.ts
require() of ES modules is not supported.
require() of {myrepo}\forge.config.ts from {myrepo}\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 {myrepo}\package.json.

So I tried many things, like change "module" in tsconfig.json / compileOptions to "es2015", but could not get it to work.

My tsconfig.json:

{
  "compilerOptions": {
    "target": "ES6",
    "allowJs": true,
    "module": "commonjs",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "noImplicitAny": true,
    "sourceMap": true,
    "baseUrl": ".",
    "outDir": "dist",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true,
    "paths": {
      "*": ["node_modules/*"]
    }
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "src/**/*.ext",
  ]
}

I run tests with npm run test:

    "test": "glob -c  \"node --loader tsx --no-warnings --test\" \"tests/**/*.ts\"",

Update

So after reading this: Support Node's ES Modules #21457 1099904505 I realised that trying to make Electron work with ESM is just not an option.

So I tried this:

I renamed my test file so the extension is .mts. This seems to get me a step further, but then the problem becomes how to import the .ts file that has the function I want to test.

  • using accolades in import seems to be the problem so i removed { and }
  • this gives me Module '"{myrepo}/src/server-log"' has no default export. Did you mean to use 'import { xyz } from "{myrepo}/src/server-log"' instead?
  • adding default to that function helps (export default function), but running the test gives me ^^^^^^ SyntaxError: Unexpected token 'export'

Update 2

I thought I could make this work by running tsx with it's own tsconfig.json, or beginning the script with cd scripts && and then having a package.json in that folder with "type": "module" so the --test file(s) run with ESM settings....

Did not get it to work yet though....

1

There are 1 best solutions below

4
Sander_P On

I got it to work eventually but using ts-node (or more precisely ts-node-script Don't know why i wrote this, ts-node works fine) instead of using node --loader tsx ..., or something like that.

Using node --loader and/or tsx put me in a maze of error messages like:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts",
SyntaxError: Unexpected token 'export',
module has no default export,
exports is not defined in ES module scope,
Cannot use import statement outside a module.

All the suggestions I could find on how to solve these errors, included things I needed to change in my already existing Electron Forge Webpack & Typescript project, that would have severe consequences and/or break it.

My solution

I installed glob (npm i glob --save-dev), and ts-node (npm i ts-node --save-dev).

And added this to my scripts:

  "test": "glob -c \"ts-node\" \"./tests/**/*.ts\""