Arjun S Kumar
Arjun S Kumar

Reputation: 376

JSX Unexpected token - Webpack and babel-loader

I'm getting JSX parse error after upgrading webpack from ^1.14.0 to "^3.0.0"

ERROR in ./shared/Application.js
Module parse failed: /Users/arjunkumar/Documents/Work/test/web/shared/Application.js Unexpected token (25:2)
You may need an appropriate loader to handle this file type.

The related code in Application.js looks like this

ReactDOM.render(
  <Provider store={store}>
    <Router routes={Routes(store)} history={history} />
  </Provider>,
  document.getElementById('app-shell') 
);

Relevant part of webpack.config.js file looks as follows (all the required plugins are imported properly to webpack config file, not present in the following code).

module.exports = {
  entry: {
    app:['./shared/Application.js'],
    vendors:[// vendors like react and other libs ]
  },
  output: {
    path: __dirname + '/public/build',
    filename: 'app.[chunkhash].js'
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            'css-loader',
            'autoprefixer-loader',
            'sass-loader'
          ],
          exclude: /node_modules/
        }),
      },
      {
        test: /\.js$/,
        exclude: [/node_modules/],
        use:[{
          loader: 'babel-loader',
          options: {
            presets: [
              ['es2015', {modules: false}],
              'react'
            ],
            babelrc: false
          }
        }]
      },
      {
        test: /\.jsx$/,
        exclude: [/node_modules/],
        use:[{
          loader: 'babel-loader',
          options: {
            presets: [
              'es2015',
              'react'
            ],
            babelrc: false
          }
        }]
      },
    ]
  },
  devtool: ( process.env.NODE_ENV === 'production' ) ? false : 'eval',
  plugins: [
    new ExtractTextPlugin(
      'app.[chunkhash].css',
      {
        allChunks: true
      }
    ),
    new webpack.optimize.CommonsChunkPlugin({
      names: ['utilities','vendors'],
      filename: '[name].[chunkhash].js',
      minChunks: Infinity
    }),
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        warnings: false
      },
      output: {
        comments:false
      },
      comments: false
    }),
    new AssetsPlugin({
      filename: 'assets.json',
      fullPath: false,
      path: __dirname + '/public/build',
      prettyPrint: true
    })
  ]

};

Relevant dependencies for the issue from package.json file is as follows.

{
  "devDependencies": {
    "babel": "^6.23.0",
    "babel-core": "^6.25.0",
    "babel-loader": "^7.1.1",
    "babel-plugin-transform-object-assign": "^6.8.0",
    "babel-plugin-transform-react-constant-elements": "^6.9.1",
    "babel-plugin-transform-react-inline-elements": "^6.8.0",
    "babel-plugin-transform-react-remove-prop-types": "^0.2.9",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-es2015-loose": "^8.0.0",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "babel-register": "^6.24.1",
    "extract-text-webpack-plugin": "^2.1.2",
    "html-webpack-plugin": "^2.21.0",
    "husky": "^0.13.1",
    "lodash-webpack-plugin": "^0.10.6",
    "node-sass": "^3.13.1",
    "postcss-loader": "^2.0.6",
    "purifycss-webpack": "^0.4.2",
    "sass-loader": "^4.1.1",
    "webpack": "^3.0.0",
    "webpack-bundle-analyzer": "^2.3.0",
    "webpack-dev-server": "^2.5.0"
  },
  "dependencies": {
    "react": "^15.1.0"
  }
}

Just in case anyone wants to check .babelrc file ( I think babel-loader respects babelrc: false flag in webpack.config.js).

{
  "presets": [
    "es2015",
    "react",
    "stage-0"
  ],
  "env": {
    "production": {
      "plugins": [
        "transform-react-constant-elements",
        "transform-react-inline-elements",
        "transform-react-remove-prop-types"
      ]
    }
  },
  "comments": false,
  "compact": false
}

Any thoughts or leads on what might be wrong?

Another important thing I noticed is even though my webpack project and global dependency is at 3.0.0, when I run the webpack in the project it shows Version: webpack 1.15.0 at the top. Screenshot below.

webpack wrong version

Upvotes: 1

Views: 647

Answers (2)

Michael Jungo
Michael Jungo

Reputation: 32972

You're running webpack from the command line, which means that you're running the globally installed unless you have ./node_modules/.bin/ in your PATH. Even though you say your globally installed version should be 3.0.0, it is a much better idea to always run the locally installed one. If you want to run it from the command line you can do it by running:

./node_modules/.bin/webpack --progress

A more elegant way to run it, is by creating an npm script in your package.json.

"scripts": {
  "build": "webpack --progress"
}

npm will automatically look into ./node_modules/.bin/ for an executable. And then you can run that script with:

npm run build

Your config looks okay, except for resolve.extensions, which no longer allows/requires an empty string.

resolve: {
  extensions: ['.js', '.jsx']
},

I don't really see why you're using two different rules for .js and .jsx. You can have a regular expression that matches both with /\.jsx?$/. But the two rules are not identical. The difference is that you use modules: false only for .js, but you should let webpack handle the ES modules. If you don't have a reason to do it differently, you should combine the two rules.

Upvotes: 1

loganfsmyth
loganfsmyth

Reputation: 161457

If it says Webpack 1.x in the output when you compile, then that is why it isn't working. Your config is for Webpack 3, so Webpack 1 doesn't know what to do with it.

This is likely because you've installed [email protected] as a global module, e.g. npm i webpack -g which means the version of it is unrelated to the version in your package.json. Installing dependencies globally is generally not a good idea because of this type of issues unless you are installing a truly global application from npm.

The first step would be to npm uninstall -g webpack so you don't accidentally run the global version anymore, then you need to explicitly run your local version when building, e.g.

instead of just running

webpack

you should run

$(npm bin)/webpack

so that you run the version of Webpack installed into node_modules.

Upvotes: 0

Related Questions