I'm setting up a new development environment (moved from Windows 7 to Lubuntu), and now I'm trying to set up a React app on it for the first time. Well, second. create-react-app
worked, but I like to do things by hand. I finally have webpack
and webpack-dev-server
working, but when I go to localhost:8080
, the React components don't render, and I get three errors relating to an invalid element type.
I read here that it's usually an import/export problem, but I haven't been able to find it, after following the suggestions given. Here's what I have:
index.js
const React = require('react');
// syntax made no difference
import * as ReactDOMClient from 'react-dom/client'
const App = require('./components/App.js');
const root = ReactDOMClient.createRoot(document.getElementById('app'));
root.render(<App />);
index.html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="app">This does appear</div>
</body>
</html>
App.js
const React = require('react');
export default class App extends React.Component {
constructor(props) {
super(props);
console.log("App constructed?");
}
render() {
return (<h1>This should appear</h1>);
}
}
The three errors:
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
The only thing on the stack trace that made any sense to me (I can post the rest if you want) comes from the first warning and points to line 7 of index.js, which is root.render(<App />);
. I'm not sure how to post my file structure neatly, but I can assure you ./components/App.js (with or without extension) is the correct relative path here.
Any suggestions?
I'm using npm, so I think I have the best versions of each module. Here is my package.json:
{
"name": "try-word",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack --mode development",
"build": "webpack",
"start": "webpack-dev-server",
"devstart": "webpack-dev-server --mode development"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@babel/core": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"babel-loader": "^9.1.0",
"html-webpack-plugin": "^5.5.0",
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1"
}
}
Anything logged in index.js prints out fine, amidst the errors, but the log in the App constructor never does. It seems like App isn't getting imported correctly, but I'm not sure how to fix that.
EDIT
webpack.config.js
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: __dirname '/app/index.js',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' }
]
}
]
},
output: {
filename: 'transformed.js',
path: __dirname '/dist'
},
plugins: [new HTMLWebpackPlugin({
template: __dirname '/app/index.html',
filename: 'index.html',
inject: 'body'
})],
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000
}
};
CodePudding user response:
Can you show me your webpack config file? webpack only understands js and json files out of the box.
CodePudding user response:
I finally found the problem. Apparently the syntax does make a difference. I changed all of my import statements to use import/export
instead of require()
, restarted my machine (and consequentially, my webpack server), and tried again. Now, the component is showing properly.
This article has a great summary of information and other potential causes of this issue. In my case, specifically:
You should only use the import/export syntax in your React.js app and not the module.exports or require() syntax.