I am new to JS and Node. From what I been reading it seems like ES6 import is not supported in Node so I am forced to use experiment mode (renaming my file to mjs)
This works for the most part unless the mjs file needs to use require. My current solution is to break out the chunk of code that depends on require to a seperate .js file and import that js file
foo.mjs
import readFileSync from './util.js'
...
//orignally just do require('fs') and do fs.readFileSync()
const configFile = readFileSync(configFilePath);
util.js
const fs = require('fs');
const path = require('path');
function readFileSync(filePath) {
console.log(__dirname)
console.log(path.resolve(__dirname, filePath))
return fs.readFileSync(path.resolve(__dirname, filePath), 'utf8');
}
module.exports = readFileSync
Is there a way I can avoid doing this? My app.js has lots of require and I don't want to break out all those parts into separate js files.
I tried changing require to import
// const express = require('express');
import * as express from 'express';
but when run node --experimental-modules app.mjs
I get an error
TypeError: express is not a function
I think I need to either
require in mjsYou have three decent options:
require in ESM codeimport() (dynamic import) in your CJS to import ESM codeThe wrapper to use require in ESM code:
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
const cjsFile = require('./test') // test is regular .js file using module.exports
Dynamic imports:
// foo.mjs:
export const foo = () => true
// index.js:
import('./foo.mjs').then(x => console.log(x.foo()))
Large projects with mixed module types frequently use Babel and/or TypeScript, both of which handle the mixed types just fine. Babel would be simpler to learn and get set up. But if you don't have a ton of code to deal with, the createRequire method works just fine.
As for the issue with Express, it failed because the default export is what you want: import express from 'express', not import * as express....