Node.js mocha/babel如何动态传输我的测试代码?

Node.js mocha/babel如何动态传输我的测试代码?,node.js,ecmascript-6,mocha.js,transpiler,Node.js,Ecmascript 6,Mocha.js,Transpiler,我的问题不是为什么有些东西不起作用,而是为什么起作用。是。 我有一个小的示例,其中包含nodeJS尚不支持的现成功能,最显著的是: import语句 String.includes() 因此,为了交付(构建),我传输并捆绑我的源代码(使用,就像webpack一样) 作为一个积极的奇迹,我的所有mocha测试(除了一个)都直接针对我的类运行,而不是包。尽管如此,它们仍然有效!包括许多import语句。包括“ES6自检”: it( 'String - include', () => {

我的问题不是为什么有些东西不起作用,而是为什么起作用。是。

我有一个小的示例,其中包含nodeJS尚不支持的现成功能,最显著的是:

  • import
    语句
  • String.includes()
因此,为了交付(构建),我传输并捆绑我的源代码(使用,就像webpack一样)

作为一个积极的奇迹,我的所有mocha测试(除了一个)都直接针对我的类运行,而不是包。尽管如此,它们仍然有效!包括许多
import
语句。包括“ES6自检”:

it( 'String - include', () => {
    var s = 'Southern Bananas'
    assert( s.includes( 'anana' ) )
    assert( !s.includes( 'kiwi' ) )
} )
因此: 我的测试代码中有String.include,而不仅仅是在测试源代码中。没有地方可以传输或捆绑我的测试代码……因此,我为我的愚蠢问题道歉:

为什么会这样?在什么地方有没有及时编译的秘密?(如果是的话,我可以用它来调试测试中的可交付代码吗?) 我的
mocha.opts
非常简单:

--require @babel/register
--require ./test/once.js  (nothing special here, either)
--reporter list
--recursive
我的
.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运行时
显然不能怪表扬,因为它

注:实例方法,如“foobar”。包括(“foo”) 将不起作用,因为这需要修改 现有内置(您可以使用@babel/polyfill)

minimalistik modern afaik中是否包含
@babel/polyfill
?还有什么我做对了:+)?有没有办法在我的(调试)构建中也使用此实时编译?

长话短说 从v6.5开始,Node.js就支持
String.prototype.includes
@babel/register
导致您的代码被动态编译,这就是您的
import
语句工作的原因。我怀疑你是否需要
@babel/plugin transform runtime
插件,除非我错过了你想要实现的东西

什么会导致这种混乱? 我认为这个(完全可以理解的)谜团有两个根本原因:

  • 巴别塔的作者们已经使得使用这个工具变得非常容易;有时很难知道它是如何/何时被调用的(特别是当与另一个工具如Mocha配对时)
  • 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模块。但是,我想谈谈它是如何作为一项实验性功能启用的

    因此,您可以通过native Node.js v8.x(通过REPL)获得以下信息:

    导入工作正常的原因是,Babel正在使用
    @Babel/preset env
    预设编译您的代码。
    此外,编译是由您的
    --require@Babel/register
    摩卡选项触发的

    其工作原理是“将自身绑定到节点的需要,并动态自动编译文件”

    以下是
    @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!');
    
    好的是,这就是摩卡建议您整合巴贝尔的方式。
    --require
    选项基本上与上面的示例相同:
    require(“@babel/register”)require
    导入所有测试文件之前调用code>


    希望这有帮助!同样,在JavaScript快速发展的现代,这是一个完全可以理解的谜。

    谢谢!这种即时编译是否会导致临时文件出现在某个“隐藏”文件夹中?还是全部都在内存中我可以让我的系统直接运行即时编译吗?(不是“发布”,而是自然开发…)据我所知,
    @babel/register
    在内存中编译。但它确实保持了一个稳定的状态。那个Babel's for development仅供CLI使用。它的作用与节点CLI相同,只是它在执行之前编译文件。也许你可以用这个?或者在CLI的入口点中集成
    @babel/register
    。哈!“生产警告”实际上准确地告诉了我,我在问什么
    import path from 'path';
    console.log('You will see this, because there is no syntax error!');