reactjswebpack-4

Which is the appropriate loader to handle React JSX?


I am trying to make webpack4 to produce the output folder with the main.js, but keeps returning "may need an appropriate loader to handle this file type" error and point to the jsx lines. How can I make webpack transform the jsx, or what kind of loader do I need?

I thought that the problem might be that the @babel/preset-env and @babel/preset-react are outdated or I need to use a more recent version but it looks like this isn't the case.

webpack.config.js

module.exports = {
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: { loader: 'babel-loader' }
            }
        ]
    }
};

.babelrc

{
    "presets": [ "@babel/preset-env", "@babel/preset-react" ]
}

package.json

{
  "name": "github_battle",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack --mode development",
    "build": "webpack --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.2.3",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.5",
    "react": "^16.7.0",
    "react-dom": "^16.7.0",
    "webpack": "^4.28.3",
    "webpack-cli": "^3.2.0"
  }
} 

App.js

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
    render (
        <p>React in here</p>
    );
};

export default App;

ReactDOM.render(
    <App />,
    document.getElementById('root')
);

index.js

import App from './App';

I expect the react code to be properly transformed and bundled into dist/main.js.

The actual result:

> github_battle@1.0.0 dev D:\WORK\github_battle
> webpack --mode development

Hash: a88a6be7f290c6ab30a1
Version: webpack 4.28.3
Time: 186ms
Built at: 01/04/2019 9:06:55 AM
    Asset      Size  Chunks             Chunk Names
main.js  4.58 KiB    main  [emitted]  main
Entrypoint main = main.js
[./src/App.js] 238 bytes {main} [built] [failed] [1 error]
[./src/index.js] 28 bytes {main} [built]

ERROR in ./src/App.js 7:8
Module parse failed: Unexpected token (7:8)
You may need an appropriate loader to handle this file type.
| class App extends React.Component {
|     render (
>         <p>React in here</p>
|     );
| };
 @ ./src/index.js 2:0-24
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! github_battle@1.0.0 dev: `webpack --mode development`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the github_battle@1.0.0 dev script.
npm ERR! This is probably not a problem with npm. There is likely 
additional logging output above.

Solution

  • The main error is that you have named your webpack config file wrongly.

    You named it webpack.conf.js but webpack command expects a file named as webpack.config.js.

    So rename that first.

    Now in side the webpack you did not mentioned the entry and output which is causing the error after you are done with the renaming.

    So rewrite your webpack config file as.

    module.exports = {
        entry: "./src/App.js",
        output: {
            filename: "bundle.js"
        },
        module: {
            rules: [
                {
                    test: /\.(js|jsx)$/,
                    exclude: /node_modules/,
                    use: { loader: 'babel-loader' }
                }
            ]
        }
    };
    

    Now for the App.js you have wrongly written the ReactJS code. it should be

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    class App extends React.Component {
        render() {
            return (
                <p> React in here</p >
            );
        }
    };
    
    export default App;
    
    ReactDOM.render(
        <App />,
        document.getElementById('root')
    );
    

    So change that then.

    It should work after following these steps.