avajs/ava

SyntaxError: Unexpected token export (import)

Closed this issue ยท 25 comments

Description

Ava starts to give SyntaxError: Unexpected token export
with babelrc es2015 set to "modules": false.
Does not happen if modules props is not set.
AND Specifying custom config via ava/babel in package.json does not help.

Webpack uses same config. Babel compiles files successfully if executed manually as

babel ./src/app/actions/constants/shared.js --presets=node6

Error Message & Stack Trace

src/app/actions/constants/shared.js:1
(function (exports, require, module, __filename, __dirname) { export var NOT_STARTED = 'NOT STARTED';
                                                              ^^^^^^
SyntaxError: Unexpected token export
    at Object.exports.runInThisContext (vm.js:76:16)
    at Module._compile (module.js:542:28)
    at loader (/Users/dlebedynskyi/Documents/Code/code/node_modules/babel-register/lib/node.js:144:5)
at require.extensions.(anonymous function) (/Users/dlebedynskyi/Documents/Code/code/node_modules/babel-register/lib/node.js:154:7)
    at extensions.(anonymous function) (/Users/dlebedynskyi/Documents/Code/code/node_modules/require-precompiled/index.js:16:3)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/dlebedynskyi/Documents/Code/code/node_modules/ava/lib/process-adapter.js:104:4)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)

Config

package.json:

{
    "ava": {
    "files": [
      "test/**/*.spec.js"
    ],
    "source": [
      "src/**/*.{js,jsx}"
    ],
    "concurrency": 5,
    "require": [
      "babel-register",
      "babel-polyfill",
      "ignore-styles",
      "./test/setup.js"
    ],
    "babel": "inherit"
  }
}

.babelrc

{
  "plugins": [
    "transform-export-extensions",
    "transform-class-properties",
    ["transform-builtin-extend", {
        "globals": ["Error"]
    }],
    ["transform-object-rest-spread", {
      "useBuiltIns": true
    }],
    ["transform-react-jsx", {
      "useBuiltIns": true
    }],
    ["transform-regenerator", {
      "async": false
    }],
    ["transform-runtime", {
      "helpers": false,
      "polyfill": false,
      "regenerator": true
    }],
    "react-hot-loader/babel"
  ],
  "presets": [
    "react",
    ["latest", {
      "es2015" : {
        "modules": false,
        "loose": true
      }
    }]
  ]
}

Command-Line Arguments

npm run ava

What I had tried and it did not work

  1. specify custom babel config in ava section
"ava": {
   ...
    "require": [
      "babel-register",
      "babel-polyfill",
      "ignore-styles",
      "./test/setup.js"
    ],
    "babel": {   "presets": [ "react",   "latest"] }
}
  1. specify "node6"
"ava": {
    ...,
    "babel": {
      "babelrc": false,
      "presets": [ "node6" ]
    }
  },
  1. Try use extend as https://github.com/avajs/ava/blob/master/docs/recipes/babelrc.md#extend-an-alternate-config-file - same result.

Environment

Node.js v6.9.1
darwin 16.1.0
ava 1.7.0

It looks like test files are being transpired correctly but for source files are ignored :(.
This happens only with modules:false. And this is being set so for tree shacking webpack2. To enable common js modules I've tried things above an it still looks like .babelrc is used without overrides.

modules: false disables transpiling the module syntax to Node.js' module system. You'll need to enable that for AVA to work.

I was having the same "problem"

.babelrc

{
  "presets": ["es2017"]
}

package.json

  "ava": {
    "files": [
      "test/**/*.test.js"
    ],
    "source": [
      "src/**/*.{js,jsx}",
      "!dist/**/*"
    ],
    "modules": false,
    "concurrency": 5,
    "failFast": true,
    "tap": true,
    "powerAssert": true,
    "require": [
      "babel-register"
    ],
    "babel": "inherit"
  },
> ava

TAP version 13
/Users/kristianmandrup/repos/node-libs/rx-aster/test/aster/aster.test.js:1
(function (exports, require, module, __filename, __dirname) { import _asyncToGenerator from '/Users/kristianmandrup/repos/node-libs/rx-aster/node_modules/babel-runtime/helpers/asyncToGenerator.js';
                                                              ^^^^^^
SyntaxError: Unexpected token import

Works with another .babelrc setup in another project of mine, I think the transform-runtime plugin is key.

{
  "presets": ["es2015", "stage-2"],
  "plugins": ["transform-runtime"],
  "comments": false
}

However adding "plugins": ["transform-runtime"], to my es2017 preset setup didn't work.
I guess I will have to go back to es2015!?

Please update your docs and recipes for various babel preset setups. Cheers!

Where do I set modules: false !?

This is what I had working:

    "ava": "^0.17.0",
    "babel-core": "^6.0.0",
    "babel-eslint": "^7.0.0",
    "babel-loader": "^6.0.0",
    "babel-plugin-transform-runtime": "^6.0.0",
    "babel-preset-es2015": "^6.0.0",
    "babel-preset-stage-2": "^6.0.0",
    "babel-register": "^6.18.0",
    "tap-nyan": "^1.1.0"

@novemberborn
I tried to override .babelrc with package.json/ava/ babel section. And this is a part that did not work.
Problem for me was that I expected that override with no modules to be used. It was not.

For now I have a workaround that I do not like -
having .client.babelrc with "modules: false" for webpack 2 client build
and .babelrc without - for ava.

@mandricore he is talking about modules false in babelrc file es2015 section.

@mandricore The modules setting needs to be true, which is the default. However the es2017 preset does not include module transpilation. It "only compiles what's in ES2017 to ES2016".


@dlebedynskyi try extending your existing .babelrc. Then either load the es2015 transform with the modules enabled, or specifically add the transform-es2015-modules-commonjs plugin.

@novemberborn
still getting same error

//package.json 
"ava": {
    "files": [
      "test/**/*.spec.js"
    ],
    "source": [
      "src/**/*.{js,jsx}"
    ],
    "concurrency": 5,
    "require": [
      "babel-core/register",
      "babel-polyfill",
      "ignore-styles",
      "./test/setup.js"
    ],
    "babel": {
      "babelrc": true,
      "plugins": ["transform-es2015-modules-commonjs"]
    }
  },
//.babelrc is client specific. expected to be merged with ava/babel for ava run
{
  "sourceMaps": true,
  "presets": [
    "react",
    "es2017",
    "es2016",
    ["es2015", { "modules": false }]
    ],
  "plugins": [
    "transform-class-properties",
    ["transform-object-rest-spread", {
      "useBuiltIns": true
      }],
    ["transform-react-jsx", {
      "useBuiltIns": true
      }],
    ["transform-regenerator", {
      "async": false
      }],
    ["babel-plugin-transform-builtin-extend", {
        "globals": ["Error"]
    }],
    ["babel-plugin-transform-runtime", {
      "helpers": false,
      "polyfill": false,
      "regenerator": true
      }],
    "transform-export-extensions",
    "react-hot-loader/babel"
  ]
}

also tried to set

"ava": {
/// 
"babel": {
      "babelrc": true,
      "presets": [
        "react",
        "es2017",
        "es2016",
        "es2015"
        ]
      }
    },

only way i had it working is to have .babelrc targeting ava/nodejs and building client with other config. it looks like babel section in ava is ignored.

@dlebedynskyi that's odd. Not sure how to help you further though. Any chance you could set up a GitHub repo with a reproduction?

@novemberborn working on it.

Ah! The issue is with babel-core/register using the .babelrc config, which isn't set up to transform module syntax. Currently there's nothing AVA can do about this.

That said, you could still simplify the ava.babel section to:

{
  "plugins": ["transform-es2015-modules-commonjs"]
}

And the test files themselves will run.

I've been thinking about how we could provide better support for Babel-based projects. I'll keep your use case in mind, where you want AVA to transpile source files using a different config than used by your build step.

@novemberborn Thanks for tracking this. I expected something like this.
I think I've tried "transform-es2015-modules-commonjs" before with same result.
Checked again - even removing "babel-core/register", and adding transform-es2015-modules-commonjs - same error in source files. test files run fine.

I think the best way to solve this would be the use the env property in the .babelrc and set this when ever running the tests. Working on it now and will post the results here when Im done.

Yeah so this is working for me:

{
  "env": {
    "test": {
      "presets": ["es2015-node4"]
    }
  },
  "presets": [
    [
      "env",
      {
        "targets": {
          "browsers": ["> 10%"]
        },
        "modules": false
      }
    ]
  ]
}

I then run my tests like this: BABEL_ENV=test gulp ava

It means I can keep module transpilation disabled for the rollup build and can transpile them when running ava

@ahumphreys87 this is interesting solution. going to try and see how it will work on out setup

I have also had this issue and was solved by following @ahumphreys87 solution - cheers

@novemberborn mentioned on gitter "We're working on making it easier to extend a babel config while specializing it for tests etc"

@stevenmathews we ended up still having client.babelrc and server.babelrc. Both are using babel-preset-env now. Server one is having test section for Ava like @ahumphreys87 suggested. We also saw problem with babel-register and "import" statements in node_modules - like lodash-es.
Anyway thanks to @ahumphreys87 for idea of solution

No luck...

Same here. I have no .babelrc set up (don't need to, I'm using webpack), and want to use ava with es6 modules.
After trying all the above configuration setups, I still get the same error

Using a .babelrc, it works. I copied https://github.com/jamestalmage/__ava-0.8-with-babel-6

Make sure your modules are inside the src folder

.babelrc

npm install babel-preset-stage-0 --save

Add to your configuration present list -[..., "stage-0"]

It worked for me!

You need add preset "es2015" and maybe "transform-class-properties" into .babelrc.

  "babel": {
    "presets": [
      "es2015"
    ],
    "plugins": [
      "transform-runtime",
      "transform-class-properties"
    ]
  },
  "ava": {
    "concurrency": 5,
    "failFast": true,
    "failWithoutAssertions": false,
    "tap": true,
    "powerAssert": false,
    "require": [
      "babel-register",
      "./test/helpers/setup-browser-env.js"
    ],
    "babel": "inherit"
  }

Still getting this error. Anyone see what I might be missing? I've tried all the suggestions in this thread.

reinstall node_modules

I'll leave a comment here since this is the latest issue on AVA.

I fixed the SyntaxError: Unexpected token import error in Node 12 with

  "ava": {
    "nodeArguments": [
      "--experimental-modules"
    ]
  }

No esm package or babel configuration was required to use import/export in local files, test files, and imported modules, as long as they also have type:module and main:index.js set.

fregante/webext-storage-cache@47b0077#diff-b9cfc7f2cdf78a7f4b91a753d10865a2

I'm using the AVA 3.3.0