Неожиданный импорт токена Babel при запуске тестов мокко

95

Решения, предлагаемые в других связанных вопросах, таких как включение правильных пресетов (es2015) в .babelrc, уже реализованы в моем проекте.

У меня есть два проекта (назовем их A и B), в которых используется синтаксис модуля ES6. В Project A я импортирую Project B, который устанавливается через npm и находится в папке node_modules. Когда я запускаю свой набор тестов для проекта A, я получаю сообщение об ошибке:

SyntaxError: неожиданный импорт токена

Кому предшествует эта предполагаемая ошибочная строка кода из проекта B:

(функция (экспорт, требование, модуль, __filename, __dirname) {импорт createBrowserHistory из 'history / lib / createBrowserHistory';

Iife кажется чем-то связанным с npm или, возможно, с babel, поскольку мой исходный файл содержит только «import createBrowserHistory из 'history / lib / createBrowserHistory'; модульные тесты в тестовом наборе Project B работают нормально, и если я удалю Project B как зависимость от Проект A, мой набор тестов (все еще использующий импорт es6 для внутренних модулей проекта) работает нормально.

Полная трассировка стека:

 SyntaxError: Unexpected token import
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:374:25)
    at Module._extensions..js (module.js:405:10)
    at Object.require.extensions.(anonymous function) [as .js] (/ProjectA/node_modules/babel-register/lib/node.js:138:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (actionCreators.js:4:17)
    at Module._compile (module.js:398:26)
    at loader (/ProjectA/node_modules/babel-register/lib/node.js:130:5)
    at Object.require.extensions.(anonymous function) [as .js] (/ProjectA/node_modules/babel-register/lib/node.js:140:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (/ProjectA/src/components/core/wrapper/wrapper.js:28:23)
    at Module._compile (module.js:398:26)
    at loader (/ProjectA/node_modules/babel-register/lib/node.js:130:5)
    at Object.require.extensions.(anonymous function) [as .js] (/ProjectA/node_modules/babel-register/lib/node.js:140:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (/ProjectA/src/components/core/wrapper/wrapperSpec.js:15:16)
    at Module._compile (module.js:398:26)
    at loader (/ProjectA/node_modules/babel-register/lib/node.js:130:5)
    at Object.require.extensions.(anonymous function) [as .js] (/ProjectA/node_modules/babel-register/lib/node.js:140:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at /ProjectA/node_modules/mocha/lib/mocha.js:219:27
    at Array.forEach (native)
    at Mocha.loadFiles (/ProjectA/node_modules/mocha/lib/mocha.js:216:14)
    at Mocha.run (/ProjectA/node_modules/mocha/lib/mocha.js:468:10)
    at Object.<anonymous> (/ProjectA/node_modules/mocha/bin/_mocha:403:18)
    at Module._compile (module.js:398:26)
    at Object.Module._extensions..js (module.js:405:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:430:10)
    at startup (node.js:141:18)
    at node.js:980:3

Вот моя тестовая команда из package.json:

"test": "mocha --compilers js:babel-core/register '+(test|src)/**/*Spec.js'"

Это сообщение StackOverflow похоже, но не предлагает решения для моего использования командной строки: импортируйте модуль из node_modules с помощью babel, но не удалось

Мышление
источник
1
Если вы распространяете модуль на npm, вы должны распространять только транспилированную версию этого модуля.
loganfsmyth
Этот проект очень легкий. Он предназначен в основном для моего собственного использования или для других, если у них есть процесс транспирации, который может его поддержать. Я пытаюсь достичь "vanilla es6" в этих зависимостях.
ThinkingInBits
2
Я думаю, вы забыли настроить babel в package.json. добавьте их в свой package.json "babel": {"presets": ["es2015"]}
Джейкоб
3
Примечание: согласно документации --compilers не является обязательным, --require babel-registerследует использовать вместо этого: «Если ваши модули ES6 имеют расширение .js, вы можете npm install --save-dev babel-register и использовать mocha --require babel-register; --compilers необходим только в том случае, если вам нужно указать расширение файла ".
try-catch-finally
1
Наконец, я смог заставить это работать, и "babel":{"presets": ["es2015"]}это было последнее, чего мне не хватало!
Брэндон

Ответы:

81

Для Вавилона <6

Самый простой способ решить эту проблему:

  1. npm install babel-preset-es2015 --save-dev
  2. Добавить .babelrcв корень проекта с содержимым:

    {
     "presets": [ "es2015" ]
    }
    

Убедитесь, что вы запускаете mocha с параметром «--compilers js: babel-core / register».

Для Babel6 / 7 +

  1. npm install @babel/preset-env --save-dev
  2. Добавить .babelrcв корень проекта с содержимым:

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

Убедитесь, что вы запускаете мокко с параметром --compilers js:babel-register(Babel 6) или --compilers js:@babel/register(Babel 7).

Для мокко версии 7 или новее используйте --require babel-registerили --require @babel/registerсоответственно.

глубина
источник
27
попробуйте запустить мокко с параметром --require babel-register param
kolec
2
@kolec Это работает. Но даже лучше создать mocha.optsфайл в корне каталога / test и добавить его туда
Мартин Доусон,
3
Все это вместе все равно не помогает (командная строка, а не mocha.opts).
Кев
3
Если вы хотите использовать es2016, имейте в виду, что es2016 в Babel «компилирует только то, что находится в ES2016, в ES2015», поэтому вам нужны как es2016, так и es2015 в вашем массиве пресетов
prauchfuss
4
--compilersустарела. --requireВместо этого используйте .
robsch 06
46

Кажется, единственное решение - явно включить:

require('babel-core/register')({
  ignore: /node_modules/(?!ProjectB)/
}); 

в тестовом вспомогательном файле и передать его в mocha в моей тестовой команде:

mocha --require ./test/testHelper.js...

Окончательное решение:

Добавьте registerBabel.js : отдельный файл, задача которого - требовать babel-core / register ...

require('babel-core/register')({
  ignore: /node_modules/(?!ProjectB)/
});

Добавьте entry.js, если ваше приложение также использует babel-node. Это действует как оболочка для вашего приложения, содержащего es6.

require('./registerBabel');
require('./server'); // this file has some es6 imports

Затем вы запустите свое приложение с node entry

Для тестирования мокко testHelper.js должен также потребовать registerBabel.js для инициализации поддержки babel во время выполнения.

require('./registerBabel');

И запустите свои мокко-тесты с mocha --require ./testHelper.js '+(test)/**/*Spec.js'

Это рекурсивно проверит любой файл, заканчивающийся на «Spec.js» в пределах «./test». Замените образец на тот, который соответствует спецификациям вашего проекта.

Мышление
источник
3
Кажется, что ignoreрегулярное выражение немного не работает. Мне пришлось добавить экранирующую обратную косую черту сразу после node_modules: ignore: /node_modules\/(?!ProjectB)/чтобы файл babelRegister работал. В остальном кажется здорово!
hellatan
Это не позволяет нам использовать Rollupify из-за операторов require. Знаете ли вы, как это сделать без использования операторов require?
MikesBarto2002
Это здорово, но как насчет инструментов, которые не позволяют добавлять такой код и хотят напрямую запускать ваши файлы. Тогда вы получите то, babel-nodeчто не позволяет использовать такую ​​вещь .babelrc.
Евгений
1
ты просто класс! Babel обрабатывал мой код ES6 при запуске сервера, но тестирование мокко не удалось. Ваш ответ решил это. Я пробовал --compilers в mocha.opts, но это привело к сбою операторов импорта.
Energetic Pixels
1
Я не мог заставить это работать, но оказалось, что мне также нужно расширить свой babelrc: `` require ('@ babel / register') ({extends: './.babelrc', ignore: [/ node_modules \ / (?! ProjectB) /]}); ``
TiggerToo
26

Конечно, у вас будет эта проблема, вы используете ES6, о котором мокко не знает

Итак, вы используете babel, но не используете его в своем тесте ...

Несколько решений:

A. если вы работаете с NPM, используйте

"test": "mocha --compilers js:babel-core/register test*.js"

Б. Я использую

"test": "./node_modules/.bin/mocha --compilers js:babel-core/register **/*spec.jsx"

C. Из cli:

mocha --compilers js: babel-core / register test * .js

Вы можете узнать больше на http://www.pauleveritt.org/articles/pylyglot/es6_imports/

Офир Атталь
источник
1
большое спасибо! Мне не хватало опции --compilers js: babel-core / register
mycargus
1
Я уже делал это ... ты вообще читал первоначальный вопрос?
ThinkingInBits
1
@ThinkingInBits Что вы в итоге использовали, как вы (если использовали) решили проблему? У меня здесь серьезные проблемы, попробовал большинство из этих вариантов
Милан Велебит
--compilersустарел, похоже, --requireэто единственный безопасный вариант
Али Ганаватян
23

Я столкнулся с той же проблемой. Попробовав любое другое решение для stackoverflow и не только, добавление этой простой конфигурации в package.json сделало это за меня:

  "babel": {
    "presets": [
      "es2015"
    ]
  }

После этого весь мой импорт ES6 работал. Между прочим, у меня была такая же конфигурация внутри webpack.config.js, но, видимо, это был единственный способ заставить его работать и для тестирования мокко.

Надеюсь, это кому-то поможет.

Аракно
источник
у меня был файл .babelrc с неправильным написанием, поэтому он изначально не работал. Это решение работает и является рекомендуемым. Создайте файл .babelrc в своем проекте и добавьте {"presets": ["es2015"]}
AfDev
14

Я был {"modules": false}в моем .babelrc файл, например так:

"presets": [
    ["es2015", {"modules": false}],
    "stage-2",
    "react"
]

который бросал

Неожиданный импорт токена

Как только я удалил его, мокко успешно запустился.

JoeTidee
источник
Это было сгенерировано Webpacker for Rails: `` "presets": [["env", {"modules": false, "target»: {"browsers": "> 1%", "uglify": true}, "useBuiltIns": true}], "react" `` `` После того, как я удалил строку модулей, у меня все заработало.
emptywalls
Это решило мою проблему, когда CircleCI не смог запустить мои юнит-тесты jest и выдал неожиданную ошибку импорта токена. +1!
Candlejack
Это сделало это для меня. Rails, Webpacker и т.д ... Спасибо!
emptywalls
8

У меня была такая же проблема, и я исправил ее, прочитав документацию по babel для интеграции Babel с Mocha:

{
  "scripts": {
    "test": "mocha --compilers js:babel-register"
  }
}
Огнян Димитров
источник
Для какой версии Mocha и Babel?
Огнян Димитров
Мои версии Babel 6.26.0кроме "babel-preset-env": "1.6.0"и "mocha": "3.5.3"
bhantol
Странный. Это решило мою проблему и в моем случае было чисто проблемой чтения документации.
Огнян Димитров
6

Для тех, кто использует Babel 7 и Mocha 4, некоторые имена пакетов немного изменились, и принятый ответ немного устарел. Что мне нужно было сделать:

npm install @babel/register --saveDev

и добавив --require @babel/registerк тестовой строке вpackage.json

"test": "./node_modules/mocha/bin/mocha --require @babel/polyfill --require @babel/register './test/**/*.spec.js'"

В @babel/polyfillзатруднительных некоторых вещах , как асинхронная / ОЖИДАНИЕ функциональность , если вам случится использовать те.

Надеюсь, это кому-то поможет :)

Сяздани
источник
4

Я добавляю сюда еще один ответ на конфигурацию ES6 + mocha + babel, актуальный по состоянию на июнь 1919 года (см. Даты в ответе / комментарии). Мокко имеют осуждали --compilerфлаг, и версия , которую я использую имеет ту недоступную даже с --no-deprecationфлагом, сравни это

Обратите внимание, что я не буду включать все соответствующие фрагменты со связанных страниц, потому что ни один из них не привел меня к чистой тестовой сборке, основанной на последних версиях mocha и babel; этот ответ должен включать шаги, которые привели меня к успешной тестовой сборке.

Следуя инструкциям здесь, в этом ответе и здесь , я попытался установить минимально последнюю версию babel, используя npm install:

$ npm install --save-dev mocha
$ npm install --save-dev @babel/preset-env

И я настроил вызов мокко в package.json, вот так:

"scripts": {
    "test": "mocha --compilers js:@babel/register"
}

Это привело к ошибкам:

× ERROR: --compilers is DEPRECATED and no longer supported.

Как указано выше, --no-deprecationне помогло, обратитесь к странице, указанной выше. Итак, следуя инструкциям здесь, я настроил package.json:

"scripts": {
    "test": "mocha --require js:@babel/register"
}

И начали замечать ошибки при поиске модулей babel, например:

× ERROR: Cannot find module '@babel/register'

На этом этапе я начал устанавливать пакеты babel, пока не смог прогрессировать. Я считаю, что полная установка выглядит примерно так:

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

Последнее необходимое изменение заключалось в обновлении вызова мокко в package.json, удалив js:префикс, например:

"scripts": {
    "test": "mocha --require @babel/register"
}

Я не могу ответить, почему это было необходимо: если кто-то может ответить на этот вопрос, оставьте комментарий, и я дополню свой ответ более подробной информацией.

Последнее, что я сделал, - это создал .babelrc в каталоге проекта с содержимым:

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

Я не могу вспомнить, что вызвало это, но я считаю, что это произошло потому, что мокко продолжал жаловаться на то, что не распознает importключевое слово в моем test.js. Как и выше, если кто-то может ответить на этот вопрос, оставьте комментарий, и я дополню свой ответ более подробной информацией.

pb2q
источник
На этом этапе я могу успешно провести тесты мокко. Я понимаю, что здесь есть пробелы в моих знаниях: я написал много производственного кода javascript, но я относительный нуб-нуб. Любой, кто увидит это и хочет добавить к ответу, оставьте комментарий, и я улучшу ответ, ИЛИ оставьте свой собственный лучший ответ.
pb2q
3

--compilers не рекомендуется.

Мое простое решение:

npm install --save-dev babel-core

И в package.json добавьте свой тестовый скрипт следующим образом:

  "scripts": {
    "test": "mocha --require babel-core/register ./test/**/*.js -r ./test-setup.js"
  },
Э. Фортес
источник
2

Я нашел самый простой способ сделать с babel 6.XX - использовать nyc, а затем добавить helperфайл вpckage.json

Итак, вот что я использовал

package.json

{
  ....
  "scripts": {
    "test": "nyc mocha --reporter tap 'test/**/*.spec.js'"
  },
  "devDependencies": {
    "babel-cli": "^6.24.0",
    "babel-core": "^6.24.0",
    "babel-loader": "^6.4.0",
    "babel-preset-env": "^1.2.2",
    "babel-preset-es2015": "^6.24.0",
    "babel-preset-react": "^6.23.0",
    "babel-preset-react-hmre": "^1.1.1",
    "babel-preset-stage-2": "^6.22.0",
    "babel-register": "^6.24.0",
    "babel-runtime": "^6.23.0",
    "chai": "^3.5.0",
    "mocha": "^3.2.0",
    "nyc": "^10.1.2",
    "webpack": "^2.3.3",
    "webpack-config": "^7.0.0",
    "webpack-dashboard": "^0.3.0",
    "webpack-dev-server": "^2.4.2"
  },
  "nyc": {
    "all": true,
    "include": [
      "src/**/*.js"
    ],
    "cache": true,
    "require": [
      "./test/helper/registerBabel.js"
    ]
  }
}

Babelrc

{
  "presets": [
    "es2015", //remove the {modules: false} it doesn't work with this
    "stage-2"
  ]
}

registerBabel.js

/* eslint-disable import/no-commonjs, import/unambiguous */
require('babel-register')();

Теперь вы сможете использовать es6 в своих тестах или где угодно. Мои все терпят неудачу;)

Тогда npm run testкоторый сработаетnyc mocha --reporter tap 'test/**/*.spec.js'

Джейми Хатбер
источник
2

Вот что у меня сработало. Я получил предупреждение при использовании --compilersфлага.

DeprecationWarning: "--compilers" будет удален в будущей версии Mocha; см. https://git.io/vdcSr для получения дополнительной информации

Поэтому я заменил его --requireфлагом

"test":  "mocha --require babel-core/register --recursive"

Вот мой .babelrc:

{
  "presets": ["env"]
}

Мои package.jsonзависимости разработчиков

"devDependencies": {
  "babel-cli": "^6.26.0",
  "babel-preset-env": "^1.7.0",
  "mocha": "^5.2.0",
}
продакшн
источник
2

Я решил эту проблему сегодня утром с помощью следующих инструкций

Установить модули NPM

npm install --save-dev @babel/polyfill
npm install --save-dev @babel/register

package.json :

"scripts": {
    "test": "mocha --require @babel/register --require @babel/polyfill src/DesktopApplication/Tests",
  }

.babelrc

{
  "presets": ["@babel/env"]
}
Андрей Тагаев
источник
1

Я решил эту проблему сегодня утром с помощью следующих инструкций из официальных инструкций по использованию Babel для Mocha 4:

Установить модули NPM

npm install --save-dev babel-polyfill
npm install --save-dev babel-preset-env
npm install --save-dev babel-register

или одна команда:

npm i -d babel-polyfill babel-preset-env babel-register

package.json :

"scripts": {
    "test": "mocha --require babel-polyfill --require babel-register"
  }

.babelrc

{
  "presets": ["env"]
}
Дуг Вильгельм
источник
0

Я установил mochaи встретил ту же ошибку, когда использую importв своем коде. Выполнив следующие действия, проблема была устранена.

npm install babel-core --save-dev
npm install babel-preset-es2015 --save-dev
npm install babel-preset-stage-0 --save-dev

А затем добавьте .babelrcфайл:

{
    "presets": [
        "es2015"
    ]
}

А потом запускаем mochaтак:

mocha --compilers js:babel-core/register
Джефф Тиан
источник
-1

У меня такая же проблема. При запуске тестов я понял, что действительно хочу заглушить зависимые модули. Это хорошо для модульного тестирования и не позволяет babel преобразовывать подмодули. Так я использовал proxyquire, а именно:

const proxyquire = require('proxyquire').noCallThru()

const myTestedModule = proxyquire('../myTestedModule', {
    'dependentModule1': { //stubbed module1 },
    'dependentModule2': { //stubbed module2 }
})
томкур
источник
Это лучше подходит в качестве комментария.
Gajus
-3

для более перспективной настройки

npm install babel-preset-latest --save-dev

и в .babelrc

{
  "presets": [ "latest" ]
}

в отличие от ...

npm install babel-preset-es2015 --save-dev

а также

{
 "presets": [ "es2015" ]
}
Фил Генри Макбуб
источник
2
Думаю, этот ответ практически не имеет отношения к этому вопросу .. или, скорее, его можно было бы добавить как комментарий к другому ответу
62mkv
@ 62mkv Спасибо! Способ быть ястребом и содержать это место в чистоте.
Фил Генри Макбуб