Jie Jie - 3 months ago 39
React JSX Question

ReactDOM does not render component into html

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>

Answer

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.