ES6 模块如何在 Node 中作为脚本运行?

cur*_*nii 13 executable shebang node.js es6-modules

ES6 模块如何在 Node 中作为脚本运行?

当我尝试这个shebang时,我收到一个错误:

#!/usr/bin/env node --experimental-modules
Run Code Online (Sandbox Code Playgroud)

/usr/bin/env: 'node --experimental-modules': 没有那个文件或目录

如果我使用这个shebang,它有语法错误(当然):

#!/usr/bin/env node
Run Code Online (Sandbox Code Playgroud)

语法错误:意外的令牌导入

我正在使用的解决方法是使用 shell 脚本来调用模块:

#!/usr/bin/env sh

BASEDIR=$( dirname "$0" )
node --experimental-modules $BASEDIR/script.mjs "$@"
Run Code Online (Sandbox Code Playgroud)

是否可以在没有第二个文件的情况下使其工作?

Ish*_*iri 6

您需要将参数传递给 shebang 上的节点。这在http://sambal.org/2014/02/passing-options-node-shebang-line/的文章中得到了很好的解释。

代码如下。

#!/bin/sh 
":" //# comment; exec /usr/bin/env node --harmony "$0" "$@"

console.log("It Works!");
Run Code Online (Sandbox Code Playgroud)

我用harmony而不是--experimental-modules. 来自网站的解释如下。

#!/bin/sh 使脚本被识别为 shell 脚本,并传递给 /bin/sh 执行。/bin/sh 一次一行地读取和执行脚本,我们在下面利用这一点。

由 shell 解释的第二行包含两个命令。

  • 2a. 第一个命令是“:”,它是很少使用的 bash 命令 : 的引用版本,意思是“扩展参数和无操作”。: 的唯一参数是 //,这是一个有效的路径。下面的# 是一个 bash 注释,它在命令分隔符 ; 之前一直有效。

  • 2b. 第二个命令是 exec /usr/bin/env node --noharmony "$0" "$@" 它使用所需的参数执行节点解释器并将参数 0(此脚本文件)和其余参数传递给 bash 脚本(“$@”)

exec 导致 bash 进程被 node 进程替换,因此 bash 不会尝试处理任何进一步的行。


gib*_*nic 6

我已经修补了Ishan Thilina Somasiri解决方案,Node 13无需.mjs扩展即可使用:

#!/usr/bin/env bash
":" //# comment; exec /usr/bin/env node --input-type=module - "$@" < "$0"

import { hostname } from 'os';

console.log(hostname());
Run Code Online (Sandbox Code Playgroud)

技巧几乎相同,但使用标准输入,这是当您没有扩展名或扩展名时唯一记录的方式。因此,一个独立的无扩展脚本。package.json.mjs

但是,像__dirname或这样的全局变量__filename将不可用。


cur*_*nii 3

我不确定它是什么时候改变的,但在最近的 Node 版本中,如果脚本是包的一部分(即,文件夹或任何父文件夹中有一个 package.json 文件),则不需要特别注意。只需确保遵循以下步骤:

  1. 在package.json中,设置"type": "module"
  2. 给文件一个.js扩展名
  3. 使用舍邦#!/usr/bin/env node