React element is not rendering / React Setup Issue - reactjs

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/

Related

How can I pull in an AngularJS app into a React host app Using Single-Spa

I'm hoping someone will be able to help.
I'm trying to use single-spa-angularjs to pull in a legacy AngularJS application into a React app. So the React app is the host. In the same React app, I'm also using Module Federation to pull in a separate React microfrontend.
So to sum it up, I have three apps:
React app - host and container
AngularJS app - legacy app using
AngularJS version 1.4.8
React microfrontend
All three apps are completely separate and hosted separately.
I was able to pull in the React microfrontend using Module Federation with no issues. The problem that I'm facing is pulling the AngularJS app into the host React app (app 1).
I'm getting a lot of errors in the console but I think this is the most relevant one:
xxx.js:701 Uncaught Error: application 'AngularJS' died in status LOADING_SOURCE_CODE: Module parse failed: Unexpected token (1:1)
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
> <!DOCTYPE html>
| <html lang="en" ng-app="MyAngularJSApp" ng-controller="MyAngularJSCtrl">
| <head>
at eval (index.html:1:7)
at ./index.html (node_modules_angularjs-bootstrap-datetimepicker_node_modules_moment_locale_sync_recursive_-no-1f57b2.app.bundle.js:27:1)
at __webpack_require__ (remoteEntry.js:44:42)
at eval (app.entry.js:21:69)
at ./app/app.entry.js (node_modules_angularjs-bootstrap-datetimepicker_node_modules_moment_locale_sync_recursive_-no-1f57b2.app.bundle.js:113:1)
at __webpack_require__ (remoteEntry.js:44:42)
at eval (container_entry:3:298)
at u.m.<computed> (bundle.js:2:262091)
at u (bundle.js:2:259451)
This is my current set up:
AngularJS App:
We're using webpack so we have a webpack.config.js file and the most important part is:
module.exports = function (env = {}) {
const isProd = !!env.prod;
const buildpath = env.buildpath ? env.buildpath : isProd ? 'dist' : 'build';
return {
entry: path.resolve(__dirname, 'app/app.entry.js'),
output: {
path: path.resolve(__dirname, buildpath),
filename: 'js/app.bundle.js',
clean: true,
},
plugins: [
new webpack.container.ModuleFederationPlugin({
name: 'MyAngularJSApp',
filename: 'remoteEntry.js',
remotes: {},
exposes: {
'./App': path.resolve(__dirname, 'app/app.entry.js'),
},
}),
new HtmlWebpackPlugin({
inject: 'body',
template: path.resolve(__dirname, 'index.html'),
filename: path.resolve(buildpath, 'index.html'),
})
],
module: {
......
},
resolve: {
......
},
optimization: {
......
},
};
};
In app/app.entry.js I've added the following:
import singleSpaAngularJS from 'single-spa-angularjs';
import angular from 'angular';
import app from '../index.html'
const domElementGetter = () => document.getElementById('AngularJSApp');
const ngLifecycles = singleSpaAngularJS({
angular: angular,
domElementGetter,
mainAngularModule: 'AngularJSApp',
template: app,
});
export const bootstrap = ngLifecycles.bootstrap;
export const mount = ngLifecycles.mount;
export const unmount = ngLifecycles.unmount;
In the host/consuming React application:
webpack.config.js:
const path = require('path');
const webpack = require('webpack')
const { ModuleFederationPlugin } = webpack.container;
const HtmlWebpackPlugin = require("html-webpack-plugin");
const dependencies = require('./package.json').dependencies;
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
entry: './src/index.tsx',
mode: 'production',
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000
},
module: {
rules: [
{
test: /\.(jsx|js)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
exclude: /\.lazy\.html$/,
use: [
{
loader: 'html-loader',
options: {
minimize: true,
},
},
],
},
// Use Babel to transpile TypeScript and TypeScript / React files to ES5
{
test: /\.(tsx|ts)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new ModuleFederationPlugin({
name: 'container',
remotes: {
reactMFE: 'reactMFE#http://localhost:3000/remoteEntry.js',
AngularJSApp: 'AngularJSApp#http://localhost:3004/remoteEntry.js',
},
shared: {
react: {
singleton: true,
eager: true,
requiredVersion: dependencies.react,
},
'react-dom': {
singleton: true,
eager: true,
requiredVersion: dependencies['react-dom'],
}
},
}),
new webpack.DefinePlugin({ // <-- key to reducing React's size
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
// new BundleAnalyzerPlugin(),
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
};
I've registered the Angular app in the entry point /src/index.tsx. The same file also imports 'bootstrap' to resolve the eager consumption error when using module federation:
/src/index.tsx:
import("./bootstrap")
import {registerApplication} from 'single-spa'
registerApplication(
'AngularJSApp',
//#ts-ignore
() => import('AngularJSApp/App'),
location => location.pathname.startsWith('/')
)
/src/bootstrap.tsx:
import React from 'react';
import ReactDOM from 'react-dom/client';
import { App } from './App'
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
I've made changes to load in the scripts for the imported apps in public/index.html:
<html>
<head>
<script src="http://localhost:3000/remoteEntry.js"></script>
<script src="http://localhost:3004/remoteEntry.js"></script>
</head>
<body>
<div>Container App</div>
<div id="root"></div>
{/* I've put these two lines as a last ditch attempt - not sure which one of them should be working*/}
<div id="AngularJSApp"></div>
<div id="single-spa-application:AngularJSApp"></div>
</body>
</html>
Can someone advise on how I can get this working, it would be much appreciated.
Thank you

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

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);

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.

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
};

How to use static js generated throught webpack for react app with es6

I am new to es6/react js and webpack and from last 6 days I am trying to create startkit for react app with es6 and webpack below is my webpack.config.js , I am successfully able to configure web pack dev server. My app is running on http:/localhost:8080/webpack-dev-server. When I am running npm build to generate bundle.js. if I am running my app only using localhost:8080 my app is running in chrome but giving error in mozilla (r.render is not function). Webpack is very confusing... Can we run file bundle.js file locally on file:// server. means like in normal html file if I include that bundle.js file it should work right?
My webpack.config.js
var path = require('path');
var webpack = require('webpack');
//var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
var mainPath = path.join(__dirname, 'app', 'index.js');
var buildPath = path.join(__dirname, 'dist/assets/');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var autoprefixer = require('autoprefixer')
var sassLoaders = [
'css-loader?sourceMap',
'postcss-loader',
'sass-loader?sourceMap&includePaths[]=' + path.join(__dirname, './app')
]
module.exports = {
// Makes sure errors in console map to the correct file
// and line number
devtool: 'cheap-module-source-map',
entry: {
'vendor': ['react','react-dom'],
"bundle":mainPath
},
module: {
loaders: [
{
test: [/\.js$/],
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
},
// //{ test: /\.less$/, loader: 'style-loader!css-loader!less-loader' }, // use ! to chain loaders
// { test: /\.less$/, loader: 'style-loader!css-loader!less-loader' }, // use ! to chain loaders
// { test: /\.s?css$/, loaders: ['style', 'css', 'sass','css?sourceMap', 'sass?sourceMap'] }
{ test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader', sassLoaders.join('!'))
},
{ test: /\.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, loader: 'file-loader?name=/fonts/[name].[ext]' }
]
},
output: {
// We need to give Webpack a path. It does not actually need it,
// because files are kept in memory in webpack-dev-server, but an
// error will occur if nothing is specified. We use the buildPath
// as that points to where the files will eventually be bundled
// in production
path: buildPath,
filename: '[name].js',
publicPath: 'http://localhost:8080/assets'
},
plugins: [
// Pro-tip: Order matters here.
new ExtractTextPlugin('[name].css'), new webpack.optimize.CommonsChunkPlugin(['bundle', 'vendor'], '[name].js')
],
postcss: [
autoprefixer({
browsers: ['last 2 versions'],
//path: "./dist",
filename: '[name].js',
// Everything related to Webpack should go through a build path,
// localhost:8080/build. That makes proxying easier to handle
publicPath: '/dist/'
})
],
resolve: {
extensions: ['', '.js', '.jsx','.sass','.woff','.ttf','.eot','.svg'],
root: [path.join(__dirname, './app')]
},
watch:true
};
my index.html
<!DOCTYPE html>
<html>
<head>
<title>React Home Page</title>
<link rel="stylesheet" href="assets/bundle.css" />
</head>
<body>
<div id="react-app"></div>
<script type="text/javascript" src="assets/vendor.js"></script>
<script type="text/javascript" src="assets/bundle.js"></script>
</body>
</html>
You don't have to link it yourself, webpack does that for you.
the HtmlWebpackPlugin will make sure that the bundle is being linked in the file that you configure.
var path = require("path");
var HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./app/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "index_bundle.js"
},
module: {
rules: [
{ test: /\.(js)$/, use: "babel-loader" },
{ test: /\.css$/, use: ["style-loader", "css-loader"] }
]
},
plugins: [
new HtmlWebpackPlugin({
template: "app/index.html"
})
]
};

Resources