我不明白是怎么回事。
节点v5.6.0
NPM v3.10.6
代码:
function (exports, require, module, __filename, __dirname) {
import express from 'express'
};
错误:
SyntaxError: Unexpected token import
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:387:25)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:140:18)
at node.js:1001:3
Node 13+从Node 13开始,你可以使用.mjs扩展名,或者在package.json中设置{"type": "module"}。你不需要使用——experimental-modules标志。Modules现在在node.js中被标记为稳定
Node 12从Node 12开始,你可以使用.mjs扩展名,或者在package.json中设置"type": "module"。你需要带着——experimental-modules标志运行node。
节点9在节点9中,它被启用在一个标志后面,并使用.mjs扩展名。
node --experimental-modules my-app.mjs
虽然导入确实是ES6的一部分,但不幸的是,它在默认情况下还不被NodeJS支持,直到最近才在浏览器中获得支持。
查看浏览器compat表上的MDN和这个节点的问题。
摘自James M Snell关于Node.js中ES6模块的更新(2017年2月):
工作正在进行中,但需要一些时间——我们目前预计至少需要一年。
在本地支持出现之前(现在在Node 13+中标记为稳定),你必须继续使用经典的require语句:
const express = require("express");
如果你真的想在NodeJS中使用新的ES6/7特性,你可以使用Babel编译它。下面是一个服务器示例。
正如在其他回答中提到的,Node JS目前不支持ES6导入。
(从现在开始,请阅读EDIT 2)
在node js中启用ES6导入可以解决这个问题。我试过这个方法,对我很有效。
执行如下命令:
npm install babel-register babel-preset-env --save-dev
现在需要创建一个新文件(config.js),并向其中添加以下代码。
require('babel-register')({
presets: [ 'env' ]
})
// Import the rest of our application.
module.exports = require('./your_server_file.js')
现在您可以编写import语句而不会得到任何错误。
希望这能有所帮助。
编辑:
您需要运行使用上述代码创建的新文件。我用的是config.js。所以我得跑了:
node config.js
编辑2:
在试验过程中,我发现了一个简单的解决方法。
在项目的根目录下创建.babelrc文件。
添加以下(和任何其他你需要的babel预设,可以添加在这个文件中):
{
"presets": ["env"]
}
使用npm Install babel-pre -env——save命令安装babel-cli,然后使用npm Install babel-cli -g——save命令安装babel-cli
现在,转到服务器或索引文件所在的文件夹,使用以下命令运行:
babel-node fileName.js
或者你也可以使用npm start运行,在你的包中添加以下代码。json文件:
"scripts": {
"start": "babel-node src/index.js"
}
巴别塔7号提案
您可以添加开发依赖项吗
npm i -D @babel/core @babel/preset-env @babel/register
并在根目录中添加。babelrc
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
]
}
并添加到.js文件中
require("@babel/register")
或者如果你在cli中运行它,你可以使用require钩子作为-r @babel/register, ex。
$node -r @babel/register executeMyFileWithESModules.js
作为Node.js v12(这可能是相当稳定的现在,但仍然标记为“实验”),你有两个选项使用ESM (ECMAScript模块)在Node.js(文件,有第三种方法计算字符串),以下是文档所说的:
The --experimental-modules flag can be used to enable support for
ECMAScript modules (ES modules).
Once enabled, Node.js will treat the following as ES modules when passed to
node as the initial input, or when referenced by import statements within
ES module code:
Files ending in .mjs.
Files ending in .js, or extensionless files, when the nearest parent
package.json file contains a top-level field "type" with a value of
"module".
Strings passed in as an argument to --eval or --print, or piped to
node via STDIN, with the flag --input-type=module.
Node.js will treat as CommonJS all other forms of input, such as .js files
where the nearest parent package.json file contains no top-level "type"
field, or string input without the flag --input-type. This behavior is to
preserve backward compatibility. However, now that Node.js supports both
CommonJS and ES modules, it is best to be explicit whenever possible. Node.js
will treat the following as CommonJS when passed to node as the initial input,
or when referenced by import statements within ES module code:
Files ending in .cjs.
Files ending in .js, or extensionless files, when the nearest parent
package.json file contains a top-level field "type" with a value of
"commonjs".
Strings passed in as an argument to --eval or --print, or piped to
node via STDIN, with the flag --input-type=commonjs.
我要在最初的问题中解决另一个问题,没有人问过这个问题。最近在我自己的NodeJS项目中从CommonJS转换到ESM后,我很少看到关于你不能像require那样把导入放在你想要的任何地方的讨论。我的项目现在使用导入工作得很好,但是当我使用问题中的代码时,我首先得到一个没有命名函数的错误。命名函数后,我收到以下…
import express from 'express'
^^^^^^^
SyntaxError: Unexpected identifier
at Loader.moduleStrategy (internal/modules/esm/translators.js:88:18)
您不能像需要的那样在函数中导入。它们必须放在文件的顶部,在代码块之外。我自己在这个问题上也浪费了不少时间。
因此,虽然上面所有的答案都能很好地帮助您在项目中导入,但没有一个能解决原始问题中的代码不能像编写的那样工作的问题。
My project uses node v10.21.0, which still does not support ES6 import keyword. There are multiple ways to make node recognize import, one of them is to start node with node --experimental-modules index.mjs (The mjs extension is already covered in one of the answers here). But, this way, you will not be able to use node specific keyword like require in your code. If there is need to use both nodejs's require keyword along with ES6's import, then the way out is to use the esm npm package. After adding esm package as a dependency, node needs to be started with a special configuration like: node -r esm index.js