Permalink
Browse files

Include syntax-object-rest-spread in default Babel options for Node.j…

…s >= 8.3.0

Fixes #1554.
  • Loading branch information...
codeslikejaggars authored and novemberborn committed Oct 27, 2017
1 parent 035fd31 commit 37c9122c50722b06039f1cc2306a7c176fd3c786
Showing with 80 additions and 8 deletions.
  1. +6 −0 docs/recipes/babelrc.md
  2. +8 −0 lib/babel-config.js
  3. +13 −8 package-lock.json
  4. +2 −0 package.json
  5. +51 −0 test/babel-config.js
View
@@ -15,6 +15,12 @@ There are multiple options for configuring how AVA transpiles your tests using B
AVA lets you use some nifty JavaScript features, like [async functions](https://github.com/avajs/ava#async-function-support). To make this work on older Node.js versions AVA transpiles the tests and helper files using the [`@ava/stage-4`](https://github.com/avajs/babel-preset-stage-4) Babel preset. This is great for projects where you do not use Babel for your source, but do want to use the newest JavaScript features for your tests.
### Using object rest/spread properties
As of Node.js [8.3.0](https://github.com/nodejs/node/blob/v8.3.0/doc/changelogs/CHANGELOG_V8.md#8.3.0) [object rest/spread properties](https://github.com/tc39/proposal-object-rest-spread) is supported directly. This new language feature however has not yet reached [stage 4](http://2ality.com/2015/11/tc39-process.html#stage-4-finished), which means that AVA won't support it by default. That said, if you're using Node.js 8.3.0 or newer, AVA will load the [`syntax-object-rest-spread`](https://www.npmjs.com/package/babel-plugin-syntax-object-rest-spread) plugin for you. This means you *can* use object rest/spread properties in your tests as long as you're not targeting older Node.js versions.
Note that if you customize the Babel configuration you'll have to explicitly specify the `syntax-object-rest-spread` plugin.
## Customizing how AVA transpiles your tests
You can override the default Babel configuration AVA uses for test transpilation in `package.json`. For example, the configuration below adds the Babel `rewire` plugin, and adds the Babel [`stage-3`](http://babeljs.io/docs/plugins/preset-stage-3/) preset.
View
@@ -6,6 +6,7 @@ const figures = require('figures');
const configManager = require('hullabaloo-config-manager');
const md5Hex = require('md5-hex');
const makeDir = require('make-dir');
const semver = require('semver');
const colors = require('./colors');
function validate(conf) {
@@ -99,6 +100,7 @@ function build(projectDir, cacheDir, userOptions, powerAssert) {
const baseOptions = {
babelrc: false,
plugins: [],
presets: [
['@ava/transform-test-files', {powerAssert}]
]
@@ -107,6 +109,12 @@ function build(projectDir, cacheDir, userOptions, powerAssert) {
baseOptions.presets.unshift('@ava/stage-4');
}
// Include object rest spread support for node versions that support it
// natively.
if (userOptions === 'default' && semver.satisfies(process.versions.node, '>= 8.3.0')) {
baseOptions.plugins.push('babel-plugin-syntax-object-rest-spread');
}
const baseConfig = configManager.createConfig({
dir: AVA_DIR, // Presets are resolved relative to this directory
hash: md5Hex(JSON.stringify(baseOptions)),
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -108,6 +108,7 @@
"ava-init": "^0.2.0",
"babel-core": "^6.17.0",
"babel-generator": "^6.26.0",
"babel-plugin-syntax-object-rest-spread": "^6.13.0",
"bluebird": "^3.0.0",
"caching-transform": "^1.0.0",
"chalk": "^2.0.1",
@@ -165,6 +166,7 @@
"require-precompiled": "^0.1.0",
"resolve-cwd": "^2.0.0",
"safe-buffer": "^5.1.1",
"semver": "^5.4.1",
"slash": "^1.0.0",
"source-map-support": "^0.4.0",
"stack-utils": "^1.0.1",
View
@@ -9,6 +9,19 @@ const configManager = require('hullabaloo-config-manager');
const babelConfigHelper = require('../lib/babel-config');
const fixture = name => path.join(__dirname, 'fixture', name);
const setNodeVersion = value => Object.defineProperty(process.versions, 'node', {value});
const resetNodeVersion = setNodeVersion.bind(null, process.versions.node);
// Execute `run` with a given stubbed node version, then reset to the real
// version.
function withNodeVersion(version, run) {
setNodeVersion(version);
const promise = new Promise(resolve => {
resolve(run());
});
promise.then(resetNodeVersion, resetNodeVersion);
return promise;
}
test('uses default presets when userOptions is "default"', t => {
const userOptions = 'default';
@@ -46,6 +59,7 @@ test('uses options from babelrc when userOptions is "inherit"', t => {
t.same(options.presets, [require.resolve('@ava/babel-preset-stage-4')]);
const envOptions = options.env[configManager.currentEnv()];
t.same(envOptions, {
plugins: [],
presets: [
[
require.resolve('@ava/babel-preset-transform-test-files'),
@@ -82,6 +96,43 @@ test('uses userOptions for babel options when userOptions is an object', t => {
});
});
test('adds babel-plugin-syntax-object-rest-spread for node versions > 8.3.0', t => {
const projectDir = uniqueTempDir();
const cacheDir = path.join(projectDir, 'cache');
return withNodeVersion('9.0.0', () => babelConfigHelper.build(projectDir, cacheDir, 'default', true))
.then(result => {
const options = result.getOptions();
t.same(options.plugins, [
require.resolve('babel-plugin-syntax-object-rest-spread')
]);
});
});
test('adds babel-plugin-syntax-object-rest-spread for node versions == 8.3.0', t => {
const projectDir = uniqueTempDir();
const cacheDir = path.join(projectDir, 'cache');
return withNodeVersion('8.3.0', () => babelConfigHelper.build(projectDir, cacheDir, 'default', true))
.then(result => {
const options = result.getOptions();
t.same(options.plugins, [
require.resolve('babel-plugin-syntax-object-rest-spread')
]);
});
});
test('does not add babel-plugin-syntax-object-rest-spread for node versions < 8.3.0', t => {
const projectDir = uniqueTempDir();
const cacheDir = path.join(projectDir, 'cache');
return withNodeVersion('8.2.0', () => babelConfigHelper.build(projectDir, cacheDir, 'default', true))
.then(result => {
const options = result.getOptions();
t.same(options.plugins, []);
});
});
test('should disable power-assert when powerAssert is false', t => {
const userOptions = 'default';
const powerAssert = false;

2 comments on commit 37c9122

@sholladay

This comment has been minimized.

Show comment
Hide comment
@sholladay

sholladay Nov 16, 2017

@novemberborn any chance you could release this soon? Just a friendly nudge.

I am on Node 8.9.1 and writing tests that benefit a lot from object spread and was surprised when AVA blew up. I can confirm that this commit fixes it.

For context, Node 8.3 came out August 10th, and 8.9.0 with Long Term Support status came out October 31st, so it probably has good adoption by now.

sholladay replied Nov 16, 2017

@novemberborn any chance you could release this soon? Just a friendly nudge.

I am on Node 8.9.1 and writing tests that benefit a lot from object spread and was surprised when AVA blew up. I can confirm that this commit fixes it.

For context, Node 8.3 came out August 10th, and 8.9.0 with Long Term Support status came out October 31st, so it probably has good adoption by now.

@novemberborn

This comment has been minimized.

Show comment
Hide comment
@novemberborn

novemberborn Nov 18, 2017

Member

@sholladay yea we could do a release. I'm doing a bit of traveling at the moment so I'm not sure when I'll get around to it. Definitely not on this train's WiFi connection 😉

Member

novemberborn replied Nov 18, 2017

@sholladay yea we could do a release. I'm doing a bit of traveling at the moment so I'm not sure when I'll get around to it. Definitely not on this train's WiFi connection 😉

Please sign in to comment.