Как mocha / babel переносит мой тестовый код на лету? - PullRequest
0 голосов
/ 20 декабря 2018

Мой вопрос не о том, почему что-то не работает, а о том, почему это так.Да.

У меня есть небольшой инструмент командной строки nodeJS , который содержит функции, которые nodeJS еще не поддерживает "из коробки", в частности:

  • import операторов
  • String.includes().

Таким образом, для доставки (сборки) я перемещаю + упаковываю свой исходный код (используя посылка , какwebpack).

Как положительный момент, все (кроме одного) из моих тестов мокко запускают прямо против моих классов, а не связки.Тем не менее, они работают!Включая много import заявлений.И включая самопроверку ES6:

it( 'String - include', () => {
    var s = 'Southern Bananas'
    assert( s.includes( 'anana' ) )
    assert( !s.includes( 'kiwi' ) )
} )

Таким образом:

У меня есть String.include в моем тестовом коде , а не только в тестируемом источнике,И нет места, где я могу перенести или связать свой тестовый код ... Таким образом, извиняюсь за мой тупой вопрос:

Почему это работает?Есть ли где-нибудь секретная своевременная компиляция?(и если да, могу ли я использовать это для отладки своего тестируемого кода?)

my mocha.opts довольно просты:

--require @babel/register
--require ./test/once.js  (nothing special here, either)
--reporter list
--recursive

my .babelrc имеет это:

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "targets": {
                    "Electron": "3.0",
                    "Node": "8.0"
                }
            }
        ]
    ],
    "plugins": [
        "@babel/plugin-transform-runtime"
    ],
    "retainLines": true,
    "comments": false,
    "sourceMaps": true
}

@babel/plugin-transform-runtime явно не для обвинения похвалы, как это явно заявляет

ПРИМЕЧАНИЕ: Методы экземпляра, такие как "foobar" .include ("foo"), не будут работать, поскольку это потребует модификации существующих встроенных модулей (для этого вы можете использовать @ babel / polyfill).

Is@babel/polyfill содержится в minimalistik-modern afaik @babel/preset-env?Что еще я делаю правильно: +)?Есть ли способ использовать эту живую компиляцию и для моей (отладочной) сборки?

1 Ответ

0 голосов
/ 03 января 2019

Короткая история

String.prototype.includes поддерживается Node.js начиная с версии 6.5.@babel/register вызывает компиляцию вашего кода на лету, поэтому ваши операторы import работают.Я сомневаюсь, что вам нужен плагин @babel/plugin-transform-runtime, если только мне не хватает чего-то, чего вы пытаетесь достичь.

Что может вызвать эту путаницу?

Я думаю, что есть две основные причиныэта (полностью понятная) тайна:

  1. Авторы Babel сделали действительно простым в использовании инструментом;и иногда трудно понять, как / когда он вызывается (особенно в сочетании с другим инструментом, таким как Mocha).
  2. Что изначально поддерживается / не поддерживается Node.js (в терминах ES2015, ES2016и т. д.) Традиционно было трудно идти в ногу.

Итак, о двух загадках.

Почему String.prototype.includes работает?

Этоу каждого есть более легкое объяснение.String.prototype.includes изначально поддерживается с Node.js v6.5 (, как вы можете видеть , с тех пор поддерживается подавляющее большинство поддержки ES2015).

Итак, хотя вы правы в том, что у вас не настроен @babel/polyfill (насколько я могу судить) и что вам понадобится в среде, которая не поддерживает String.prototype.includes, ваша среда уже поддерживает это !

Из Node.js v8.x REPL:

> 'ES2015'.includes('2015')
true

Почему ваш оператор import работает?

Как вы заявили, Node.js v8.x изначально не поддерживает модули ECMAScript .Тем не менее, есть несколько хороших статей о том, как он был включен в качестве экспериментальной функции , начиная с Node.js v9.x .

Итак, вы получитедалее с родным Node.js v8.x (через REPL):

> import path from 'path';
import path from 'path';
^^^^^^

SyntaxError: Unexpected token import

Причина, по которой ваш импорт работает, заключается в том, что ваш код компилируется Babel с использованием предустановки @babel/preset-env. Кроме того, эта компиляция запускается вашим параметром --require @babel/register Mocha.

@babel/register работает путем "привязки [самого себя] к узлу require и автоматической компиляции файлов на лету".

Вот базовый пример @babel/register в действии:

Из командной строки:

$ node main.js
You will see this, because there is no syntax error!

main.js

require('@babel/register');
// This next file is compiled on the fly
require('./file1.js');

file1.js

import path from 'path';
console.log('You will see this, because there is no syntax error!');

Хорошо, вот как Mocha рекомендует вам включить Babel в их документацию .Опция --require в основном делает то, что делает приведенный выше пример: require('@babel/register'); вызывается до того, как Mocha использует require для импорта всех ваших тестовых файлов.

Надеюсь, это поможет!Опять же, это совершенно понятная загадка в современную эпоху быстро развивающегося JavaScript.

...