Run ES6 code in Bash terminal with Bash heredoc

心已入冬 提交于 2019-12-10 11:34:01

问题


ES5 code can be run easily with Bash heredoc in terminal:

node <<HEREDOC
  var fs = require("fs");
  ...
HEREDOC

But ES6 code doesn't run, even with the correct --experimental-modules flag:

node --experimental-modules <<HEREDOC
  import fs from "fs";
  ...
HEREDOC

The error shown is:

(node:4130) ExperimentalWarning: The ESM module loader is experimental.
[stdin]:1
import fs from "fs";
       ^^

SyntaxError: Unexpected identifier
    at new Script (vm.js:83:7)
    at createScript (vm.js:267:10)
    at Proxy.runInThisContext (vm.js:319:10)
    at Object.<anonymous> ([stdin]-wrapper:6:22)
    at Module._compile (internal/modules/cjs/loader.js:722:30)
    at evalScript (internal/bootstrap/node.js:670:27)
    at ReadStream.<anonymous> (internal/bootstrap/node.js:340:15)
    at ReadStream.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1098:12)
    at process.internalTickCallback (internal/process/next_tick.js:72:19)

It does show this info "ExperimentalWarning: The ESM module loader is experimental." which means Node.js is running correctly with ES6 module feature, however, the import keyword is just not working.

How to run ES6 code inline in terminal with Bash heredoc? I know I can write the code to file to load as ES6 module normally, but it's a short temporary code, should it be in heredoc better.


回答1:


After looking into it, Node 11 does not support ES modules from stdin at all, if you want to use modules in Node 11 you need to put them in a file.

With Node 12 (currently unreleased but you can try it using npm i -g node-nightly), you can use the flag --entry-type=module to use stdin as a module.

With node-nightly the following worked just fine:

node-nightly --experimental-modules --entry-type=module <<HEREDOC
  import fs from 'fs'
  console.log(fs)
HEREDOC

Edit:

As noted by @Jamesernator in comments, for node-nightly from v13, use "--input-type" instead of "--entry-type".

And only built-in modules are supported, ie. 'import' won't be able to find modules in local dir, and also won't be able to find global modules installed with '-g' flag. Related issue: https://github.com/nodejs/node/issues/19570




回答2:


This is a great question that taught me a lot! Thanks for asking it. Here is what I learned:

First of all
Bash heredoc for node is like simply executing node and then typing whatever was typed in heredoc tag

I.E.

node --experimental-modules <<HEREDOC
  import fs from "fs";
  ...
HEREDOC

is equivalent to

node --experimental-modules
> import fs from "fs";

And executing node like that opens up the REPL from node

Secondly, the import syntax:

import fs from "fs"

There is no fs in "fs". That's not an issue for you now, but if the import went through, it wouldn't find that in the "fs" module. Instead, what would have been the correct syntax would be, for example:

import { readFile } from "fs";

This, however, yields:

SyntaxError: Unexpected token {

Lastly, the problem is that the entire feature is, indeed, experimental.

There are opened issues about this:

  • dynamic import can't be used in the REPL
  • How to import an ES module in Node.js REPL?
  • Bug: import() doesn’t work in string input


来源:https://stackoverflow.com/questions/55568214/run-es6-code-in-bash-terminal-with-bash-heredoc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!