获取意外的令牌导出


220

我试图在我的项目中运行一些ES6代码,但出现意外的令牌导出错误。

export class MyClass {
  constructor() {
    console.log("es6");
  }
}

5
有关您的环境或配置的信息不足,无法提供任何帮助。该错误表明webpack或babel无法正常工作export(仅在ES6中可用),并且这些模块提供了ES6支持。
Claies

24
您应该使用module.exports = MyClass,而不是export class MyClass
onmyway133

Answers:


249

您正在使用ES6模块语法。

这意味着您的环境(例如,node.js)必须支持ES6模块语法。

NodeJS使用CommonJS Module语法(module.exports)而不是ES6模块语法(export关键字)。

解:

  • 使用babelnpm软件包将ES6转换为commonjs目标

要么

  • 使用CommonJS语法进行重构。

CommonJS语法的示例是(来自flaviocopes.com/commonjs/):

  • exports.uppercase = str => str.toUpperCase()
  • exports.a = 1

15
nodejs何时会原生支持import?我以为v10.0.0会有,但显然没有。
chovy

4
@chovy实验支持带有标志“ --experimental-modules”。文件需要具有.mjs扩展名
Giovanni

1
使用带有本机支持模块的Chrome 66时出现此错误。
汤姆·罗素

顺便说一句:请注意,虽然node10 / node12支持标志后面的模块,但它们在REPL模式下不支持它-但是在node12的eval模式下受支持
jakub.g

2
对于尚不清楚CommonJs语法的人。请查看此链接,可能会有所帮助。flaviocopes.com/commonjs
LT

142

如果出现此错误,则可能还与将javascript文件包含到html页面中的方式有​​关。加载模块时,您必须像这样明确声明这些文件。这里是一个例子:

//module.js:
function foo(){
   return "foo";
}

var bar = "bar";

export { foo, bar };

当包含这样的脚本时:

<script src="module.js"></script>

您将收到错误:

未捕获的SyntaxError:意外的令牌导出

您需要包含类型属性设置为“模块”的文件:

<script type="module" src="module.js"></script>

然后它将按预期工作,并且您准备将模块导入另一个模块:

import { foo, bar } from  "./module.js";

console.log( foo() );
console.log( bar );

37
与“最赞成”的答案不同,这实际上解决了问题并解释了为什么会发生这种情况,而没有建议唯一的选择就是利用CommonJS方法,APM方法或转译我们的代码...这也将是一个例外到w3c标准,该标准type应该是有效的mime类型(又称为媒体类型),因此这是意外的发现。谢谢!
肖恩·威尔逊

4
这可以修复错误,但随后我在Chrome 67中的import语句的行中使用内联脚本获取了“意外令牌{”,例如<script> import ... </ script>
PandaWood '18

1
@PandaWood <script type="module">import ...</script>从模块导入时,必须使用。我在最新版本的Chromium中对其进行了测试。
Vladimir S.

这解决了我的问题:)
user3651476 '18

Pure JS(ES6)支持导入,这正好解释了为什么我遇到这个问题
Eric

15

我的两分钱

出口

ES6

myClass.js

export class MyClass1 {
}
export class MyClass2 {
}

other.js

import { MyClass1, MyClass2 } from './myClass';

CommonJS替代

myClass.js

class MyClass1 {
}
class MyClass2 {
}
module.exports = { MyClass1, MyClass2 }
// or
// exports = { MyClass1, MyClass2 };

other.js

const { MyClass1, MyClass2 } = require('./myClass');

导出默认值

ES6

myClass.js

export default class MyClass {
}

other.js

import MyClass from './myClass';

CommonJS替代

myClass.js

module.exports = class MyClass1 {
}

other.js

const MyClass = require('./myClass');

希望这可以帮助


对于ES6默认导出示例,您编写了“默认导出”,但应为“导出默认”。
IAM_AL_X

@IAM_AL_X感谢抓到:-)
Barnstokkr

10

要使用ES6,请添加 babel-preset-env

并在您的.babelrc

{
  "presets": ["@babel/preset-env"]
}

由于@ghanbari评论适用Babel 7,答案得到更新。


8
他的问题不在于解释通天塔。那么,为什么要回答一些不必要的事情却可能使其他人感到困惑呢?
Jalal

7
@monsto这个问题已经被babel作者标记了。虽然Phil Ricketts的回答确实可以澄清问题,但很好,但是此答案是作者问题的直接解决方案。
boycy '18

“ @ babel / preset-env”
ghanbari

6

现在,您只需使用默认的JavaScript模块导出,就无需使用Babel(JS变得非常强大)。查看完整教程

Message.js

module.exports = 'Hello world';

app.js

var msg = require('./Messages.js');

console.log(msg); // Hello World

2
那么,您将如何导出课程?
SherwinAblañaDapito 19年

1
我删除我的答案,因为该问题实际上是针对ES6的,而不是NodeJS使用的CommonJS。请在上方查看答案。
Alvin Konda

@SherwinAblañaDapitomodule.exports = class MyClass {}起作用
玛丽安·克鲁斯派

3

安装巴贝尔包@babel/core@babel/preset将ES6转换为CommonJS的目标为节点的js不直接了解ES6目标

npm install --save-dev @babel/core @babel/preset-env

然后,您需要.babelrc在项目的根目录中创建一个名称为配置文件,并在其中添加此代码

{ "presets": ["@babel/preset-env"] }


我还需要安装@ babel / register,否则我仍然会收到“ SyntaxError:无法在模块外部使用import语句”
分子

3

我通过制作一个入口文件来解决这个问题。

// index.js
require = require('esm')(module)
module.exports = require('./app.js')

任何文件I进口内app.js及以后的工作imports/exports ,现在你只要运行它像node index.js

注意:如果app.js使用export default,则require('./app.js').default在使用入口点文件时会变为。


1
对于不需要babel,webpack,parcel等简单项目的最佳答案。我在monorepo项目中使用了简单的/ server express项目。像魅力一样
运作

-3

使用ES6语法在节点中不起作用,不幸的是,您显然必须具有babel才能使编译器理解诸如导出或导入之类的语法。

npm install babel-cli --save

现在我们需要创建一个.babelrc文件,在babelrc文件中,我们将babel设置为在编译为ES5时使用我们安装的es2015预设作为其预设。

在应用程序的根目录下,我们将创建一个.babelrc文件。$ npm install babel-preset-es2015-保存

在应用程序的根目录下,我们将创建一个.babelrc文件。

{  "presets": ["es2015"] }

希望它能起作用... :)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.