Получение неожиданного экспорта токенов


221

Я пытаюсь запустить код ES6 в своем проекте, но получаю неожиданную ошибку экспорта токена.

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

5
недостаточно информации о вашей среде или конфигурации, чтобы предложить какую-либо помощь. Эта ошибка говорит о том, что веб-пакет или babel не работают должным образом, как exportэто доступно только в ES6, и именно эти модули обеспечивают поддержку ES6.
Claies

24
Вы должны использовать module.exports = MyClass, а неexport class MyClass
onmyway133

Ответы:


251

Вы используете синтаксис модуля ES6.

Это означает, что ваша среда (например, node.js) должна поддерживать синтаксис модуля ES6.

NodeJS использует синтаксис модуля CommonJS ( module.exports), а не синтаксис модуля ES6 ( exportключевое слово).

Решение:

  • Используйте babelпакет npm, чтобы перенести ES6 к commonjsцели

или

  • Рефакторинг с синтаксисом CommonJS.

Примеры синтаксиса CommonJS (от flaviocopes.com/commonjs/ ):

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

15
Когда nodejs будет поддерживать importизначально? Я думал, что v10.0.0 будет, но, видимо, нет.
Чови

4
Экспериментальная поддержка @chovy доступна с флагом "--experimental-modules". Файлы должны иметь расширение .mjs
Джованни П.

1
Я получаю эту ошибку, используя Chrome 66 с собственной поддержкой модулей.
Том Рассел

Кстати, обратите внимание, что хотя node10 / node12 поддерживают модули, стоящие за флагом, они не поддерживают его в режиме REPL - однако он поддерживается в режиме eval в node12 .
jakub.g

2
Для кого-то до сих пор не ясно, синтаксис CommonJs. Пожалуйста, проверьте эту ссылку, может помочь немного. flaviocopes.com/commonjs
LT

143

В случае, если вы получите эту ошибку, это также может быть связано с тем, как вы включили файл javascript на свою HTML-страницу. При загрузке модулей вы должны явно объявить эти файлы как таковые. Вот пример:

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

var bar = "bar";

export { foo, bar };

Когда вы включаете скрипт следующим образом:

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

Вы получите ошибку:

Uncaught SyntaxError: Неожиданный экспорт токена

Вам необходимо включить файл с атрибутом type, установленным в «module»:

<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 со встроенным скриптом, например, <script> import ... </ script>
PandaWood

1
@PandaWood Вы должны использовать <script type="module">import ...</script>, когда вы импортируете из модуля. Я проверил это в последней версии Chromium.
Владимир С.

Это исправило мою проблему :)
user3651476

Чистый JS (ES6) поддержал импорт, и это объясняет, почему я встретил это
Эрик

17

Мои два цента

экспорт

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
его вопрос не об объяснении Вавилона. Так зачем отвечать на что-то не обязательно, что может смутить других?
Джалал,

7
@monsto этот вопрос уже был помечен babelавтором. Хотя ответ Фила Рикетта проясняет проблему, и это хорошо, этот ответ является прямым решением проблемы автора.
мальчик

"@ babel / preset-env"
ghanbari

6

В этот момент нет необходимости использовать Babel (JS стал очень мощным), когда вы можете просто использовать экспорт модуля JavaScript по умолчанию. Проверьте полный учебник

Message.js

module.exports = 'Hello world';

app.js

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

console.log(msg); // Hello World

2
Ну, как бы вы экспортировать класс тогда?
Шервин Аблана Дапито

1
Я удаляю свой ответ, так как вопрос был на самом деле для ES6, а не для CommonJS, используемого NodeJS. Пожалуйста, проверьте выше для ответа.
Элвин Конда

@ SherwinAblañaDapito module.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: Невозможно использовать оператор импорта вне модуля»
молекулярное сообщение

3

Я исправил это, сделав файл точки входа как.

// 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при использовании файла точки входа.


1
Лучший ответ для простых проектов, не нуждающихся в babel, webpack, parcel и т.д ... Я использовал в проекте monorepo с simple / server express для проекта. Работал как шарм ...
mattdlockyer

-3

Использование синтаксиса ES6 не работает в узле, к сожалению, вам нужно иметь babel, чтобы компилятор понимал синтаксис, такой как экспорт или импорт.

npm install babel-cli --save

Теперь нам нужно создать файл .babelrc. В файле babelrc мы настроим babel на использование предустановки es2015, которую мы установили в качестве предустановки при компиляции в ES5.

В корне нашего приложения мы создадим файл .babelrc. $ npm установить babel-preset-es2015 --save

В корне нашего приложения мы создадим файл .babelrc.

{  "presets": ["es2015"] }

Надеюсь, что это работает ... :)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.