[英]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
中启用模块支持,如果.ts
文件与ts-node
或ts-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.