Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ElectronJS Must use import to load ES Module

I am super new to Electron and I am working on a personal learning project. I started from the official Starter Guide with few customizations:

  • Using TypeScript
  • Using ES6 modules
  • Using ESLint
  • Moving all tsc output to dist folder

When I run npm start I get the following error:

App threw an error during load
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: F:\Gabriele\DEV\arcanium\dist\main.js
require() of ES modules is not supported.
require() of F:\Gabriele\DEV\arcanium\dist\main.js from F:\Gabriele\DEV\arcanium\node_modules\electron\dist\resources\default_app.asar\main.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename F:\Gabriele\DEV\arcanium\dist\main.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from F:\Gabriele\DEV\arcanium\package.json.

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1096:13)
    at Module.load (internal/modules/cjs/loader.js:935:32)
    at Module._load (internal/modules/cjs/loader.js:776:14)
    at Function.f._load (electron/js2c/asar_bundle.js:5:12913)
    at loadApplicationPackage (F:\Gabriele\DEV\arcanium\node_modules\electron\dist\resources\default_app.asar\main.js:110:16)
    at Object.<anonymous> (F:\Gabriele\DEV\arcanium\node_modules\electron\dist\resources\default_app.asar\main.js:222:9)   
    at Module._compile (internal/modules/cjs/loader.js:1078:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1108:10)
    at Module.load (internal/modules/cjs/loader.js:935:32)
    at Module._load (internal/modules/cjs/loader.js:776:14)

Here is my package.json file

{
  "main": "dist/main.js",
  "type": "module",
  "scripts": {
    "start": "npm run build && electron ./dist/main.js",
    "build": "tsc && npm run lint",
    "lint": "npx eslint --fix"
  },
  "devDependencies": {
    "@tsconfig/node16": "^1.0.1",
    "@typescript-eslint/eslint-plugin": "^4.28.3",
    "@typescript-eslint/parser": "^4.28.3",
    "electron": "^13.1.7",
    "eslint": "^7.30.0",
    "eslint-plugin-react": "^7.24.0",
    "prettier": "^2.3.2",
    "typescript": "^4.3.5"
  }
}

And my tsconfig.json file

{
  "extends": "@tsconfig/node16/tsconfig.json",
  "compilerOptions": {
    "target": "ES6",
    "module": "ES6",
    "moduleResolution": "node",
    "sourceMap": true,
    "experimentalDecorators": true,
    "removeComments": true,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "allowJs": true,
    "outDir": "dist"
  },
  "include": ["src"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

And my .eslintrc file

{
  "env": {
    "browser": true,
    "es2021": true,
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  "plugins": ["react", "@typescript-eslint"],
  "rules": {
    "indent": ["warn", 2],
    "linebreak-style": ["warn", "win"],
    "quotes": ["warn", "double"],
    "semi": ["error", "always"],
    "curly": "warn"
  },
  "ignorePatterns": "dist"
}

Other than those, I just changed the require statements to import ones in main.js:

import { app, BrowserWindow } from "electron";
import path from "path";

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: { preload: path.join(__dirname, "preload.js") },
  });

  win.loadFile("index.html");
}

app.whenReady().then(() => {
  createWindow();

  app.on("activate", function () {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

app.on("window-all-closed", function () {
  if (process.platform !== "darwin") {
    app.quit();
  }
});

My questions are:

  1. I cannot find any require in dist folder, as tsc leaves the main.js file as is, with the import statements. What that error actually means?

  2. What I want to achieve, is that I want to write TS code in ES6 fashion and let it be compiled down to anything that just works (I kept ES6 in both target and module tsc options), so I guess I should not be forced to compile down to ES5, right? But trying with target as ES5 the error doesn't change. I am totally puzzled...

  3. Probably the right answer: am I missing something BIG in this picture?

like image 429
Gabriele Buffolino Avatar asked Sep 01 '25 16:09

Gabriele Buffolino


1 Answers

The easiest solution is to use "module": "CommonJS" in your tsconfig.json. Node doesn't have great support for ES6 imports, though you can tell it to use them if you add "type": "module" to your package.json.

like image 198
Richard Dunn Avatar answered Sep 04 '25 07:09

Richard Dunn