Open QGB opened 4 years ago
Your experience with ES6 modules depends on your Node version.
I've just tested the REPL in the current version (v13.9.0) and this is the error Node throws:
$ node -e "import defaultExport from './test.mjs'"
[eval]:1
import defaultExport from './test.mjs'
^^^^^^
SyntaxError: Cannot use import statement outside a module
at new Script (vm.js:88:7)
at createScript (vm.js:263:10)
at Object.runInThisContext (vm.js:311:10)
at Object.<anonymous> ([eval]-wrapper:10:26)
at Module._compile (internal/modules/cjs/loader.js:1151:30)
at evalScript (internal/process/execution.js:94:25)
at internal/main/eval_string.js:23:3
And for example, I'm able to reproduce the error message you get, using Node v10:
$ node --experimental-modules -e "import defaultExport from './test.mjs'"
[eval]:1
import defaultExport from './test.mjs'
^^^^^^^^^^^^^
SyntaxError: Unexpected identifier
at new Script (vm.js:79:7)
at createScript (vm.js:251:10)
at Proxy.runInThisContext (vm.js:303:10)
at Object.<anonymous> ([eval]-wrapper:6:22)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at evalScript (internal/bootstrap/node.js:587:27)
at startup (internal/bootstrap/node.js:265:9)
at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)
I've looked through this issue and some of the related ones, but I wasn't able to find a solution for this.
Is enabling ECMAScript modules supported by ijavascript for use in Jupyter Notebooks? I tried setting type
in package.json
and also using NODE_OPTIONS=-r esm
, but no dice.
Last time I checked (node.js v14.13.0), the REPL doesn't support this use yet. It fails with:
$ node
Welcome to Node.js v14.13.0.
Type ".help" for more information.
> import test from ".";
import test from ".";
^^^^^^
Uncaught:
SyntaxError: Cannot use import statement inside the Node.js REPL, alternatively use dynamic import
>
Re esm
, unfortunately esm
doesn't work on vm
. See https://github.com/n-riesco/ijavascript/issues/215#issuecomment-678268578
I haven't seen any activity in https://github.com/standard-things/esm/issues/886 ,
The issue is not related to the extension used for a module. I wouldn't expect the use of type
to help.
From #239, alternatives to a static import:
var { Gitlab } = require('@gitbeaker/node');
import('@gitbeaker/node').then((module) => {global.Gitlab = module.Gitlab});
Hi @n-riesco - Might you have any thoughts on what the status of this is? (It seems like the only workaround I've found is by importing older cjs module versions, instead of the newer ones)
I've tried using the suggestions provided above (like from 239, or the related ones that mentions)
Might you have any other thoughts we could try?
like any options for ESM (but it seems like there hasn't been any traction there from the ESM team)
or working with NODE_OPTIONS etc
the destructure works but the require fails, like with node-fetch@3.0.0
, like with error: Error [ERR_REQUIRE_ESM]: Must use import to load ES Module
and the dynamic import also doesn't work - but seems the most promising
(it always gives me either an error cannot use import statement outside of a module
or A dynamic import callback was not specified
)
Hi @prothSFDC
I'm sorry it took me so long to come back to you. It's been hard to find chunks of time long enough to look into this.
These are the options I've looked into so far:
vm.runInThisContext
, no feedback from https://github.com/standard-things/esm/issues/886 and no development since September 2019.--input-type=module
: I've tried this approach, but it has 2 major issues:
require
is undefined,esm
, the flag doesn't work with code run in vm.runInThisContext
.vm.runInThisContext
.ijavascript-await
, and essentially what esm
does.I've opened https://github.com/nodejs/node/issues/40898 with nodejs re vm.runInThisContext
, but I reckon it has to be fixed at V8 first.
I'm not familiar with esm
, but I had a quick look through their code. The solution could be as simple as adding vmHook
to our case (i.e. running with node --eval
).
check out:
Name: Node.js Notebooks (REPL) Id: donjayamanne.typescript-notebook Description: Iterative & interactive programming for Node.js in JavaScript/TypeScript (REPL), with great support for Tensorflow.js, debugging, & more.. Version: 2.0.6 Publisher: Don Jayamanne VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=donjayamanne.typescript-notebook
https://github.com/DonJayamanne/typescript-notebook
It appears to be using runInNewContext and can do imports
For the time being I am using https://github.com/DonJayamanne/typescript-notebook (very well done) but I would prefer to use Jupyter as I would like to share notebooks with non-developers who aren't running vs-code. Without import I am not sure how I would use the redis npm which my project depends on. If I've missed a work-around please let me know. Otherwise, I'll be watching this space.
@disarticulate apologies for the late reply (somehow I missed your message).
I had a look at ts-node
(I imagine the same results apply to typescript-notebook
). ts-node
uses esbuild
to transpile import
statements into require
calls. This means ts-node
fails to import ES modules (for the same reason iJavaScript does). See:
# ts-node
> import d3 from "d3"
undefined
> d3
node:internal/modules/cjs/loader:1210
throw err;
^
Uncaught:
Error [ERR_REQUIRE_ESM]: require() of ES Module /usr/local/lib/node_modules/d3/src/index.js not supported.
Instead change the require of index.js in null to a dynamic import() which is available in all CommonJS modules.
at require.extensions.<computed> [as .js] (/usr/local/lib/node_modules/ts-node/dist/index.js:851:20)
at /usr/local/lib/<repl>.ts:1:30
at Script.runInThisContext (node:vm:129:12)
at runInContext (/usr/local/lib/node_modules/ts-node/dist/repl.js:466:23)
at Object.execCommand (/usr/local/lib/node_modules/ts-node/dist/repl.js:434:36)
at /usr/local/lib/node_modules/ts-node/dist/repl.js:456:48
at Array.reduce (<anonymous>)
at appendCompileAndEvalInput (/usr/local/lib/node_modules/ts-node/dist/repl.js:456:29)
at evalCodeInternal (/usr/local/lib/node_modules/ts-node/dist/repl.js:117:16)
at REPLServer.nodeEval (/usr/local/lib/node_modules/ts-node/dist/repl.js:132:32)
at bound (node:domain:433:15)
at REPLServer.runBound [as eval] (node:domain:444:12)
at REPLServer.onLine (node:repl:902:10)
at REPLServer.emit (node:events:525:35)
at REPLServer.emit (node:domain:489:12)
at REPLServer.self._ttyWrite (node:repl:997:9)
at ReadStream.emit (node:events:513:28)
at ReadStream.emit (node:domain:489:12)
at emitKeys.next (<anonymous>)
at ReadStream.emit (node:events:513:28)
at ReadStream.emit (node:domain:489:12) {
code: 'ERR_REQUIRE_ESM'
}
BTW, the reason iJavasScript is using runInThisContext
is because the node REPL makes some of the node.js API available in the global context without the need for require
.
For those interested in using ES modules in iJavaScript: I've been able to do so using esm-hook and a recent version of node.js (failed with v12, worked with v18):
# cat test.mjs
const test = "test";
export default test;
# node
Welcome to Node.js v18.12.1.
Type ".help" for more information.
> require("esm-hook")
[Function (anonymous)]
> var test1 = require("./test.mjs").default; test1
'test'
> vm.runInThisContext("var test2 = require('./test.mjs').default; test2")
'test'
Flag --experimental-require-module
(see https://github.com/nodejs/node/pull/51977 ).