Node: ECMAScript Modules not working

Created on 6 Nov 2017  路  10Comments  路  Source: nodejs/node

  • Version: 9.0.0
  • Platform: Windows
  • Subsystem: 10


Command:

node --experimental-modules scripts\es6modules.js

Code:

import * as fs from 'fs';

const start = async () => {
    const buffer = fs.readFileSync(`${__filename}`)
    const string = buffer.toString();
    console.log(string);
}

start();

Error:

patrikx3@WORKSTATION G:\Projects\patrikx3\play
> node --experimental-modules scripts\es6modules.js
(node:10488) ExperimentalWarning: The ESM module loader is experimental.
G:\Projects\patrikx3\play\scripts\es6modules.js:1
(function (exports, require, module, __filename, __dirname) { import * as fs from 'fs';
                                                              ^^^^^^

SyntaxError: Unexpected token import
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:152:10)
    at Module._compile (module.js:605:28)
    at Object.Module._extensions..js (module.js:652:10)
    at Module.load (module.js:560:32)
    at tryModuleLoad (module.js:503:12)
    at Function.Module._load (module.js:495:3)
    at createDynamicModule (internal/loader/ModuleRequest.js:43:15)
    at setExecutor (internal/loader/ModuleWrap.js:39:23)
    at file:///G:/Projects/patrikx3/play/scripts/es6modules.js:8:36
ES Modules question

Most helpful comment

esm is not node-specific, and node-specific "globals" (such as __dirname and module) will not work. import.meta is expected to provide a suitable replacement.

All 10 comments

you have to use mjs as the file extension (see https://nodejs.org/api/esm.html#esm_enabling for more information)

ahh, ok, but why ___dirname is not defined?

Code:

import fs from 'fs';

const start = () => {
console.log(`${__dirname}`);
console.log(`${__filename}`);
    const buffer = fs.readFileSync(`${__filename}`)
    const string = buffer.toString();
    console.log(string);
}

start();

Error:

patrikx3@WORKSTATION G:\Projects\patrikx3\play
> node --experimental-modules scripts\es6modules.mjs
(node:11960) ExperimentalWarning: The ESM module loader is experimental.
ReferenceError: __dirname is not defined
    at start (file:///G:/Projects/patrikx3/play/scripts/es6modules.mjs:4:16)
    at file:///G:/Projects/patrikx3/play/scripts/es6modules.mjs:11:1
    at ModuleJob.run (internal/loader/ModuleJob.js:94:14)
    at <anonymous>

esm is not node-specific, and node-specific "globals" (such as __dirname and module) will not work. import.meta is expected to provide a suitable replacement.

i got it, it works, but it is too experimental to use it. thanks!

@p3x-robot if want a temporary solution to __filename and __dirname consider this:

//#region META 

/** @todo Replace with import.meta eventually */
const FILENAME = typeof __filename !== 'undefined' ? __filename : (/^ +at (?:file:\/*(?=\/)|)(.*?):\d+:\d+$/m.exec(Error().stack) || '')[1];
const DIRNAME = typeof __dirname !== 'undefined' ? __dirname : FILENAME.replace(/[\/\\].*?$/, '');

//#endregion

console.log(process.argv[1], { FILENAME, DIRNAME });

awesome, thanks.

@smotaal solution is great. It needs a little fix
const DIRNAME = typeof __dirname !== 'undefined' ? __dirname : FILENAME.replace(/[\/\\][^\/\\]*?$/, '');

https://regex101.com/r/pTc2Zm/1

It's not the best (/linux/path/with\backslashes) but at least it does not replace whole FILENAME

esm is not node-specific, and node-specific "globals" (such as __dirname and module) will not work. import.meta is expected to provide a suitable replacement.

i console.log(import.meta) and have only 1 property available which is 'url'.

i'm using node 10.12.0

@datdinhquoc you can use fileURLToPath here -

import { fileURLToPath } from 'url';
console.log(fileURLToPath(import.meta.url));

import path from 'path
const __dirname = path.resolve()

console.log( __dirname )

Was this page helpful?
0 / 5 - 0 ratings