繁体   English   中英

获取意外的令牌导出

[英]Getting Unexpected Token Export

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

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

2022 年更新

您正在使用 ES6 模块语法。

这意味着您的环境(例如节点 v14.13.0 或更新版本)必须支持 ESM(Ecmascript 模块语法)。

NodeJS 自 v14.13.0 起支持 EcmaScript 模块语法,但必须通过将属性"type":"module"添加到package.json来启用它。 v14.13.0 之前的 NodeJS 版本默认使用 CommonJS 模块语法( module.exports ),而不是 ES6 模块语法( export关键字)。

解决方案:

  • 如上所述在package.json中启用模块支持,如果
  • 使用 CommonJS 语法重构(适用于旧版本的 NodeJS)
  • 接受 TypeScript 更好,并将.ts文件与ts-nodets-node-dev npm 包一起编写
  • (已弃用)使用babel npm 包将 ES6 转换为commonjs目标

近年来,Javascript 模块标准发生了很大变化,因此可能会有些混乱。

如果您收到此错误,也可能与您如何将 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 );

我的两分钱

出口

ES6

myClass.js

export class MyClass1 {
}
export class MyClass2 {
}

其他.js

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

CommonJS 替代方案

myClass.js

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

其他.js

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

导出默认值

ES6

myClass.js

export default class MyClass {
}

其他.js

import MyClass from './myClass';

CommonJS 替代方案

myClass.js

module.exports = class MyClass1 {
}

其他.js

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

希望这可以帮助

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

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

并且我在app.js中导入的任何文件都可以与imports/exports一起使用,现在您只需像node index.js一样运行它

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

当您可以简单地使用默认的 JavaScript 模块导出时,此时无需使用 Babel(JS 已经变得非常强大)。 查看完整教程

消息.js

module.exports = 'Hello world';

应用程序.js

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

console.log(msg); // Hello World

使用 ES6 添加babel-preset-env

在你的.babelrc中:

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

感谢@ghanbari 评论更新答案以应用 babel 7。

安装 babel 包@babel/core@babel/preset将 ES6 转换为 commonjs 目标,因为 node js 不直接理解 ES6 目标

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

然后你需要在项目的根目录下创建一个名为.babelrc的配置文件,并在其中添加这段代码。

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

当我尝试在我的项目中导入本地 javascript 模块时,我也遇到了意外的令牌导出错误。 在我的 index.html 文件中添加脚本标记时,我通过将类型声明为模块来解决它。

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

我让模块工作了一段时间,然后它们没有出现这个Uncaught SyntaxError: Unexpected token export error。

事实证明,我添加了一个没有闭合支架的开放式支架。 就像是:

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

虽然最大的错误是忘记了 end } ,但解析器首先在大括号内找到了一个导出,这是一个禁忌。

export关键字必须位于文件的顶层。

所以:

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

也将是非法的。 当解析器遇到这种情况时,它会立即停止解析,模糊地宣布滥用export ,给出与加载使用export关键字的“非模块”JavaScript 文件时相同的错误。 它从不报告潜在的缺少大括号错误。

我花了很长时间才弄清楚这一点,所以我在这里发帖以帮助任何未来的患者。

理想情况下,解析器会报告只允许在文件的顶层export

可能的答案

我遇到了这个问题,就我而言,发生的事情是我缺少将扩展名添加到文件 << File.ts >>

我遇到了这个问题,我花了一个小时才找到我的问题。

问题是我将我的代码从非模块更改为模块,我忘记删除导入的脚本文件。

我的“table.js”文件有以下行。 这是模块文件。

export function tableize(tableIdentifier) {

我的“orderinquiry.js”文件有以下行。

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

我的“orderinquiry.html”有以下两行。

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

虽然第二行很好并声明了type='module 但是第一行直接链接到 table.js 并导致了意外错误。 当我删除第一个<script>时,一切都开始工作了。

对于那些在 2022 年查看此内容的人,我遇到了同样的错误,但是我将代码更改为如下所示:

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

通常导入在 a.js 扩展中不起作用,因为默认情况下 js 表示 javascript 的 cjs 版本。 如果你想要 es6 功能,你需要将 .js 扩展名重命名为 .mjs 扩展名

父母.mjs

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

孩子.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;
  }
}

索引.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>

最后在实时服务器上运行此代码

只需使用tsx作为您的运行时而不是node 它将允许您使用普通的 import 语句,而无需将您的项目切换到type: module并且不必处理type: module的恶劣后果。 此外,您还将获得 TypeScript 支持。

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

npm install babel-cli --save

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

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

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

{  "presets": ["es2015"] }

希望它有效...... :)

在最新版本的 Nodejs(v17?)中,您可以通过使用 .mjs 文件扩展名来使用顶级“import”、“async”、“await”——而不是转译或变通方法。

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

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

我实际上想添加简单的解决方案。 使用const和反引号(`)。

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

暂无
暂无

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

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