Uncaught Error: Target container is not a DOM element. in React - reactjs

I encountered this error when trying to set up my React app. I have looked at other people's solution, but didn't seem to find the solution that works for me.
I normally just do create-react-app, but this time I try to configure webpack and I'm not sure what went wrong here.
my index.js and App.js files are both in the src folder and my index.html is inside the dist folder
THANK YOU FOR YOUR HELP
my index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>High Five</title>
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>
my webpack.config.js
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const config = {
entry: ["react-hot-loader/patch", "./src/index.js"],
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js",
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: "babel-loader",
exclude: /node_modules/,
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
{
test: /\.png$/,
use: [
{
loader: "url-loader",
options: {
mimetype: "image/png",
},
},
],
},
{
test: /\.svg$/,
use: "file-loader",
},
],
},
resolve: {
extensions: [".js", ".jsx"],
alias: {
"react-dom": "#hot-loader/react-dom",
},
},
devServer: {
contentBase: "./dist",
},
plugins: [
new HtmlWebpackPlugin({
appMountId: "app",
filename: "index.html",
}),
new MiniCssExtractPlugin(),
],
};
module.exports = config;
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import "./styles.css";
ReactDOM.render(<App />, document.getElementById("app"));
App.js
import React, { Component } from "react";
import { hot } from "react-hot-loader/root";
class App extends Component {
render() {
return (
<div>
<h1>Hello React</h1>
</div>
);
}
}
export default hot(App);

Related

React express SSR can't read CSS on the server

I've been trying to learn React SSR with babel/webpack. I've gotten to the point of rendering the HTML on the page but once I start adding CSS I start getting errors saying
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> body {
| color: red
| }
index.js
import React from 'react';
import { hydrateRoot } from 'react-dom/client';
import App from './App';
const container = document.getElementById('root');
hydrateRoot(container, <App/>);
App.js
import { useState } from 'react';
import React from 'react';
import './App.css'
function App() {
const [counter, setCounter] = useState(0);
const incrementHandler = () => {
setCounter(prev => {
return ++prev
})
}
const decrementHandler = () => {
setCounter(prev => {
return --prev
})
}
return (
<div>
<button onClick={incrementHandler}>Increment</button>
<br/>
<button onClick={decrementHandler}>Decrement</button>
<br/>
{counter}
</div>
);
}
export default App;
server.js
import express from "express";
import React from "react";
import ReactDOMServer from "react-dom/server";
import App from "./src/App.js";
import path from "path";
const app = express();
app.use(express.static(path.resolve(__dirname, "build")));
app.get("*", (req, res) => {
let html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React-SSR</title>
</head>
<body>
<div id="root">${ReactDOMServer.renderToString(<App />)}</div>
<script src="bundle.js"></script>
</body>
</html>`;
res.send(html);
});
app.listen(3000, () => {
console.log("server listening on port 3000");
});
webpack-config-server.js
const path = require("path");
const nodeExternals = require('webpack-node-externals');
module.exports = {
mode: 'development',
target: 'node',
entry: './server',
externals: [nodeExternals()],
output: {
path: path.resolve(__dirname),
filename: "server-start.js",
},
devServer: {
port: 3010,
static: true,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['#babel/preset-env', "#babel/preset-react"]
}
},
},
],
}
};
webpack.config.js
const path = require("path");
module.exports = {
mode: 'development',
target: 'web',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: "bundle.js",
publicPath: '/'
},
devServer: {
port: 3010,
static: true,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['#babel/preset-env', "#babel/preset-react"]
}
},
},
{
test: /\.css$/,
use: [
'style-loader', 'css-loader'
]
}
],
}
};
These are the scripts in my package.json
"scripts": {
"build-react": "webpack",
"build-server": "webpack --config webpack.config-server.js",
"start": "node server-start",
"dev": "npm-run-all build-react build-server start --parallel"
},
Also how can I make it so when I change something in the App.js the app rebuilds and I see the change(I tried with webpack server but the "dev" script stops on build-react)

Webpack config for SSR SCSS

I have a React-TypeScript SSR app where I used SCSS files for my styling. I need to write a rule in Webpack to load the SCSS and I haven't been able to do it.
I found various solutions online, all of which are extremely complex and use things like mini-css-extract-plugin. I couldn't get any of them to work.
I currently have two webpack config files, one for the client (web) and one for the server (node), both of which load the SCSS as such:
{
test: /\.scss$/,
use: ["css-loader", "sass-loader"]
}
I also encountered another issue in that I can't use style-loader as it throws an error about the window object. Does anyone have a working example (simple preferably) of loading SCSS in Webpack?
You are on right track with 2 web config file you can use
https://gist.github.com/mburakerman/629783c16acf5e5f03de60528d3139af
But don't set any other config file like babel.rc .yaml etc or other definition in project.json
try this
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader'
]
//..
plugins: [
new MiniCssExtractPlugin({
filename: 'assets/css/bundle-[contenthash].css',
chunkFilename: 'assets/css/bundle-[contenthash].css'
})
],
Look full example https://github.com/dewelloper/pzone/blob/master/webpack.config.store.js
A boilerplate for server-side rendering using react, webpack, Sass
(for both css-modules and pure sass)
webpack.config.js
const path = require('path');
const isDevelopment = true;
module.exports = [
{
name: 'client',
target: 'web',
entry: './client.jsx',
output: {
path: path.join(__dirname, 'static'),
filename: 'client.js',
publicPath: '/static/',
},
resolve: {
extensions: ['.js', '.jsx']
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules\/)/,
use: [
{
loader: 'babel-loader',
}
]
},
{
test: /\.scss$/,
use: [
{
loader: 'style-loader',
},
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
sourceMap: isDevelopment,
}
},
{
loader: 'sass-loader'
}
]
}
],
},
},
{
name: 'server',
target: 'node',
entry: './server.jsx',
output: {
path: path.join(__dirname, 'static'),
filename: 'server.js',
libraryTarget: 'commonjs2',
publicPath: '/static/',
},
devtool: 'source-map',
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules\/)/,
use: [
{
loader: 'babel-loader',
}
]
},
{
test: /\.scss$/,
use: [
{
loader: 'isomorphic-style-loader',
},
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
sourceMap: isDevelopment,
}
},
{
loader: 'sass-loader'
}
]
}
],
},
}
];
dev dependencies:
npm i -D #babel/cli #babel/preset-es2015 #babel/core #babel/plugin-proposal-class-properties #babel/preset-env #babel/preset-react babel-core babel-loader babel-plugin-lodash babel-plugin-react-transform babel-preset-env babel-preset-es2015 babel-preset-react babel-preset-stage-0 css-loader express isomorphic-style-loader node-sass sass-loader style-loader webpack webpack-dev-middleware webpack-hot-middleware webpack-hot-server-middleware
and dependencies:
npm i react react-dom react-helmet react-router-dom
sever.jsx:
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { StaticRouter } from 'react-router-dom';
import {Helmet} from "react-helmet";
import Template from './template';
import App from './App';
export default function serverRenderer({ clientStats, serverStats }) {
return (req, res, next) => {
const context = {};
const markup = ReactDOMServer.renderToString(
<StaticRouter location={ req.url } context={ context }>
<App />
</StaticRouter>
);
const helmet = Helmet.renderStatic();
res.status(200).send(Template({
markup: markup,
helmet: helmet,
}));
};
}
App.jsx:
import React, { Component } from 'react';
import { Switch, Route } from 'react-router-dom';
import Menu from './Menu'
import Helmet from "react-helmet";
import homepageStyles from './homepage.scss';
class Homepage extends Component {
render() {
return (
<div className={ homepageStyles.component }>
<Helmet
title="Welcome to our Homepage"
/>
<Menu />
<h1>Homepage</h1>
</div>
);
}
}
class About extends Component {
render() {
return (
<div>
<h1>About</h1>
</div>
);
}
}
class Contact extends Component {
render() {
return (
<div>
<h1>Contact</h1>
</div>
);
}
}
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Helmet
htmlAttributes={{lang: "en", amp: undefined}} // amp takes no value
titleTemplate="%s | React App"
titleAttributes={{itemprop: "name", lang: "en"}}
meta={[
{name: "description", content: "Server side rendering example"},
{name: "viewport", content: "width=device-width, initial-scale=1"},
]}
/>
<Switch>
<Route exact path='/' component={ Homepage } />
<Route path="/about" component={ About } />
<Route path="/contact" component={ Contact } />
</Switch>
</div>
);
}
}
template.jsx
export default ({ markup, helmet }) => {
return `<!doctype html>
<html ${helmet.htmlAttributes.toString()}>
<head>
${helmet.title.toString()}
${helmet.meta.toString()}
${helmet.link.toString()}
</head>
<body ${helmet.bodyAttributes.toString()}>
<div id="root">${markup}</div>
<div>Heeeeeeeeeeeeeeeeeeeelmet</div>
<script src="/static/client.js" async></script>
</body>
</html>`;
};
menu.jsx:
import { Link } from 'react-router-dom';
import React, { Component } from 'react';
import './menu.scss';
class Menu extends Component {
render() {
return (
<div>
<ul>
<li>
<Link to={'/'}>Homepage</Link>
</li>
<li>
<Link to={'/about'}>About</Link>
</li>
<li>
<Link to={'/contact'}>Contact</Link>
</li>
</ul>
</div>
);
}
}
export default Menu;
.babelrc:
{
"presets": [
"#babel/react",
"#babel/preset-env"
],
"plugins": [
"#babel/proposal-class-properties"
]
}
homepage.sccs
.component {
color: blue;
}
menu.scss:
li {
background-color: yellow;
}
I used this article:
https://blog.digitalkwarts.com/server-side-rendering-with-reactjs-react-router-v4-react-helmet-and-css-modules/
Webpack Community now details an approach for SSR sass compiled via webpack in mini-css-extract-plugin/#recommend
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== "production";
module.exports = {
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
devMode ? "style-loader" : MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader",
],
},
],
},
plugins: [].concat(devMode ? [] : [new MiniCssExtractPlugin()]),
};
Note that style-loader should not be used in an SSR app or in a webpack production build because injects CSS into the DOM. MiniCSSExtractPlugin is recommended for SSR production builds and should not be used with style-loader (window will not be defined in webpack's node-based prod build).

how to render javascript files at the end of body in reactjs+webpack?

I created a reactjs+ webpack SPA and tested it on 'Google pagespeed insights'. I have just one main.js file and it's getting rendered at the beginning.
here is the result
how do i resolve this ?
this is my webpack configuration :
const HtmlWebPackPlugin = require("html-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new UglifyJsPlugin({
cache: true,
parallel: true,
// uglifyOptions: {
// compress: false,
// ecma: 6,
// mangle: true
// },
})]
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader?cacheDirectory=true"
}
},
{
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test: /\.(ttf|eot|woff|woff2)$/,
use: {
loader: "file-loader",
},
},
{
test: /\.(png|jpg|svg)$/,
use: [{
loader: 'file-loader',
options: {
limit: 8000, // Convert images < 8kb to base64 strings
name: 'static/[name].[ext]'
}
}]
},
{
test: /\.html$/,
use: [
{
loader: "html-loader"
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
})
]
};
how could i tell webpack to load the js file at the end of the body ? or any other solution that helps to solve this issue?
and my index.html and index.js files are so simple.
index.html :
<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="utf-8">
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no"
/>
<link rel="shortcut icon" type="image/png" href="static/favicon.png"/>
<title>آسان یادبگیر</title>
</head>
<body dir="rtl">
<div id="mainDiv">
</div>
</body>
</html>
index.js :
import React from "react";
import ReactDOM from "react-dom";
import Theme from './styles/theme';
import { MuiThemeProvider} from '#material-ui/core/styles';
import CssBaseline from '#material-ui/core/CssBaseline';
import './styles/style.css';
import RTL from './jss-rtl';
import './static/favicon.png'
import App from './app';
ReactDOM.render(
<RTL>
<MuiThemeProvider theme={Theme}>
<React.Fragment>
<CssBaseline/>
<App/>
</React.Fragment>
</MuiThemeProvider>
</RTL>,
document.getElementById('mainDiv'));
here the google issue :
Eliminate render-blocking JavaScript and CSS in above-the-fold content: None of the above-the-fold content on your page could be rendered without waiting for the following resources to load. Try to defer or asynchronously load blocking resources, or inline the critical portions of those resources directly in the HTML.
Remove render-blocking JavaScript:
https://asanyadbegir.com/main.js
I added ' defer="true" ' to the dist/index.html file and it got better(50% better). then by using React-Loadable I splited my files. every thing is file now.

React element is not rendering / React Setup Issue

I am trying to learn to react, after spending two days on setting up webpack and babel. Finally, I am trying to run some sample code. I am trying to print some strings from my react element, and unable to get this element working.
I do get the "Hello World" which is from the HTML, and no compilation errors for react, so I can validate client-server setup is working well.
However, the react element is not rendered.
Following is three file setup.
components/homepage.js
"use strict";
var React = require('react');
var Home = React.createClass({
render: function () {
return (
<div className="jumbotron">
<h1>PluralSight Adminstrator</h1>
<p>React, React Router, and Flux for ultra responsive website</p>
</div>
);
}
});
module.exports = Home;
And index.js
const jquery = $ = require('jquery');
const Home = require('./components/homepage');
const ReactDOM = require('react-dom');
ReactDOM.render(<Home/>, document.getElementById('app'));
And index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="index.js"></script>
</head>
<body>
<div id="app"></div>
Hello World.:)
</body>
</html>
webpack.config.dev.js
const webpack = require('webpack');
const path = require('path');
module.exports = {
debug: true,
devtool: 'inline-source-map',
noInfo: false,
entry: [
'eventsource-polyfill', // necessary for hot reloading with IE
'webpack-hot-middleware/client?reload=true', //note that it reloads the page if hot module reloading fails.
path.resolve(__dirname, 'src/index')
],
target: 'web',
output: {
path: __dirname + '/dist', // Note: Physical files are only output by the production build task `npm run build`.
publicPath: '/',
filename: 'bundle.js'
},
devServer: {
contentBase: path.resolve(__dirname, 'src')
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [
{test: /\.js$/, include: path.join(__dirname, 'src'), loaders: ['babel']},
{test: /(\.css)$/, loaders: ['style', 'css']},
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file'},
{test: /\.(woff|woff2)$/, loader: 'url?prefix=font/&limit=5000'},
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream'},
{test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml'}
]
}
};
The following code should work (replace the home component code):
var Home = class Home extends React.Component {
render() {
return (
<div className="jumbotron">
<h1>PluralSight Adminstrator</h1>
<p>React, React Router, and Flux for ultra responsive website</p>
</div>
);
}
}
According to docs, if you want to use create-react-class then you need to install the package using NPM and require it as shown below:
var createReactClass = require('create-react-class');
The compiler might not show the error, but your browser's console must be showing some error.
Ref fiddle: https://jsfiddle.net/69z2wepo/194263/

Use Pure Bootstrap v4 on ReactJs is NOT working

I was desperately want to use pure Bootstrap v4 on my React.js app. I created my app using create-react-app. So, i put Bootstrap assets on index.html (in public folder).
At the first try, it was working well. Then, i added some dependencies like react-router-dom, react-router-config, and prop-types. Suddenly, it displayed almost a blank page.
1) Project Folder
2) kodebaru/webpack.config.js
const path = require('path');
module.exports = {
entry: path.join(__dirname, '/client/src/index.jsx'),
output: {
path: path.join(__dirname, '/client/dist/js'),
filename: 'app.js',
},
module: {
loaders: [
{
test: /\.jsx?$/,
include: path.join(__dirname, '/client/src'),
loader: 'babel-loader',
query: {
presets: ["react", "es2015"]
}
}
]
},
watch: true
};
3) kodebaru/server.js
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.resolve(__dirname, './backend/static/')));
app.use(express.static(path.resolve(__dirname, './client/dist/')));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, './backend/static/', 'index.html'));
});
const PORT = process.env.PORT || 3500;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}!`);
});
4) kodebaru/backend/static/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Kodebaru</title>
<link rel="stylesheet" href="./bootstrap/bootstrap.min.css">
</head>
<body>
<div id="root"></div>
<script src="/js/app.js"></script>
</body>
</html>
5) result
6) Warning Message
I knew there is a framework bootstrap for react app (reactstrap). But, this time i want to know how to use pure bootstrap v4 in react app ?
It is too late. But, i think it is good to answer my own question since there is no one. The solution was to install bootstrap using npm, import bootstrap on index.jsx, add jQuery, Popper.js, and css loader on webpack configuration file.
a) Install bootstrap using npm
npm install bootstrap#4.0.0-beta
b) Import bootstrap on index.jsx
import 'bootstrap';
require('bootstrap/dist/css/bootstrap.css');
c) Add jQuery and Popper.js on webpack
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default']
})
d) Add css loader on webpack
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
The full implementation is below :
1) index.jsx
import React from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from "redux";
import promise from "redux-promise";
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import { renderRoutes } from 'react-router-config';
import routes from './routes.js';
import reducers from './redux/reducers/index.js'
import 'bootstrap';
require('bootstrap/dist/css/bootstrap.css');
const createStoreWithMiddleware = createStore(reducers, {}, compose(applyMiddleware(promise)));
ReactDOM.render(
<Provider store = {createStoreWithMiddleware}>
<Router>
{/* kick it all off with the root route */}
{renderRoutes(routes)}
</Router>
</Provider>,
document.getElementById('root')
);
if(module.hot) {
module.hot.accept('./routes.js', function() {
routes();
})
}
2) webpack.config.js
const webpack = require('webpack');
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './app/index.js',
output: {
filename: 'index_bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.jsx?$/,
include: path.join(__dirname, '/app'),
exclude: '/node_modules',
loader: 'babel-loader',
query: {
presets: ["react", "es2015"],
plugins: [
"transform-react-pug",
"transform-react-jsx",
"transform-object-rest-spread"
]
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default']
}),
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
template: './index.html'
})
],
devtool: 'cheap-module-eval-source-map',
watch: true
};

Resources