babel: Unexpected token, expected "" by 7.0.0-beta.48

Edit by @nicolo-ribaudo

To fix this problem, pass the isTSX: true option to the TypeScript plugin.

Bug Report

Current Behavior JSX code below is not parsed by 7.0.0-beta.48 since today although it is parsed no problem yesterday with 7.0.0-beta.47

Input Code

ERROR in ./src/some.jsx
Module build failed: SyntaxError: src/some.jsx: Unexpected token, expected "</>" (24:16)

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from "react-redux";
import {Router} from "react-router";

  22 |   return (
  23 |     <SomeProvider>
> 24 |       <Provider store={store} key="provider">
     |                 ^
  25 |         <Router history={history}>
  26 |           <Application/>
  27 |         </Router>
    at _class.raise (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:3858:15)
    at _class.unexpected (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5187:16)
    at _class.expectRelational (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5128:12)
    at _class.tsParseTypeAssertion (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:9212:12)
    at _class.parseMaybeUnary (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:10109:21)
    at _class.tsParseTypeAssertion (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:9213:30)
    at _class.parseMaybeUnary (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:10109:21)
    at _class.parseExprOps (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5751:21)
    at _class.parseMaybeConditional (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5723:21)
    at _class.parseMaybeAssign (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5670:21)
    at _class.parseMaybeAssign (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:10096:87)
    at _class.parseParenAndDistinguishExpression (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:6411:28)
    at _class.parseExprAtom (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:6221:21)
    at _class.parseExprSubscripts (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5865:21)
    at _class.parseMaybeUnary (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5844:21)
    at _class.parseMaybeUnary (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:10111:54)
    at _class.parseExprOps (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5751:21)
    at _class.parseMaybeConditional (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5723:21)
    at _class.parseMaybeAssign (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5670:21)
    at _class.parseMaybeAssign (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:10067:87)
    at _class.parseExpression (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5623:21)
    at _class.parseReturnStatement (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:7430:28)
    at _class.parseStatementContent (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:7116:21)
    at _class.parseStatementContent (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:9813:58)
    at _class.parseStatement (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:7082:17)
    at _class.parseBlockOrModuleBlockBody (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:7629:23)
    at _class.parseBlockBody (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:7616:10)
    at _class.parseBlock (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:7605:10)
    at _class.parseFunctionBody (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:6862:24)
    at _class.parseArrowExpression (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:6814:10)
    at _class.parseExprAtom (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:6168:18)
    at _class.parseExprSubscripts (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5865:21)
    at _class.parseMaybeUnary (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5844:21)
    at _class.parseMaybeUnary (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:10111:54)
    at _class.parseExprOps (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5751:21)
    at _class.parseMaybeConditional (/Users/mts/some-site/node_modules/@babel/parser/lib/index.js:5723:21)
const client = (Application) => {
  return (
    <SomeProvider>
      <Provider store={ store } key="provider">
        <Router history={ history }>
          <Application/>
        </Router>
      </Provider>
    </SomeProvider>
  );
};

Expected behavior/code JSX gets properly parsed.

Babel Configuration (.babelrc, package.json, cli command)

  "devDependencies": {
    "@babel/core": "7.0.0-beta.48",
    "@babel/plugin-syntax-decorators": "7.0.0-beta.48",
    "@babel/plugin-syntax-jsx": "7.0.0-beta.48",
    "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.48",
    "@babel/plugin-syntax-typescript": "7.0.0-beta.48",
    "@babel/plugin-transform-runtime": "7.0.0-beta.48",
    "@babel/plugin-transform-shorthand-properties": "7.0.0-beta.48",
    "@babel/preset-react": "7.0.0-beta.48",

  "dependencies": {
    "@babel/runtime": "7.0.0-beta.48",
{
  test: /\.jsx?$/,
  exclude: /(node_modules)/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: [
          '@babel/preset-react'
      ],
      babelrc: false,
      "plugins": [
        "@babel/plugin-syntax-typescript",
        "@babel/plugin-syntax-decorators",
        "@babel/plugin-syntax-jsx",
        "@babel/plugin-transform-runtime"
      ]
    }
  }
}

Environment

  • Babel version(s): 7.0.0-beta.48
  • Node/npm version: node v8.11.1, npm 6.0.0
  • OS: MacOS Sierra 10.13.4
  • Monorepo: yes
  • How you are using Babel: loader

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 13
  • Comments: 33 (18 by maintainers)

Most upvoted comments

I’m seeing the same issue as well and downgrading only @babel/preset-react to 7.0.0-beta.47 fixes the issue.

This seems to happen when the typescript syntax or transform plugin are used directly.

It seems that, currently, only the preset is capable of actually looking at the file extension and decide whether JSX or typescript parsing is enabled or disabled. It needs to do it because .ts files are not allowed to use JSX as it conflicts with the old-style angle bracket cast (const y = <Foo>x;).

A workaround for this would be to give { isTSX: true } as an option to the syntax plugin, but this would also just enable isTSX on all files, even .ts files.

You are right, this needes to at least be well documented.

@nicolo-ribaudo I don’t think this issue should be closed.

While the proposed workaround may work it is absolutely not obvious. Lots of users will face the exact same issue and will spend hours investigating.

Babel needs to know if it is parsing .ts or .tsx module, and this can be specified using the isTSX option.

How did this use to work in 7.0.0-beta.47 without specifying isTSX options? Maybe it can be fixed properly. I can give it a try.

In case there is no proper fix this has to be at least documented or some hints should be added to error message before closing this issue.

downgrading to version 47 worked for me.

The typescript plugin ignores the syntax-jsx plugin because TypeScript itself handles .ts files and .tsx files differently: the same syntax is used to mean different things in those two kind of ts files. Babel needs to know if it is parsing .ts or .tsx module, and this can be specified using the isTSX option.

For example

var foo = <T>(arg: T) => { };

in a .ts file is totally fine, but in a .tsx file it will throw an exception as an unclosed JSX element.

These are possible configs that you may want to use:

// Always use TypeScript + JSX
module.exports = {
  plugins: [
    ["@babel/plugin-syntax-typescript", { isTSX: true }]
  ]
};

// Use JSX in .tsx files, type casts in .ts files
module.exports = {
  overrides: [{
    test: /.ts$/,
    plugins: [
      "@babel/plugin-syntax-typescript"
    ]
  }, {
    test: /.tsx$/,
    plugins: [
      ["@babel/plugin-syntax-typescript", { isTSX: true }]
    ]
  }]
}

// Use JSX in .tsx and .jsx files, type casts in .ts files
module.exports = {
  overrides: [{
    test: /.ts$/,
    plugins: [
      "@babel/plugin-syntax-typescript"
    ]
  }, {
    test: /.tsx$/,
    plugins: [
      ["@babel/plugin-syntax-typescript", { isTSX: true }]
    ]
  }, {
    test: /.jsx$/,
    plugins: [
      "@babel/plugin-syntax-jsx"
    ]
  }]
}

Can confirm that I do have typescript transform enabled and that it seems to have been caused by having React code in .ts files.

👍 there’s probably something to do with ts and jsx syntax collapsing