How To Trick Node.js To Load .js Files As Es6 Modules?
Solution 1:
You can now import .js
file in node v12.x, in 2 steps:
- Add the following line in your
package.json
file:
// package.json
{
"type": "module"
}
- Add
--experimental-modules
flag before the script:
node --experimental-modules index.js
Reference: https://nodejs.org/api/esm.html
Solution 2:
Node.js requires all ES modules should have .mjs extension. Since Node.js support of ES modules is experimental, this is subject to change. A proposal and open pull request are expected to address this problem with package.json esm
flag and --mode
option.
Currently this can be solved with custom ES module loader that hooks into default module resolver and changes module type for some modules:
custom-loader.mjs
import path from'path';
constESM_WITH_JS_EXT = './MyFile.js'; // relative to loader pathconstESM_WITH_JS_EXT_URL = newURL(path.dirname(import.meta.url) + `/${ESM_WITH_JS_EXT}`).href;
exportfunctionresolve(specifier, parentModuleURL, defaultResolver) {
const resolvedModule = defaultResolver(specifier, parentModuleURL);
if (resolvedModule.url === ESM_WITH_JS_EXT_URL)
resolvedModule.format = 'esm';
return resolvedModule;
}
It is used as:
node --experimental-modules --loader ./custom-loader.mjs ./index.mjs
Since there are fundamental differences in how ES and CommonJS modules are evaluated, the changes should be limited to modules that need them.
Solution 3:
I solved exactly this problem with the fabulous esm package. You can enable dynamic (smart) esm module loading package wide, or per run with a flag like this:
node -r esm your/es6/module.js
It also has options to treat every file as a es6 module, or only those ending in '.mjs'. There are other packages out there, but this one just worked.
Solution 4:
Import and export modules using ES6 that work with Node.js
Name files with .mjs
extension instead of .js
Create files
touch main.mjs lib.mjs
main.js
import { add } from'./lib.mjs';
console.log(add(40, 2));
lib.mjs
exportletadd = (x,y) => {
return x + y
}
Run
node --experimental-modulesmain.js
Solution 5:
Here is a module that does what you need esmjs.mjs
import { readFileSync } from'fs'import { fileURLToPath, pathToFileURL } from'url'import { dirname, join } from'path'exportconstjsmodule = (test_url_or_path, module_path) => {
const __filename = test_url_or_path.toLowerCase().startsWith('file:')
? fileURLToPath(test_url_or_path)
: test_url_or_path
const __dirname = dirname(__filename)
const abs_path = join(__dirname, module_path)
const file_url = pathToFileURL(abs_path)
const file_buf = readFileSync(file_url)
const b64 = file_buf.toString('base64')
const moduleData = "data:text/javascript;base64," + b64
returnimport(moduleData)
}
Usage from .mjs
module:
const { hey } = awaitjsmodule(import.meta.url, '../../test-data/mjs.js')
Usage, from .js
file:
const { hey } = awaitjsmodule(__filename, '../../test-data/mjs.js')
Post a Comment for "How To Trick Node.js To Load .js Files As Es6 Modules?"