ReactDOM does not render component into html - reactjs

Just started redux, get stuck on a weird situation, webpack shows no error, but in the html, the component did not get rendered. The file structure:
dist
bundle.js
node_modules
src
index.js
.babelrc
index.html
package.json
server.js
webpack.config.js
index.html
<html>
<head>
<title>jie blog</title>
<meta charset="utf-8">
</head>
<body>
<div id="root"></div>
</body>
<script src="dist/bundle.js">
</script>
</html>
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { Router, Route, Redirect, browserHistory } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
class App extends React.Component{
render(){
return(
<div>
hello world
</div>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
)
server.js
var http = require('http')
var express = require('express')
var httpProxy = require('http-proxy')
var fs = require('fs')
var babelrc = fs.readFileSync('./.babelrc')
var config = JSON.parse(babelrc)
require('babel-core/register')(config)
var proxy = httpProxy.createProxyServer({})
var app = express()
app.use(require('morgan')('short'))
// webpack
var webpack = require('webpack')
var config = require('./webpack.config')
var compiler = webpack(config)
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: config.output.publicPath
}))
app.use(require('webpack-hot-middleware')(compiler))
app.all(/^\/api\/(.*)/, function api(req, res){
proxy.web(req, res, {
target: 'http://localhost:5000'
})
})
app.get(/.*/, function root(req, res){
res.sendFile(__dirname + '/index.html')
})
const server = http.createServer(app)
server.listen(process.env.PORT || 3000, function(){
const address = server.address()
console.log('listening on %j', address)
})
webpack.config.js
const webpack = require('webpack')
const path = require('path')
module.exports = {
devtool: 'source-map',
entry: [
'webpack-hot-middleware/client',
path.resolve(__dirname, 'src/index.js')
],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
resolve: {
extensions: ['', '.jsx', '.js', '.json', '.scss']
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
}
}
output html
<body>
<div id="root"></div>
<script src="dist/bundle.js">
</script>
</body>

It looks it's not an issue with ReactDOM but instead a configuration problem.
In server.js
...
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: config.output.publicPath // <--- /static/
}))
...
publicPath specifies the public URL address of your bundle.js when referenced in a browser. So /static/bundle.js as you set in your webpack.config.js. Ok fine !
So Index.html need to request for /static/bundle.js. and NOT dist/bundle.js
...
<script src="static/bundle.js"></script>
...
Check output.publicPath configurations for webpack for more informations
As index.html requested for your bundle at /dist and webpack-dev-middleware handle requests at /static, an index.html file was returned instead of a your bundle.js
app.get(/.*/, function root(req, res){
res.sendFile(__dirname + '/index.html')
})
It's why you got Uncaught SyntaxError: Unexpected token < bundler.js:1.

The problem is that Babel is transpiling only .jsx files:
test: /\.jsx?$/,
while your file with JSX has a .js extension (index.js)

Related

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

webpack-dev-server: Cannot get /

Unable to get a simple hello world working!
server.js
var webpack = require('webpack')
var WebpackDevServer = require('webpack-dev-server')
var config = require('./webpack.config')
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
inline: true,
historyApiFallback: true
}).listen(3000, '0.0.0.0', function (err, result) {
if (err) {
console.log(err)
}
console.log('Listening at 0.0.0.0:3000')
})
webpack.config.js
var path = require("path")
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
module.exports = {
context: __dirname,
entry: [
'./assets/js/index', // entry point of our app. assets/js/index.js should require other js modules and dependencies it needs
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
],
output: {
path: path.resolve('./assets/bundles/'),
filename: "[name]-[hash].js",
publicPath: 'http://localhost:3000/assets/bundles/', // Tell django to use this URL to load packages and not use STATIC_URL + bundle_name
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(), // don't reload if there is an error
new BundleTracker({filename: './webpack-stats.json'}),
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot-loader/webpack', 'babel-loader?presets[]=react'],
}, // to transform JSX into JS
],
},
resolve: {
modules: ['node_modules', 'bower_components'],
extensions: ['.js', '.jsx']
},
}
index.html
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Example</title>
</head>
<body>
<div id="react-app"></div>
{% render_bundle 'main' %}
</body>
</html>
index.js
var React = require('react')
var ReactDOM = require('react-dom')
var App = require('./app')
var Hello = React.createClass ({
render: function() {
return (
<h1>
Hello, World!
</h1>
)
}
})
ReactDOM.render(<Hello />, document.gectElementById('react-app'))
I have integrated React with Django, trying to setup hot-reload. However the error doesn't seem to be with any of django or react. Probably I'm missing something with webpack-dev-server.

ReactJs AdminLTE Dashboard

I am new in ReactJS. I want to use ReactJS-AdminLTE in my project. Can anybody tell how to use it with step by step process.
Steps I followed
1) I set Reactjs environment using https://www.tutorialspoint.com/reactjs/ tutorial
2) Then I install ReactJS-AdminLTE using command npm install adminlte-reactjs
My webpack.config file is
var path=require('path');
var config = {
entry: './main.js',
output: {
path: path.join(__dirname, "./"),
filename: 'index.js',
},
devServer: {
inline: true,
port: 8080
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
}
}
module.exports = config;
App.jsx
import React from 'react';
import reactjsAdminlte from 'adminlte-reactjs';
class App extends React.Component {
render() {
return (
<Box
width = 3
border = true
content = 'The body of the box'
theme = 'box-primary'
title = 'Collapsable'
collapsed = true
boxTools = ['collapse']
/>
);
}
}
export default App;
Index.html
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<title>React App</title>
</head>
<body>
<div id = "app"></div>
<script src = "index.js"></script>
</body>
</html>
But result is not displaing.
Are you using ReactDOM to render your app component to the HTML?
import ReactDOM from 'react-dom';
ReactDOM.render(
<App />,
document.getElementById('app')
);

React server-side rendering with hot module reload

I've been doing a lot of reading on this, it seems that a lot of boilerplates available on github that enable both of these use webpack-dev-server to rebuild the client bundle. However, I'm not sure how or if the server is hot-module reloaded. Is there a way to configure webpack to enable HMR on the server-side? Otherwise, it seems that anything I change won't be rendered by the server, only refreshed on the client.
My webpack config looks something like this:
module.exports = {
entry: "./js/client.js",
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy'],
}
}
]
},
output: {
path: __dirname + "/public/",
filename: "client.min.js"
}
};
server.js:
app.get('/', function(request, response) {
var html = ReactDOMServer.renderToString(React.createElement(Component));
response.send(html);
});
Component.js:
module.exports = React.createClass({
_handleClick: function() {
alert();
},
render: function() {
return (
<html>
<head>
<title>{this.props.title}</title>
<link rel="stylesheet" href="/style.css" />
</head>
<body>
<h1>{this.props.title}</h1>
<p>isn't server-side rendering remarkable?</p>
<button onClick={this._handleClick}>Click me</button>
<script dangerouslySetInnerHTML={{
__html: 'window.PROPS=' + JSON.stringify(this.props)
}} />
<script src="/client.min.js" />
</body>
</html>
);
}
})
and client.js:
var props = window.PROPS;
ReactDOM.render(React.createElement(Component, props), document);
I use webpack-dev-server --content-base src --inline --hot to run webpack
You're going to want to run your code via your server.js. Create a script in your package.json to run that file.
For example:
"serve":"nodemon server.js"
Then, add an alternative to webpack-dev-server which is the webpack-dev-middleware and webpack-hot-middlware which can help you with HMR.
This is how you're server.js will look like:
import express from 'express';
import webpack from 'webpack';
import path from 'path';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
const port = 5000;
const app = express();
const config = require(path.resolve("./webpack.config.js"));
const compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, {
noInfo: true,
publicPath: config.output.publicPath,
}));
app.use(webpackHotMiddleware(compiler));
app.get("*", function(req, res, next) {
res.sendFile( path.join( __dirname, '/path/to/your/index.html') );
});
app.listen(port, function(err) {
if(err) {
return console.log(err);
}
return console.log(`App is now running on http://localhost:${port}`);
});
Then, run your script, like so:
npm run serve
And just visit the port on the browser, your client will then show up.
Hope this helps.

webpack express Uncaught SyntaxError: Unexpected token <

i need help, with this error "webpack express Uncaught SyntaxError: Unexpected token <" can u tell me what i doing wrong ? webpack and express server not reported eny erorrs..
file struture:
app
package.json
server.js
webpack.config.js
-public
--index.html
--bundle.js
-node_modules
-src
--config.js
--index.js
--about
---about.html
--todos
---todos.html
webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = {
devtool: 'inline-source-map',
entry: ['./src'],
output: {
path: path.join(__dirname, 'public'),
filename: 'bundle.js'
},
resolve: {
modulesDirectories: ['node_modules', 'src'],
extension: ['', '.js']
},
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015']
}},
{ test: /\.html$/,
loader: 'raw'}
]
},
devServer: {
hot: true,
proxy: {
'*': 'http://localhost:3000'
}
}
};
index.js
import angular from 'angular';
import appModule from 'config';
angular.bootstrap(document, [appModule.name]);
index.html
<html>
<head>
<title>MEAN ToDo App</title>
<base href="/">
</head>
<body>
<div ui-view></div>
<script src="bundle.js"></script>
</body>
</html>
config.js
import angular from 'angular';
import uiRouter from 'angular-ui-router';
const app = angular.module('app', [uiRouter]);
app.config(($stateProvider, $urlRouterProvider, $locationProvider) => {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('todos', {
url: '/',
template: require('todos/todos.html'),
})
.state('about', {
url: '/about',
template: require('about/about.html')
});
$locationProvider.html5Mode(true);
});
export default app;
server.js
var express = require('express');
var app = express();
var path = require('path');
var PORT = process.env.PORT || 3000;
app.all('/*', function(req, res) {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
app.listen(PORT, function() {
console.log('Server running on ' + PORT);
});
The problem is in the node code:
app.all('/*', function(req, res) {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
All routes are returning index.html. Try removing the *.
Your express server is misconfigured – it always returns index.html.
Try this instead:
app.use(express.static('/'));
app.listen(3000, function() {
console.log('listening');
});
Or use http-server from npm.

Resources