Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ECMAScript Modules not working #16844

Closed
p3x-robot opened this issue Nov 6, 2017 · 11 comments
Closed

ECMAScript Modules not working #16844

p3x-robot opened this issue Nov 6, 2017 · 11 comments
Labels
esm Issues and PRs related to the ECMAScript Modules implementation. question Issues that look for answers.

Comments

@p3x-robot
Copy link

p3x-robot commented Nov 6, 2017

  • 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
@devsnek
Copy link
Member

devsnek commented Nov 6, 2017

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

@p3x-robot
Copy link
Author

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>

@devsnek
Copy link
Member

devsnek commented Nov 6, 2017

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.

@p3x-robot
Copy link
Author

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

@mscdex mscdex added esm Issues and PRs related to the ECMAScript Modules implementation. question Issues that look for answers. labels Nov 11, 2017
@SMotaal
Copy link

SMotaal commented Dec 4, 2017

@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 });

@p3x-robot
Copy link
Author

awesome, thanks.

@KrzysztofKarol
Copy link

KrzysztofKarol commented Dec 14, 2017

@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

@datdinhquoc
Copy link

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

@guybedford
Copy link
Contributor

@datdinhquoc you can use fileURLToPath here -

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

@MoamberRaza
Copy link

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

console.log( __dirname )

@DVLP
Copy link

DVLP commented Feb 23, 2021

@guybedford
...and dirname

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

btw this became very overcomplicated and can't be executed from external module for convenience because import.meta must be coming from current file and eval('import.meta.url') throws an error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
esm Issues and PRs related to the ECMAScript Modules implementation. question Issues that look for answers.
Projects
None yet
Development

No branches or pull requests

9 participants