Bad experience of migrating Electron application to ECMAScript modules

While working on my starting template for Electron applications, I decided to completely abandon CommonJS modules and use exclusively ECMAScript modules (hereinafter ES modules or ESM).





I really want to have a consistent style of code everywhere. In my project, like many others, the source code itself is written using ES modules, and everything else (tests, configuration files, additional scripts for building) is written using CommonJS modules. It bothers me a lot and I want everything to be in the same style - ESM.





Briefly about modular systems in NodeJS

Since version 13, NodeJS supports two module systems:





  • CommonJS: a function is used to connect a module require()



    ;





  • ECMAScript: a keyword import



    or function is used to connect a module import()



    ;





It is important to know:





  • You cannot use both require



    and and in the same file import



    . Either one or the other.





  • In an ES module, you can connect another ES or CommonJS module.





  • In a CommonJS module, you can connect exclusively CommonJS modules.





How NodeJS chooses a system for a specific file

Everything is simple here. There are two extensions for files: .cjs



and .mjs



which define that this is a CommonJS or ES module, respectively.





, package.json



type



commonjs



module



- .js



.





Electron

Electron ? main.js



( background.js



) -- , , , , api . , :





const { app, BrowserWindow } = require('electron')

app.whenReady().then(() =>
  new BrowserWindow().loadFile('index.html')
)

app.on('window-all-closed', () => app.quit())
      
      



: .





ESM, package.json



"type": "module"



main.js



:





- const { app, BrowserWindow } = require('electron')
+ import { app, BrowserWindow } from 'electron'
      
      



:





Error [ERR_REQUIRE_ESM]: Must use import to load ES Module
      
      



. electron v12 NodeJS 14.15. ESM .





CommonJS

, electron, , JavaScript . -- require



:









electron /path/to/main.js
      
      



- , electron





require('/path/to/main.js')
      
      



electron CommonJS . main.js



-- ES . CommonJS ES . .





ESM-.





ES - Electron. , - .





, . , ESM CommonJS Electron. nodeJS .cjs



.





, .





JavaScript .js



. , .





tsc



esbuild



, , . .js



.





/ JavaScript .js



. .cjs



.





Vite, , [filename].[hash].cjs



. loader .cjs



. PR ( ) .cjs



JavaScript.





electron-builder

. ES , Vite CommonJS Electron.





, . electron-builder



. :





  • electron-builder



    read-config-file



    .





  • read-config-file



    CommonJS , require('/path/to/config.js')



    .





  • CommonJS ES .





, electron-builder



ES .





electron-builder



CommonJS .cjs



. CommonJS .





, .





, read-config-file



.cjs



JavaScript:





if (config.endsWith('.js')) {
    require(config)
} else {
    // ...   ,   JavaScript
}
      
      



PR , .





electron-builder



JavaScript package.json



"type": "module"



.





.js



.json



, .





, , ES .





  • eslint. eslint ESM. .





    -- - require



    .eslintrc.js



    . .eslintrc.cjs



    CommonJS.





    . IDE .eslintrc.cjs



    eslint.





  • -- dotenv



    . ESM, .





  • Jest , ES .





- , . , , - . . . .








All Articles