简体   繁体   English

获取意外的令牌导出

[英]Getting Unexpected Token Export

I am trying to run some ES6 code in my project but I am getting an unexpected token export error.我正在尝试在我的项目中运行一些 ES6 代码,但出现意外的令牌导出错误。

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

Updated for 2022 2022 年更新

You are using ES6 Module syntax.您正在使用 ES6 模块语法。

This means your environment (eg node v14.13.0 or newer) must support ESM (Ecmascript Module Syntax).这意味着您的环境(例如节点 v14.13.0 或更新版本)必须支持 ESM(Ecmascript 模块语法)。

NodeJS since v14.13.0 supports EcmaScript Module Syntax but it must be enabled by adding the property "type":"module" to package.json . NodeJS 自 v14.13.0 起支持 EcmaScript 模块语法,但必须通过将属性"type":"module"添加到package.json来启用它。 NodeJS versions prior to v14.13.0 uses CommonJS Module syntax by default ( module.exports ), not ES6 module syntax ( export keyword). v14.13.0 之前的 NodeJS 版本默认使用 CommonJS 模块语法( module.exports ),而不是 ES6 模块语法( export关键字)。

Solutions:解决方案:

  • Enable module support in package.json as outlined above, if如上所述在package.json中启用模块支持,如果
  • Refactor with CommonJS syntax (for older versions of NodeJS)使用 CommonJS 语法重构(适用于旧版本的 NodeJS)
  • Accept that TypeScript is just better and write .ts files along with ts-node or ts-node-dev npm package接受 TypeScript 更好,并将.ts文件与ts-nodets-node-dev npm 包一起编写
  • (deprecated) Use babel npm package to transpile your ES6 to a commonjs target (已弃用)使用babel npm 包将 ES6 转换为commonjs目标

Javascript Module standards have changed a lot in recent years, so it can be a bit confusing.近年来,Javascript 模块标准发生了很大变化,因此可能会有些混乱。

In case you get this error, it might also be related to how you included the JavaScript file into your html page.如果您收到此错误,也可能与您如何将 JavaScript 文件包含到您的 html 页面中有关。 When loading modules, you have to explicitly declare those files as such.加载模块时,您必须明确声明这些文件。 Here's an example:这是一个例子:

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

var bar = "bar";

export { foo, bar };

When you include the script like this:当您包含这样的脚本时:

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

You will get the error:你会得到错误:

Uncaught SyntaxError: Unexpected token export未捕获的 SyntaxError:意外的令牌导出

You need to include the file with a type attribute set to "module":您需要包含类型属性设置为“模块”的文件:

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

then it should work as expected and you are ready to import your module in another module:那么它应该可以按预期工作,并且您已准备好将您的模块导入另一个模块:

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

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

My two cents我的两分钱

Export出口

ES6 ES6

myClass.js myClass.js

export class MyClass1 {
}
export class MyClass2 {
}

other.js其他.js

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

CommonJS Alternative CommonJS 替代方案

myClass.js myClass.js

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

other.js其他.js

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

Export Default导出默认值

ES6 ES6

myClass.js myClass.js

export default class MyClass {
}

other.js其他.js

import MyClass from './myClass';

CommonJS Alternative CommonJS 替代方案

myClass.js myClass.js

module.exports = class MyClass1 {
}

other.js其他.js

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

Hope this helps希望这可以帮助

I fixed this by making an entry point file like.我通过制作一个入口点文件来解决这个问题。

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

and any file I imported inside app.js and beyond worked with imports/exports now you just run it like node index.js并且我在app.js中导入的任何文件都可以与imports/exports一起使用,现在您只需像node index.js一样运行它

Note: if app.js uses export default , this becomes require('./app.js').default when using the entry point file.注意:如果app.js使用export default ,则在使用入口点文件时,这将变为require('./app.js').default

There is no need to use Babel at this moment (JS has become very powerful) when you can simply use the default JavaScript module exports.当您可以简单地使用默认的 JavaScript 模块导出时,此时无需使用 Babel(JS 已经变得非常强大)。 Check full tutorial 查看完整教程

Message.js消息.js

module.exports = 'Hello world';

app.js应用程序.js

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

console.log(msg); // Hello World

To use ES6 add babel-preset-env使用 ES6 添加babel-preset-env

and in your .babelrc :在你的.babelrc中:

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

Answer updated thanks to @ghanbari comment to apply babel 7.感谢@ghanbari 评论更新答案以应用 babel 7。

Install the babel packages @babel/core and @babel/preset which will convert ES6 to a commonjs target as node js doesn't understand ES6 targets directly安装 babel 包@babel/core@babel/preset将 ES6 转换为 commonjs 目标,因为 node js 不直接理解 ES6 目标

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

Then you need to create one configuration file with name .babelrc in your project's root directory and add this code there.然后你需要在项目的根目录下创建一个名为.babelrc的配置文件,并在其中添加这段代码。

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

I got the unexpected token export error also when I was trying to import a local javascript module in my project.当我尝试在我的项目中导入本地 javascript 模块时,我也遇到了意外的令牌导出错误。 I solved it by declaring a type as a module when adding a script tag in my index.html file.在我的 index.html 文件中添加脚本标记时,我通过将类型声明为模块来解决它。

<script src = "./path/to/the/module/" type = "module"></script>

I had modules working for a while, and then they weren't with this Uncaught SyntaxError: Unexpected token export error.我让模块工作了一段时间,然后它们没有出现这个Uncaught SyntaxError: Unexpected token export error。

Turns out, I had added an open brace without a closed brace.事实证明,我添加了一个没有闭合支架的开放式支架。 Something like:就像是:

if (true) {
export function foo() {}

While the big error is the forgetting of the end } , the parser first finds an export inside the brace, which is a no-no.虽然最大的错误是忘记了 end } ,但解析器首先在大括号内找到了一个导出,这是一个禁忌。

The export keyword must be in the top level of the file. export关键字必须位于文件的顶层。

So:所以:

if (true) {
    export function foo() {}
}

would also be illegal.也将是非法的。 When the parser encounters this, it stops parsing right there, announcing the misuse of export vaguely, giving the same error it gives when it is loading a "non-module" JavaScript file that uses the export keyword.当解析器遇到这种情况时,它会立即停止解析,模糊地宣布滥用export ,给出与加载使用export关键字的“非模块”JavaScript 文件时相同的错误。 It never reports the underlying missing brace error.它从不报告潜在的缺少大括号错误。

Took me a long time to figure that out, so I'm posting here to help any future sufferers.我花了很长时间才弄清楚这一点,所以我在这里发帖以帮助任何未来的患者。

Ideally, the parser would report that export is only allowed at the top level of the file.理想情况下,解析器会报告只允许在文件的顶层export

Possible answer可能的答案

I had that problem, in my case what happened was that I lacked add the extension to the file << File.ts >>我遇到了这个问题,就我而言,发生的事情是我缺少将扩展名添加到文件 << File.ts >>

I experienced this problem and it took me an hour to find my problem.我遇到了这个问题,我花了一个小时才找到我的问题。

The problem was that I was changing my code from non-modules to modules and I forgot to delete the imported script file.问题是我将我的代码从非模块更改为模块,我忘记删除导入的脚本文件。

My "table.js" file had the following line.我的“table.js”文件有以下行。 This is the module file.这是模块文件。

export function tableize(tableIdentifier) {

My "orderinquiry.js" file had the following line.我的“orderinquiry.js”文件有以下行。

import { tableize, changeColumnSizesDynamic } from '../common/table.js';

My "orderinquiry.html" had the following two lines.我的“orderinquiry.html”有以下两行。

<script src='/resources/js/common/table.js'></script>
<script type='module' src='/resources/js/client/orderinquiry.js'></script>

While the second line is good and declares type='module .虽然第二行很好并声明了type='module But the first line directly links to table.js and caused the unexpected error.但是第一行直接链接到 table.js 并导致了意外错误。 Everything started working when I removed that first <script> .当我删除第一个<script>时,一切都开始工作了。

For those that are viewing this in 2022, I had the same error, however I changed my code to something like this:对于那些在 2022 年查看此内容的人,我遇到了同样的错误,但是我将代码更改为如下所示:

    module.exports = () => {
    getUsers: () => users;
    addUser: (user) => users.push(user);
  };

Normally import not working in a.js extension because by default js means cjs version of javascript.通常导入在 a.js 扩展中不起作用,因为默认情况下 js 表示 javascript 的 cjs 版本。 If you want to es6 feature you need to rename the.js extension to the.mjs extension如果你想要 es6 功能,你需要将 .js 扩展名重命名为 .mjs 扩展名

parent.mjs父母.mjs

export default class Car {
   constructor(brand) {
   this.carname = brand;
}
 present() {
   return 'I have a ' + this.carname;
  }
}

child.mjs孩子.mjs

import Car from './parent.mjs'
export default class Model extends Car {
constructor(brand, mod , country) {
  super(brand);
  this.model = mod;
  this.country = country;
}
show() {
  return this.present() + ', it is a ' + this.model + "i am from " + 
  this.country;
  }
}

index.html索引.html

<!DOCTYPE html>
 <html lang="en" class="no-js">
  <head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, 
shrink-to-fit=no">
  <title>Quick Start Pack Template</title>
 </head>
 <div class="demo"></div>
 <script type="module">
   import Model from './child.mjs'
   let value = new Model("Ford", "Mustang", "bangladesh")
   document.querySelector(".demo").innerHTML = value.show()
 </script>
 </body>
 </html>

Finally run this code on live server最后在实时服务器上运行此代码

Just use tsx as your runtime instead of node .只需使用tsx作为您的运行时而不是node It will allow you to use normal import statements, without switching your project to type: module and without having to deal with the nasty consequences of type: module .它将允许您使用普通的 import 语句,而无需将您的项目切换到type: module并且不必处理type: module的恶劣后果。 In addition, you'll get TypeScript support.此外,您还将获得 TypeScript 支持。

Using ES6 syntax does not work in node, unfortunately, you have to have babel apparently to make the compiler understand syntax such as export or import.使用 ES6 语法在 node 中不起作用,不幸的是,您显然必须拥有 babel 才能使编译器理解诸如导出或导入之类的语法。

npm install babel-cli --save

Now we need to create a .babelrc file, in the babelrc file, we'll set babel to use the es2015 preset we installed as its preset when compiling to ES5.现在我们需要创建一个 .babelrc 文件,在 babelrc 文件中,我们将设置 babel 使用我们安装的 es2015 预设作为编译到 ES5 时的预设。

At the root of our app, we'll create a .babelrc file.在我们应用程序的根目录中,我们将创建一个 .babelrc 文件。 $ npm install babel-preset-es2015 --save $ npm install babel-preset-es2015 --save

At the root of our app, we'll create a .babelrc file.在我们应用程序的根目录中,我们将创建一个 .babelrc 文件。

{  "presets": ["es2015"] }

Hope it works ... :)希望它有效...... :)

In the latest versions of Nodejs (v17?) you can use top-level "import", "async", "await" by using the .mjs file extension - instead of transpiling or workarounds.在最新版本的 Nodejs(v17?)中,您可以通过使用 .mjs 文件扩展名来使用顶级“import”、“async”、“await”——而不是转译或变通方法。

   // > node my.mjs
   
   import {MyClass} from 'https://someurl'
   async func () {
     // return some promise
   }
   await func ()

// ✅ Using module.exports instead of export module.exports = { Person, }; // ✅ 使用 module.exports 而不是 export module.exports = { Person, };

I actually want to add simple solution.我实际上想添加简单的解决方案。 use const and backticks(`).使用const和反引号(`)。

const model = `<script type="module" src="/"></<script>`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM