如何在Jest中使用babel-preset-env

5
我们正在更新API,Babel的Henry Zhu提醒我有一个名为“babel-preset-env”的预设可以替代“babel-preset-es2015”和“babel-preset-es2018”。
现在,我遇到了困难,不知道如何处理一切最简单的方法。
我们的API使用node v8.x和async/await,原生的promise。
我想要spread操作符。
我想要pipeline操作符。
我想要import/export语法。
我想支持Jest。
我喜欢babel-node将API转译到内存中的方式。
如果我展示一下我们当前配置的位置,这将更容易:
.babelrc
 {
   "presets": [
     "env",
       {
         "targets": {
           "node": "current"
         }
       },
     "jest"
   ]
 }

package.json

 {
   "scripts": {
     "test": "node --harmony-async-await node_modules/jest/bin/jest.js",
     "start:local": "NODE_ENV=localhost npm run babel-node -- warpcore/server.js",
     "start": "npm run babel-node -- warpcore/server.js",
     "babel-node": "babel-node --presets=es2015,stage-2"
   },
   "dependencies": {
     "babel-polyfill": "^6.23.0"
   },
   "devDependencies": {
     "babel-cli": "^6.24.1",
     "babel-core": "^6.25.0",
     "babel-eslint": "^7.2.3",
     "babel-jest": "^20.0.3",
     "babel-preset-env": "^1.6.0",
     "babel-preset-es2015": "^6.24.1",
     "babel-preset-es2018": "^1.0.0",
     "babel-preset-stage-2": "^6.24.1",
     "jest": "^20.0.4"
   },
   "jest": {
     "testURL": "http://localhost:8080",
     "testEnvironment": "node"
   }
 }

我不确定这些东西应该如何组织才能最好地实现上面的任务清单。

我应该做什么改变?

  • 我认为 babel-node 脚本需要进行更改
  • 我怀疑我可以删除其中一些包
  • 我怀疑 .babelrc 文件不是最佳配置
3个回答

8
如果你想在Jest中使用babel-preset-env代替已经被弃用的babel-preset-es2015,那么你需要确保在你的"env"配置中,"modules"属性被设置为"commonjs"。以下是一个示例配置:

.babelrc

{     
  "env": {
    "test": {
      "plugins": [
        "transform-class-properties",
        "transform-object-rest-spread"
      ],
      "presets": [
        "jest",
        "react",
        [
          "env",
          {
            "debug": false,
            "modules": "commonjs",
            "targets": {
              "node": "current"
            },
            "useBuiltIns": true
          }
        ]
      ]
    }
  }
}

你可以在env.test中看到,预设env(即“babel-preset-env”配置)将“modules”设置为“commonjs”。这很重要,否则你会得到“SyntaxError:Unexpected token import”的错误提示。
为了完整起见,这里是一个简单的测试:

ExampleButton.test.jsx

import ExampleButton from './ExampleButton';
import React from 'react';
import renderer from 'react-test-renderer';

test('Example Test', () => {
  const component = renderer.create(<ExampleButton />);
  const json = component.toJSON();
  expect(json.type).toBe('button');
});

ExampleButton.jsx

import React from 'react';

class ExampleButton extends React.Component {
  render() {
    return (
      <button onClick={this.props.onClick}>
        {this.props.text}
      </button>
    )
  }
}

export default ExampleButton;

对于我的Babel设置,我使用了以下依赖项:

"babel-core": "6.26.0",
"babel-jest": "21.2.0",
"babel-plugin-transform-class-properties": "6.24.1",
"babel-plugin-transform-object-rest-spread": "6.26.0",
"babel-preset-env": "1.6.1",
"babel-preset-react": "6.24.1",
"jest": "21.2.1",
"react-test-renderer": "16.1.1",

2
当我从Babel 6迁移到7时,我通过艰难的方式发现了这一点。在Babel 6中,默认情况下是modules: 'commonjs',而Babel 7的preset-env则没有。但是为什么jest需要commonjs模块呢?无论我如何阅读有关commonjs、amd、umd等之间差异的文章,我都从未真正理解过这一部分。是否有一个简单的解释,可以说明为什么jest绝对需要commonjs? - Dac0d3r
@Dac0d3r 因为Jest钩入了require函数来处理模拟依赖项,所以它无法处理import语句。此外,在非实验性的Node环境中还不支持import,因此会出现语法错误。 - sepehr

5

我觉得我已经解决了。以下是解决方案:

.babelrc文件

问题中发布的一个语法错误,因为env预设需要用方括号[]括起来 (来源: http://babeljs.io/docs/plugins/preset-env/)

正确写法:

 {
   "presets": [
     ["env",
       {
         "targets": {
           "node": "current"
         }
       }],
     "jest"
   ]
 }

package.json

这个问题中发布的 package.json 文件有一些可以省略的内容:

  {
     "scripts": {
       "test": "jest --verbose",
       "start:local": "cross-env NODE_ENV=localhost babel-node -- app.js",
       "babel-node": "babel-node --presets=env"
    },
    "dependencies": {
      "babel-cli": "^6.24.1",
      "babel-preset-env": "^1.6.0"
    },
    "devDependencies": {
      "babel-eslint": "^7.2.3",
      "babel-jest": "^20.0.3",
      "jest": "^20.0.4"
    },
    "jest": {
      "testURL": "http://localhost:8080",
      "testEnvironment": "node"
    }
  }

在我看来,这个方法要简洁得多。如果您想明确地包含或排除某些预设,或者指定要支持的浏览器,则可以从.babelrc文件中调节预设。

更新:我已经使用接受答案中所示的内容几个月了,效果很好。 - agm1984
你如何进行生产环境的实现? https://babeljs.io/docs/en/babel-cli#not-meant-for-production-use 不适用于生产环境 你不应该在生产环境中使用 babel-node。它过于沉重,由于缓存存储在内存中,会占用大量内存。您还将始终经历启动性能惩罚,因为整个应用程序需要即时编译。查看使用Babel部署生产环境的Node.js服务器示例,以了解如何使用Babel。 - Victor Grados

0
这是我找到的解决方案:
{
  "presets": ["@babel/env", "@babel/react"]
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接