Отримання несподіваного експорту токена


221

Я намагаюся запустити якийсь код ES6 у своєму проекті, але я отримую несподівану помилку експорту токена.

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

5
недостатньо інформації про ваше оточення чи конфігурацію, щоб запропонувати будь-яку допомогу. Ця помилка говорить про те, що або webpack, або babel не працюють належним чином, як exportце доступно лише в ES6, і ці модулі забезпечують підтримку ES6.
Claies

24
Ви повинні використовувати module.exports = MyClass, неexport class MyClass
onmyway133

Відповіді:


249

Ви використовуєте синтаксис модуля 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
Коли нодеї підтримуватимуться import? Я думав, що v10.0.0 матиме його, але, мабуть, ні.
chovy

4
Експериментальна підтримка @chovy доступна з прапором "--experimental-module". Файли повинні мати розширення .mjs
Джованні П.

1
Я отримую цю помилку, використовуючи Chrome 66 з нативної підтримкою модулів
Том Расселл

BTW: зауважте, що, хоча node10 / node12 підтримують модулі за прапором, вони не підтримують його в режимі REPL - однак він підтримується в режимі eval в node12 .
jakub.g

2
Для когось досі не зрозуміло синтаксису CommonJs. перевірте це посилання, може трохи допомогти. flaviocopes.com/commonjs
LT

142

Якщо ви отримаєте цю помилку, вона також може бути пов’язана з тим, як ви включили файл javascript у вашу html-сторінку. Під час завантаження модулів ви повинні чітко оголосити ці файли як такі. Ось приклад:

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

var bar = "bar";

export { foo, bar };

Коли ви включаєте такий сценарій:

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

Ви отримаєте помилку:

Uncaught SyntaxError: Несподіваний експорт маркера

Вам потрібно включити файл з атрибутом типу, встановленим на "модуль":

<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> імпорт ... </script>
PandaWood

1
@PandaWood Ви повинні використовувати <script type="module">import ...</script>під час імпорту з модуля. Я перевірив це в останній версії Chromium.
Володимир С.


Pure JS (ES6) підтримує імпорт, і це саме пояснює, чому я зустрів це
Ерік,

16

Мої два центи

Експорт

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 = клас MyClass {} працює
Marian Klühspies

3

Встановіть пакети babel @babel/coreі @babel/presetякі перетворять ES6 на спільну ціль, оскільки вузол 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, посилки тощо ... Я використовував у проекті монорепо з простим / серверним експресом для проекту. Працював як шарм ...
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.