ijavascript icon indicating copy to clipboard operation
ijavascript copied to clipboard

Error using `import`

Open QGB opened this issue 5 years ago • 13 comments

import defaultExport from  "/root/hs-airdrop/bin/hs-airdrop"
       ^^^^^^^^^^^^^

SyntaxError: Unexpected identifier
    at new Script (vm.js:83:7)
    at createScript (vm.js:277:10)
    at Object.runInThisContext (vm.js:329:10)
    at run ([eval]:1054:15)
    at onRunRequest ([eval]:888:18)
    at onMessage ([eval]:848:13)
    at process.emit (events.js:198:13)
    at emit (internal/child_process.js:832:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)

QGB avatar Feb 24 '20 04:02 QGB

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)

n-riesco avatar Feb 24 '20 14:02 n-riesco

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.

radamson avatar Mar 30 '21 19:03 radamson

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
> 

n-riesco avatar Mar 30 '21 20:03 n-riesco

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 ,

n-riesco avatar Mar 30 '21 20:03 n-riesco

The issue is not related to the extension used for a module. I wouldn't expect the use of type to help.

n-riesco avatar Mar 30 '21 20:03 n-riesco

From #239, alternatives to a static import:

  • an ES5 import: var { Gitlab } = require('@gitbeaker/node');
  • a dynamic import: import('@gitbeaker/node').then((module) => {global.Gitlab = module.Gitlab});

n-riesco avatar Apr 27 '21 12:04 n-riesco

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 [email protected], 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)

prothSFDC avatar Oct 04 '21 21:10 prothSFDC

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:

  1. top level ES modules supported by the CLI: judging by https://github.com/nodejs/node/issues/39353 this is an ongoing discussion.
  2. use of esm: not working in vm.runInThisContext, no feedback from https://github.com/standard-things/esm/issues/886 and no development since September 2019.
  3. use of --input-type=module: I've tried this approach, but it has 2 major issues:
    • require is undefined,
    • and, as with esm, the flag doesn't work with code run in vm.runInThisContext.
  4. use of dynamic imports: again, not working in vm.runInThisContext.
  5. use a parser: this is what we do in 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).

n-riesco avatar Nov 20 '21 21:11 n-riesco

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

disarticulate avatar Jul 01 '22 17:07 disarticulate

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.

jpshackelford avatar Nov 30 '22 04:11 jpshackelford

@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.

n-riesco avatar Mar 07 '23 16:03 n-riesco

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'

n-riesco avatar Mar 07 '23 16:03 n-riesco