When I upgrade a Node.js 16/Typescript project to Node 18 and newest module versions, I got a strange error message for import of module emailjs.
rc/main.ts:4:95 - error TS1479: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("emailjs")' call instead.
To convert this file to an ECMAScript module, change its file extension to '.mts' or create a local package.json file with `{ "type": "module" }`.
4 import { SMTPClient } from 'emailjs';
The reason is clear, new emailjs module is written as ECMAScript module ("type" : "module" in it's package.json), while my program is build as common.js module, as defined in tsconfig.json (see @tsconfig/node18).
Changing my project to an ECMAScript module solves this problem, but then I get problems on import of classes from my project:
src/main.ts:5:22 - error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './test.js'?
5 import { Test } from './test';
Adding a .js to the import solves that problem:
import { Test } from './test.js';
Now I am a little bit confused:
- I write ts files but have to include js files
- On installed packages I have not to use a
.js
There is also some information in Mix CommonJS and ES6 modules in same project, but the answer there is very general and not handling Node.js/Typescript projects in detail.
My Questions:
- What is the proper way to solve this commonjs/module confusion in Node.js/Typecript projects?
- Is it recommended to change projects to the ECMAScript module style?
- Is there a way to stay on commonjs when importing node modules written in ECMAScript module style?