I am setting up webpack and react in a SpringMVC webapp and I'm getting this error when hitting my /index page.
The relevant controller method is here
@RequestMapping("/index")
public ModelAndView index(final HttpServletRequest request) {
return new ModelAndView("index");
}
The template at src/main/resource/templates/index.html looks like this
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Webpack App</title>
</head>
<body>
<span>React Content Below:</span>
<div id="content"/>
</body>
<script type="text/javascript" src="http://localhost:3000/dist/app.js">
</script>
</html>
Now onto the meat. My webpack.config.js looks like this
// Generated using webpack-cli
const path = require('path');
const webpack = require("webpack");
module.exports = {
mode: 'development',
entry: './src-js/app.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.js',
},
devServer: {
open: true,
host: 'localhost',
port:3000
},
externals: {
'react': 'React'
},
module: {
rules: [
{
test: /\.js|jsx$/,
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
]
}
},
{
test: /\.css$/i,
use: ['style-loader','css-loader'],
},
{
test: /\.s[ac]ss$/i,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/,
type: 'asset',
},
// Add your rules for custom modules here
// Learn more about loaders from /
],
},
};
and my ./src-js/app.js looks like this.
import * as ReactDOM from "react-dom";
ReactDOM.render(<h1>Hello, world</h1>, document.getElementById('content'));
I later ammended app.js to look like this
import * as React from 'react';
import * as ReactDOM from 'react-dom'
class Component extends React.PureComponent {
constructor(props) {
super(props);
}
render() {
return <h1>Hello, world</h1>
}
}
ReactDOM.render(<Component/>, document.getElementById('content'));
This works for now but long term I would prefer to not need to import React from this file and wrap everything in a Component.
Adding import React from 'react'
to the top of app.js has no effect and neither does var React = require('react')
. I'm assuming I'm just missing something in my webpack config but I can't seem to find what, anyone know why this is happening?
I am setting up webpack and react in a SpringMVC webapp and I'm getting this error when hitting my /index page.
The relevant controller method is here
@RequestMapping("/index")
public ModelAndView index(final HttpServletRequest request) {
return new ModelAndView("index");
}
The template at src/main/resource/templates/index.html looks like this
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Webpack App</title>
</head>
<body>
<span>React Content Below:</span>
<div id="content"/>
</body>
<script type="text/javascript" src="http://localhost:3000/dist/app.js">
</script>
</html>
Now onto the meat. My webpack.config.js looks like this
// Generated using webpack-cli http://github./webpack-cli
const path = require('path');
const webpack = require("webpack");
module.exports = {
mode: 'development',
entry: './src-js/app.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.js',
},
devServer: {
open: true,
host: 'localhost',
port:3000
},
externals: {
'react': 'React'
},
module: {
rules: [
{
test: /\.js|jsx$/,
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
]
}
},
{
test: /\.css$/i,
use: ['style-loader','css-loader'],
},
{
test: /\.s[ac]ss$/i,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/,
type: 'asset',
},
// Add your rules for custom modules here
// Learn more about loaders from https://webpack.js/loaders/
],
},
};
and my ./src-js/app.js looks like this.
import * as ReactDOM from "react-dom";
ReactDOM.render(<h1>Hello, world</h1>, document.getElementById('content'));
I later ammended app.js to look like this
import * as React from 'react';
import * as ReactDOM from 'react-dom'
class Component extends React.PureComponent {
constructor(props) {
super(props);
}
render() {
return <h1>Hello, world</h1>
}
}
ReactDOM.render(<Component/>, document.getElementById('content'));
This works for now but long term I would prefer to not need to import React from this file and wrap everything in a Component.
Adding import React from 'react'
to the top of app.js has no effect and neither does var React = require('react')
. I'm assuming I'm just missing something in my webpack config but I can't seem to find what, anyone know why this is happening?
3 Answers
Reset to default 2you can add this to webpack.config.js:
plugins: [
new webpack.ProvidePlugin({
React: 'react',
}),
]
In the webpack documentation (https://webpack.js/configuration/externals/) it looks like there are no quotes before the colon:
externals: {
react: 'React'
},
A few lines below (https://webpack.js/configuration/externals/#object) you can find react in lowerCase:
externals: {
react: 'react'
},
You can add a resolve
prop here if that works for you. Like below,
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: { 'react': path.resolve(__dirname), './node_modules', 'react' }
}
Thus, providing the react
module's path manually.