Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack 4, babel 7, react, typescript: Unexpected token, expected ","

Error:

ERROR in ./src/client/index.tsx
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: ***\src\client\index.tsx: Unexpected token, expected "," (5:16)

  3 | 
  4 | const a = {title: 'te'}
> 5 | const x = <span {...a}/>
    |                 ^
  6 | console.log(`>>>`, a)

webpack config:

import * as Webpack from 'webpack';
import {Compiler} from 'webpack';
import * as WebpackDevServer from 'webpack-dev-server';
import {paths} from './paths';
import {alias} from './alias';


const domain = ''
const createWebpackConfig = (): Webpack.Configuration => {
  const config: Webpack.Configuration = {
    mode: 'development',
    devtool: 'cheap-module-source-map',
    entry: [
      'react-hot-loader/patch',
      paths.appEntryFile,
    ],
    output: {
      // Add /* filename */ comments to generated require()s in the output.
      pathinfo: true,
      // This does not produce a real file. It's just the virtual path that is
      // served by WebpackDevServer in development. This is the JS bundle
      // containing code from all our entry points, and the Webpack runtime.
      filename: 'static/js/[name].bundle.js',
      // There are also additional JS chunk files if you use code splitting.
      chunkFilename: 'static/js/[name].chunk.js',
      // This is the URL that app is served from. We use "/" in development.
      publicPath: '/',
    },
    resolve: {
      alias,
      extensions: ['.tsx', '.ts', '.js', '.jsx'],
    },
    module: {
      rules: [
        {
          test: /\.(j|t)sx?$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              cacheDirectory: true,
              babelrc: false,
              presets: [
                ['@babel/preset-env', {
                  targets: '> 0.25%, not dead',
                  // Only add polyfills our code might need
                  useBuiltIns: 'usage',
                  debug: true,
                  // Looks like by default bable uses core-js 2 which breaks
                  corejs: 3,
                  modules: 'commonjs'
                }],
                '@babel/preset-react'
              ],
              plugins: [
                // To have `private` on class properties. `loose:true` to don't add bloat to the code.
                ['@babel/plugin-proposal-class-properties', {loose: true}],
                // Ability to do: `const enum`
                'babel-plugin-const-enum',
                // Ability to use typescript, has to be after 'babel-plugin-const-enum' otherwise will complain
                ['@babel/plugin-transform-typescript', {allowNamespaces: true}],
                'react-hot-loader/babel',
              ],
            },
          },
        },
        {
          test: /\.(png|jpe?g|gif)$/i,
          use: [
            {
              loader: 'file-loader',
            },
          ],
        },
      ]
    },
    plugins: [
    ],
    node: {
      fs: 'empty',
      net: 'empty',
      // Because of promise-request
      tls: 'empty'
    }
  }
  return config
}


const compiler = Webpack(createWebpackConfig());

const host = '127.0.0.1';
const devServerOptions: WebpackDevServer.Configuration = {
  open: false,
  host,
  hot: true,
  stats: {
    colors: true,
  },
}

const server = new WebpackDevServer(compiler, devServerOptions);

server.listen(3000, host, () => {
  console.log('Starting server on http://localhost:3000');
});

index.tsx:


import * as React from 'react';

const a = {title: 'te'}
const x = <span {...a}/>
console.log(`>>>`, a)

partial package.json (plus more crap):


    "@babel/core": "^7.8.4",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/plugin-transform-typescript": "^7.8.3",
    "@babel/polyfill": "^7.8.3",
    "@babel/preset-env": "^7.8.4",
    "@babel/preset-react": "^7.8.3",
    "babel-cli": "^6.26.0",
    "babel-jest": "^25.1.0",
    "babel-loader": "^8.0.6",
    "babel-plugin-const-enum": "^0.0.5",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react-app": "^9.1.1",

I can't figure out why it doesn't work. I have react plugin so it should understand react, "babel-loader": "^8.0.6",

like image 415
07mm8 Avatar asked Feb 27 '20 11:02

07mm8


2 Answers

Fixed by adding a babel preset: ['@babel/preset-typescript', {allowNamespaces: true}],

I have no clue why react breaks...

like image 170
07mm8 Avatar answered Nov 03 '22 14:11

07mm8


I faced the same issue. To fix this issue I have

  • to install @babel/preset-typescript by running

     yarn add @babel/preset-typescript
    
  • to add

     ['@babel/preset-typescript', {allowNamespaces: true}]
    

in webpack.config.js like this

rules: [
        {
            test: /\.[tj]sx?$/,
            include: /(src)/,
            use: [{
                loader: 'babel-loader',
                options: {
                    presets: [
                        [
                            '@babel/preset-env',
                            {
                                "useBuiltIns": "usage",
                                "corejs": 3
                            }
                        ],
                        ['@babel/preset-typescript', { allowNamespaces: true }]
                    ],
                    plugins: [
                        '@babel/plugin-syntax-dynamic-import'
                    ]
                }
            }]
        },
        {
            test: /\.tsx?$/,
            include: path.resolve(__dirname, "src"),
            use: [{
                loader: 'ts-loader',
                options: {
                    transpileOnly: true
                }
            }]
        },
        {
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
        },
        {
            test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
            use: [{
                loader: 'url-loader',
                options: {
                    limit: 10000,
                }
            }]
        }
    ]
like image 38
onlyme Avatar answered Nov 03 '22 15:11

onlyme