Ava: Help update recipes for Babel 7

Created on 28 Jan 2018  路  10Comments  路  Source: avajs/ava

We're upgrading AVA to use Babel 7. As part of this the way you configure AVA's Babel pipeline has changed.

There are various recipes which either use Babel 6 dependencies or AVA's previous configuration. For some recipes we just need to update the dependencies and configuration, for others we may need to test them a bit to make sure everything still works with Babel 7 in the mix.

Babel 7 uses the @babel scope on npm. Typically dependencies are renamed from babel-plugin-transform-something to @babel/plugin-transform-something.

AVA's configuration places the Babel options inside a testOptions key:

{
  "ava": {
    "babel": {
      "testOptions": {}
    }
  }
}

inherits has been removed, since it has become the default behavior. default has also been removed. See the Babel recipe for all the details.

Here's the recipes that need updating:

  • [x] [Code coverage](https://github.com/avajs/ava/blob/master/docs/recipes/code-coverage.md)
  • [x] [JSPM and SystemJS for ES2015](https://github.com/avajs/ava/blob/master/docs/recipes/jspm-systemjs.md)
  • [x] [Precompiling source files with webpack](https://github.com/avajs/ava/blob/master/docs/recipes/precompiling-with-webpack.md)
  • [x] [Testing React components](https://github.com/avajs/ava/blob/master/docs/recipes/react.md)
  • [x] [Testing Vue.js components](https://github.com/avajs/ava/blob/master/docs/recipes/vue.md)

Let's make this happen! 馃槂

good for beginner help wanted documentation

Most helpful comment

@BusbyActual woohoo!

There's no tests, no. These are descriptions of how you would use AVA for certain use cases. I suppose we could host a repository where you can put "playgrounds", as it were. Not sure if it makes sense for all recipes though.

All 10 comments

Claimed : ^). Are there tests to run against? I'm not sure how to confirm each case is working as intended.

@BusbyActual woohoo!

There's no tests, no. These are descriptions of how you would use AVA for certain use cases. I suppose we could host a repository where you can put "playgrounds", as it were. Not sure if it makes sense for all recipes though.

For

  • [ ] [Testing Vue.js components](https://github.com/avajs/ava/blob/master/docs/recipes/vue.md) I don't see any changes needed. Require extension hooks appears to be a bit different than @babel/register.

@BusbyActual the configuration needs to be cleaned up: "babel": "inherit" is now the default. I don't know if that extension hook works with Babel 7. There's also an outdated link to the Babel recipe.

@novemberborn After struggling to get the test suite added to my new nuxt.js app, I can confirm the current recipe does not work, but after a few hours of receiving this error:

> yarn test
yarn run v1.5.1
$ ava

2 exceptions

Uncaught exception in tests/foo.spec.js
Error: Requires Babel "^7.0.0-0", but was loaded with "6.26.0". If you are
sure you have a compatible version of @babel/core, it is likely that something
in your build process is loading the wrong version. Inspect the stack trace of
this error to look for the first entry that doesn't mention "@babel/core" or
"babel-core" to see what is calling Babel.

I did eventually get it working with a few modifications to the current recipe. Running the test suite actually works, that is, figuring out coverage is the next thing on my todo list. Once I get that working, I'd be more than happy to submit a pull request updating it. I'm far from a babel expert though, so I fear it may only be working out of sheer luck. So, I'll just post my setup here and hopefully someone else can confirm it works, and/or point out better way to do something while I attempt to get the coverage working.

package.json

"ava": {
  "files": [
    "tests/**/*.spec.js"
  ],
  "sources": [
    "**/*.{js,vue}"
  ],
  "require": "./tests/helpers/setup.js"
}

tests/helpers/setup.js

require("jsdom-global")();
// Pretty sure require("browser-env")(); still works here though
const hooks = require("require-extension-hooks");
hooks("vue").plugin("vue").push();
require("@babel/register")({
  extensions: [".vue", ".js"],
});

_I used jsdom-global here instead of browser-env just because the vue-test-utils guide recommends it_

.babelrc

{
  "presets": [
    "@babel/preset-env",
    "babel-preset-vue"
  ],
  "plugins": [
    "@babel/plugin-transform-runtime",
    "@babel/plugin-proposal-object-rest-spread",
    "@babel/plugin-proposal-pipeline-operator",
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-transform-modules-commonjs"
  ]
}

_Edit for completeness, the Foo.vue and foo.spec.js files_

components/Foo.vue

<template>
  <div>hello world</div>
</template>

<script>
export default {
  props: {
    bar: { default: false },
  },
  methods: {
    baz() {
      return true;
    },
  },
};
</script>

tests/foo.spec.js

import test from "ava";
import { shallow } from "@vue/test-utils";
import { createRenderer } from "vue-server-renderer";
import Foo from "../components/Foo.vue";

test("Foo text is 'hello world'", t => {
  const wrapper = shallow(Foo);
  t.is(wrapper.text(), "hello world");
});

test("Foo prop bar returns true", t => {
  const wrapper = shallow(Foo, { propsData: { bar: true } });
  t.true(wrapper.props().bar);
});

test("Foo.baz() returns true", t => {
  const wrapper = shallow(Foo);
  t.true(wrapper.vm.baz());
});

// The SSR way of rendering a component wrapper to an html
// string, it's "formatted", but this will also add the attribute
//     data-server-rendered="true"
// to the rendered tags
test("Foo SSR snapshot", async t => {
  const wrapper = shallow(Foo);
  const renderer = createRenderer();
  t.snapshot(await renderer.renderToString(wrapper.vm));
});

// If you just want a string of html for the snapshot
test("Foo snapshot unformatted", t => {
  const wrapper = shallow(Foo);
  t.snapshot(wrapper.html());
});

// Or if you want the snapshot html to be formatted
const beautify = require("js-beautify").html;
const beautifyOpts = {
  unformatted: [],
  indent_size: 2,
  preserve_newlines: true,
  wrap_attributes: "force-aligned",
};

test("Foo snapshot formatted", t => {
  const wrapper = shallow(Foo);
  t.snapshot(beautify(wrapper.html(), beautifyOpts));
});
// This would save a snapshot as:
// <div class="foo"
//      role="baz">
//   <span>hello world</span>
// </div>
// Rather than the single line string wrapper.html() returns:
// <div class="foo" role="baz"><span>hello world</span></div>
// Which makes the diffs easier to read

The suite this works on is only a few basic tests done using @vue/test-utils, so there may still be something that won't work with this setup. Snapshot testing does work though, but that was the only thing out side of pretty much t.true(1 === 1) I've tried writing.

Edit: And fortunately there weren't any issues setting up coverage, yarn add -D nyc and changing "test": "ava" to "test": "nyc ava" in the package.json was all I needed to get that working.

I'll look into the Vue docs shortly. Slipped my mind : )

babelrc: false not working.

my .babelrc config.

{
  "presets": [
    ["env", {
      "modules": false,
      "targets": { "browsers": ["Android >= 4", "iOS >= 9"] }
      }
    ],
    "stage-2"
  ],
  "plugins": [
    "lodash",
    "transform-decorators-legacy",
    "transform-runtime"
  ]
}

my ava config.

{
  "ava": {
    "files": [
      "packages/**/__tests__/**/*.js",
      "!packages/**/dist/**/*",
      "!packages/**/node_modules/**/*"
    ],
    "require": ["@babel/register"],
    "babel": {
      "testOptions": {
        "babelrc": false,
        "presets": [
          "@babel/env",
          "@babel/stage-2"
        ]
      }
    }
  }
}

The error message

image

it still use babel-preset-stage-2 instead of @babel/preset-stage-2
I'm using [email protected]

@lili21 if you could file a separate issue for this, with a small GitHub project that reproduces the problem, that'd be great.

@novemberborn #1767

Thanks for your hard work on this @BusbyActual!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fregante picture fregante  路  3Comments

sindresorhus picture sindresorhus  路  3Comments

fleg picture fleg  路  3Comments

niftylettuce picture niftylettuce  路  4Comments

sindresorhus picture sindresorhus  路  4Comments