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....
I got it to work eventually but using
ts-node(or more preciselyDon't know why i wrote this,ts-node-scriptts-nodeworks fine) instead of usingnode --loader tsx ..., or something like that.Using
node --loaderand/ortsxput 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: