获得意外的令牌导出
Getting Unexpected Token Export
我正在尝试在我的项目中运行一些 ES6 代码,但我收到意外的令牌导出错误。
export class MyClass {
constructor() {
console.log("es6");
}
}
2022 年更新
您正在使用 EcmaScript 模块(ESM 或"ES6 模块")语法,但您的环境不支持它。
v14.13.0 之前的 NodeJS 版本不支持 ESM(export
关键字语法),而是使用 CommonJS 模块(module.exports
属性语法)。NodeJS v14.13.0 及更高版本支持 ESM,但必须先启用。
解决 方案:
- 如果您使用的是 NodeJS v14.13.0 或更高版本(支持 ESM),您可以通过在项目
package.json
中设置"type":"module"
来启用它 - 使用 CommonJS 模块语法重构(适用于旧版本的 NodeJS)
- 考虑将 TypeScript 与
ts-node
或ts-node-dev
个 npm 包一起使用(用于开发时的即时转译),并在.ts
文件中编写 TypeScript
使用 esbuild - (npm 上的
esbuild
包)将 ESM 转译到 CommonJS,该 esbuild 配置为将 ES6 JavaScript 转译到您的环境支持的 CommonJS 目标。(不再推荐使用巴别塔)
如果您收到此错误,也可能与您如何将 JavaScript 文件包含在 html 页面中有关。加载模块时,必须显式声明这些文件。下面是一个示例:
//module.js:
function foo(){
return "foo";
}
var bar = "bar";
export { foo, bar };
当您包含如下所示的脚本时:
<script src="module.js"></script>
您将收到错误:
未捕获的语法错误:意外的令牌导出
您需要包含类型属性设置为"模块"的文件:
<script type="module" src="module.js"></script>
然后它应该按预期工作,并且您已准备好在另一个模块中导入模块:
import { foo, bar } from "./module.js";
console.log( foo() );
console.log( bar );
我的两分钱
出口
ES6
我的班级.js
export class MyClass1 {
}
export class MyClass2 {
}
其他.js
import { MyClass1, MyClass2 } from './myClass';
CommonJS 替代方案
我的班级.js
class MyClass1 {
}
class MyClass2 {
}
module.exports = { MyClass1, MyClass2 }
// or
// exports = { MyClass1, MyClass2 };
其他.js
const { MyClass1, MyClass2 } = require('./myClass');
导出默认值
ES6
我的班级.js
export default class MyClass {
}
其他.js
import MyClass from './myClass';
CommonJS 替代方案
我的班级.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
。
Babel(JS 已经变得非常强大),你可以简单地使用默认的 JavaScript 模块导出。查看完整教程
消息.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 目标,因为节点 js 不直接理解 ES6 目标
npm install --save-dev @babel/core @babel/preset-env
然后,您需要在项目的根目录中创建一个名称为 .babelrc
的配置文件,并将此代码添加到其中。
{ "presets": ["@babel/preset-env"] }
我有一段时间的模块工作,然后他们没有出现这个Uncaught SyntaxError: Unexpected token export
错误。
事实证明,我添加了一个没有闭合牙套的开放式支架。像这样:
if (true) {
/* } missing here */
export function foo() {}
虽然最大的错误是忘记了结尾}
,但解析器首先在大括号内找到导出,这是禁忌。
export
关键字必须位于文件的顶层。
所以:
if (true) {
export function foo() {}
}
也是非法的。当解析器遇到这种情况时,它会在那里停止解析,模糊地宣布滥用export
,给出与加载使用 export
关键字的"非模块"JavaScript 文件时相同的错误。它从不报告潜在的缺少大括号错误。
我花了很长时间才弄清楚,所以我在这里发帖是为了帮助任何未来的患者。
理想情况下,解析器将报告仅在文件的顶层允许export
。
我遇到了这个问题,我花了一个小时才找到我的问题。
问题是我正在将代码从非模块更改为模块,而忘记删除导入的脚本文件。
我的"表.js"文件有以下行。这是模块文件。
export function tableize(tableIdentifier) {
我的"订单查询.js"文件有以下行。
import { tableize, changeColumnSizesDynamic } from '../common/table.js';
我的"订单查询.html"有以下两行。
<script src='/resources/js/common/table.js'></script>
<script type='module' src='/resources/js/client/orderinquiry.js'></script>
虽然第二行很好,宣布type='module
.但是第一行直接链接到表.js并导致意外错误。当我删除第一<script>
时,一切都开始工作。
通常导入在.js扩展中不起作用,因为默认情况下 js 表示 javascript 的 cjs 版本。如果要使用es6功能,则需要将.js扩展名重命名为.mjs扩展名
parent.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
。它将允许您使用正常的导入语句,而无需将项目切换到type: module
,也不必处理type: module
的恶劣后果。此外,您还将获得TypeScript支持。
从CommonJS
导入 ES6 模块的另一种方法是重命名 ES6 模块文件以使其具有.mjs
扩展名。这是向后兼容的一种方法。然后在您的 CommonJS 代码中,您可以像这样导入:
文件导入顶部:
import myClass from "./MyClass.mjs"
或代码中任意位置的动态导入:
const myClass = await import("./MyClass.mjs");
请注意,您的CommonJS
文件不需要重命名为 .mjs
。更多信息在这里。
这个问题:浏览器只支持 ES 语法,不理解 CommonJS 中使用的require
和exports
。导入扩展名为.ts
的文件时会出现此问题。要解决此问题,请在文件中使用 ES6 模块导入。
例:文件夹结构
dist
src
|-app.ts
|-components
|-button.ts
|-helper
|-eventHander.ts
tsconfig.json
index.html
- 在 tsconfig 文件中,设置
"module": "ES2015"
- 在 tsconfig 文件中,设置
"outDir": "./dist"
- 在 HTML 文件中,添加属性
<script type="module" src="./dist/app.js"></script>
您可以在此处阅读有关模块的更多信息:JavaScript 模块
- 事件汉德.ts 文件
type Handler<T> = (e: T) => void;
const eventHander: Handler<Event> = (e: Event) => {
e.preventDefault();
alert("You Clicked");
};
export default eventHander;
- 在按钮中.ts
import eventHander from "../helper/eventHander.js"
function createButton(): HTMLElement {
let button: HTMLElement;
button = document.createElement("button");
button.addEventListener("click", eventHander);
button.innerText = "Click Me"
return button
}
export default createButton
- 在 app.ts 文件中
import createButton from "./components/button.js";
const hostElement: HTMLElement = document.getElementById("app")!;
hostElement.insertAdjacentElement("beforeend", createButton());
你的 HTML 代码应该是这样的:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
<script type="module" src="./dist/app.js"></script>
当我尝试在我的项目中导入本地 javascript 模块时,我也遇到了意外的令牌导出错误。我通过在索引.html文件中添加脚本标记时将类型声明为模块来解决它。
<script src = "./path/to/the/module/" type = "module"></script>
在最新版本的 Nodejs (v17?) 中,您可以使用 .mjs 文件扩展名使用顶级"导入"、"异步"、"等待" - 而不是转译或解决方法。
// > node my.mjs
import {MyClass} from 'https://someurl'
async func () {
// return some promise
}
await func ()
<</div>
div class="answers"> 对于那些在 2022 年查看此内容的人,我遇到了同样的错误,但是我将代码更改为如下所示:
module.exports = () => {
getUsers: () => users;
addUser: (user) => users.push(user);
};
使用 ES6 语法在 node 中不起作用,不幸的是,显然你必须有 babel 才能让编译器理解导出或导入等语法。
npm install babel-cli --save
现在我们需要创建一个 .babelrc 文件,在 babelrc 文件中,我们将 babel 设置为在编译到 ES5 时使用我们安装的 es2015 预设作为其预设。
在应用的根目录下,我们将创建一个 .babelrc 文件。 $ npm install babel-preset-es2015 --save
在应用的根目录下,我们将创建一个 .babelrc 文件。
{ "presets": ["es2015"] }
希望它有效... :)
//✅ 使用 module.exports 而不是 export模块导出 = {人};
我实际上想添加简单的解决方案。 使用 const
和反引号(')。
const model = `<script type="module" src="/"></<script>`
- React JS:未捕获(在承诺中)语法错误:在位置 0 的 JSON 中意外<令牌
- 未捕获的语法错误:意外的令牌,
- jQuery$.getJSON抛出意外令牌
- 当其他解析器认为意外的令牌有效时,json.parse会失败
- 意外的令牌模块生成失败:SyntaxError
- 为什么我在下面的..of循环中得到意外令牌
- 意外的令牌非法javascript/metrol
- 三元条件中出现意外的令牌中断
- DynamoDB和Node Js:意外的令牌h
- RegEx中出现意外的令牌错误
- data.php:1未捕获的语法错误:意外的令牌:
- 错误:[$parse:syntax]语法错误:令牌''是意外的令牌
- 组件中的ReactJS意外令牌
- Jquery脚本未在运行时加载编辑:意外的令牌
- 未捕获的语法错误:意外的令牌非法?看起来不错
- "未捕获的SyntaxError:意外的令牌ILLEGAL“;当我通过AJAX发送html时
- 获取意外的令牌ILLEGAL JS错误
- JavaScript-Gulp/Browserify:SyntaxError:意外的令牌
- Jquery .ajax() SyntaxError: 意外的令牌 N.
- AngularJS $http GET 请求到本地 JSON 文件返回语法错误:意外令牌]