I am attempting to learn react and I am coming to some issues when attempting client side routing. Please let me know if you see the mistake I have in my files listed.The error I keep getting on the browser page is
Cannot GET /
The error I see in my console is:
live.bundle.js:14 GET http://localhost:8080/ 404 (Not Found)
Here are my files:
webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: [
'webpack/hot/only-dev-server',
'./js/app.js'
],
output: {
path: __dirname + '/build',
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.js?$/, loaders: ['react-hot', 'babel', 'babel-loader'], exclude: /node_modules/ },
// { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },
{ test: /\.css$/, loader: "style!css" }
]
},
devServer: {
contentBase: "./src/www",
noInfo: true,
hot: true,
inline: true
},
plugins: [
new webpack.NoErrorsPlugin()
]
};
.babelrc
{
"presets": ["es2015", "react"]
}
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>New React App</title>
</head>
<body>
<section id="react"></section>
<script src="/build/bundle.js"></script>
</body>
</html>
/js/app.js
import React from 'react';
import Router from 'react-router';
import {DefaultRoute, Link, Route, RouteHandler} from 'react-router';
import LoginHandler from './components/Login.js';
class App extends React.Component{
render() {
return(
<div className="nav">
<Link to="app">Home</Link>
<Link to="login">Login</Link>
{/* Important Part */}
<RouteHandler/>
</div>
);
}
}
let routes = (
<Route name="app" path="/" handler={App}>
<Route name="login" path="/login" handler={LoginHandler}/>
</Route>
);
ReactDOM.run(routes, function (Handler) {
React.render(<Handler/>, document.body);
});
/js/components/Login.js
import React from 'react';
class Login extends React.Component{
render() {
return(
<div>Welcome to login</div>
);
}
}
export default Login;
I appreciate the help.
Here is my webpack.config.js file updated according to #Frederick Mfinanga
var webpack = require('webpack');
module.exports = {
entry: [
'webpack/hot/only-dev-server',
'./js/app.js',
'webpack-dev-server/client?localhost:8080'
],
output: {
path: __dirname + '/build',
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.js?$/, loaders: ['react-hot', 'babel', 'babel-loader'], exclude: /node_modules/ },
// { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },
{ test: /\.css$/, loader: "style!css" }
]
},
devServer: {
// contentBase: "./src/www",
noInfo: true,
hot: true,
inline: true
},
plugins: [
new webpack.NoErrorsPlugin(),
new webpack.HotModuleReplacementPlugin()
]
};
remove
contentBase: "./src/www",
from your devServer config. This will by default serve the files in your current directory. which i believe is what you are looking for and where your index.html lives? correct?
Related
I have a ReactJS application with webpack module builder, following is the configuration in my webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: {
app : './src/scripts/app.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'public')
},
context: __dirname,
resolve: {
extensions: ['.js', '.jsx', '.json', '*']
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
options: {
presets: ['react', 'es2015']
}
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
}
};
I have following code in my app.js
import React from 'react';
import ReactDOM from 'react-dom';
var MainApp = React.createClass({
render: function(){
return (
<div>
<div>Header component</div>
<div>Boady component</div>
</div>
);
}
});
ReactDOM.render(
<MainApp />,
document.getElementById('container')
);
Now after running the server, when I load my page in browser getting following error:
Uncaught TypeError: _react2.default.createClass is not a function
Attaching screenshot of the error message:
I would like to know more details on this issue, many thanks for the help.
You need to install this npm extension:
npm install create-react-class --save
And then use this code:
var createReactClass = require('create-react-class');
var MainApp = createReactClass({
render: function(){
return (
<div>
<div>Header component</div>
<div>Boady component</div>
</div>
);
}
});
}
I have the following webpack config file:
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'src/client/public');
var APP_DIR = path.resolve(__dirname, 'src/client/app');
var config = {
entry: [
APP_DIR + '/config/routes.jsx',
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080'
],
output: {
publicPath: 'http://localhost:8080/src/client/public/'
},
module : {
loaders : [
{
test: /\.jsx?$/,
loader: 'babel-loader',
include: APP_DIR,
exclude: /node_modules/,
query: {
presets: ['es2015']
}
},
{
test: /\.scss$/,
loaders: [ 'style', 'css', 'sass' ]
},
{
test: /\.json$/,
loader: "json-loader"
}
]
}
};
module.exports = config;
all I am trying to do is run my app on localhost, however when I hit: "http://localhost:8080/src/client/home" (as per my routes.jsx and after running webpack-dev-server)
import React from 'react';
import { Route, Router, browserHistory } from 'react-router';
import ReactDOM from 'react-dom';
import Wrapper from './../components/wrapper.jsx';
import Home from './../components/home.jsx';
import Projects from './../components/projects.jsx';
import SingleProject from './../components/projectContent/singleProject.jsx';
import About from './../components/aboutUs.jsx'
ReactDOM.render((
<Router history={browserHistory} >
<Route path="/" component={Wrapper} >
<Route path="home" component={Home} />
<Route path="projects" component={Projects} />
<Route path="projects/:id" component={SingleProject} />
<Route path="about" component={About} />
</Route>
</Router>
), document.getElementById('app'));
I get
"Cannot GET /src/client/home".
First thing you have mentioned in your routes as the home component to have path /home. So you need to visit http://localhost:8080/home. Also if you try to access this url directly, it will give you this error since you are using browserHistory. If you want you can use hashHistory or HashRouter in react-router v4, in which case you will need to visit http://localhost:8080/#/home. If you want to continue using browserHistory or BrowserRouter as in react-router v4, then you will need to add historyApiFallback: true in you webpack
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'src/client/public');
var APP_DIR = path.resolve(__dirname, 'src/client/app');
var config = {
entry: [
APP_DIR + '/config/routes.jsx',
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080'
],
output: {
publicPath: 'http://localhost:8080/src/client/public/'
},
devServer: {
historyApiFallback: true
},
module : {
loaders : [
{
test: /\.jsx?$/,
loader: 'babel-loader',
include: APP_DIR,
exclude: /node_modules/,
query: {
presets: ['es2015']
}
},
{
test: /\.scss$/,
loaders: [ 'style', 'css', 'sass' ]
},
{
test: /\.json$/,
loader: "json-loader"
}
]
}
};
module.exports = config;
You need to add this in your webpack settings:
devServer: {
historyApiFallback: true,
},
And start your server like this:
webpack-dev-server --config webpack.config.js
Because you want React-Route to handle the route instead of your server. So no matter what the url is it should goes to index.html.
I've followed the following guides:
https://webpack.js.org/guides/hmr-react/
http://gaearon.github.io/react-hot-loader/getstarted/
https://github.com/wkwiatek/react-hot-loader-minimal-boilerplate
But I can't seem to make HMR work for Electron. These are logs I get when I apply some changes:
[WDS] App updated. Recompiling...
[WDS] App hot update...
[HMR] Checking for updates on the server...
[HMR] Cannot find update. Need to do a full reload!
[HMR] (Probably because of restarting the webpack-dev-server)
[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.
This is my webpack.config.js:
const webpack = require('webpack')
const { join, resolve } = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
context: resolve(__dirname, 'app'),
entry: [
'babel-polyfill',
'react-hot-loader/patch',
'./index.tsx'
],
output: {
filename: './bundle.js',
path: resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.(js|ts|tsx)$/,
use: 'babel-loader',
exclude: /node_modules/
}, {
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/
}, {
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader'
}, {
loader: 'sass-loader'
}
]
}),
exclude: /node_modules/
}]
},
target: 'electron',
resolve: {
extensions: ['.tsx', '.ts', '.js', '.jsx', 'scss']
},
devtool: 'source-map',
plugins: [
new ExtractTextPlugin('bundle.css')
]
}
This is my start script:
"watch": "./node_modules/.bin/webpack-dev-server --hot --history-api-fallback"
This is my root component:
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import { Provider, Store } from 'react-redux'
import App from './App'
import reducer from './reducers'
import configureStore from './store/configureStore'
import './stylesheets/index.scss'
const store: Store<any> = configureStore()
const render = (Component) => {
ReactDOM.render(
<AppContainer>
<Provider store={store}>
<Component/>
</Provider>
</AppContainer>,
document.getElementById('root')
)
}
render(App)
if (module['hot']) {
module['hot'].accept('./App', () => {
render(App)
})
}
This is my .babelrc config:
{
"presets": [
["es2015", {"modules": false}],
"react"
],
"plugins": [
"react-hot-loader/babel"
]
}
Also my index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Markers - Notes for students</title>
<link href="http://localhost:8080/bundle.css" rel="stylesheet"/>
</head>
<body>
<div id="root"></div>
<script src="http://localhost:8080/bundle.js"></script>
</body>
</html>
I don't know if it has something to do but I'm using typescript. Any help is welcome. Thanks!
My tree view:
- app
- App.js
- assets
- Linux.png
- render-web.js
- webpack.config.js
My config:
const path = require('path');
const webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'react-hot-loader/patch',
'webpack-dev-server/client?https://localhost:9000',
'webpack/hot/only-dev-server',
'./render-web'
],
output: {
path: path.join(__dirname, 'assets'),
filename: 'bundle.js',
publicPath: '/assets/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
devServer: {
compress: true,
https: true,
historyApiFallback: true,
inline: false,
port: 9000,
hot: true,
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
ast: false,
babelrc: false,
comments: false,
minified: true,
presets: ['es2015', 'react', 'stage-0'],
plugins: ['syntax-flow', 'react-hot-loader/babel'],
}
},
{
test: /node_modules\/react-native/,
loader: 'ignore-loader',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'url-loader?limit=9999999',
]
},
],
},
};
My entry file:
/* globals document */
import {AppContainer} from 'react-hot-loader';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app/App';
const rootElement = document.getElementById('reactors');
ReactDOM.render(
<AppContainer>
<App />
</AppContainer>,
rootElement
);
if (module.hot) {
module.hot.accept('./app/App', () => {
const NextApp = require('./app/App').default;
ReactDOM.render(
<AppContainer>
<NextApp />
</AppContainer>,
rootElement
);
});
}
Then from app/App.js:
import LinuxIcon from '../assets/Linux.png';
<img src={LinuxIcon} />
The path is correct (if I change it, webpack complains it does not exist).
It generates a base64 image:
data:image/png;base64,77+...too long to paste
But it just displays a blank square (no image). What am I doing wrong? Thanks!
BTW using:
file-loader#0.10.0
url-loader#0.5.7
webpack#2.2.1
webpack-dev-server#2.3.0
PS I've tried to move the assets directory into App as I've seen suggested but with no luck.
Despite heavy efforts to my knowledge, I am not able to get:
ReactDebugTool.js:14 Uncaught ReferenceError: require is not defined(…)
I have written a webpack config as below:
// webpack.config.babel.js
import path from 'path';
import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
const sharedConfiguration = {
cache: true,
context: __dirname,
entry: {
app: ["./example/example.js"],
styles: ["./example/example.scss"]
},
devtool: "source-map",
resolve: {
extensions: ["", ".js"]
},
module: {
preLoaders: [
{ test: /\.js$/, loaders: ["eslint", "eslint-loader"] }
],
loaders: [
{ test: /\.js$/, loader: "babel-loader", exclude: /node_modules/, query: { presets: ["es2015", "stage-0", "react"], plugins: ['transform-runtime'] } },
{ test: /\.(scss|sass)$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader?sourceMap!resolve-url-loader!sass-loader?sourceMap") },
{ test: /\.html$/, loaders: ["html-loader"] },
{ test: /\.(jpg|png|woff|woff2|eot|ttf|svg|ico)$/, loader: "file-loader?name=[name]-[hash].[ext]" },
{ test: /\.(json|geojson)$/, loader: "json-loader" }
],
noParse: /ol\.js/
},
eslint: {
configFile: './.eslintrc'
}
};
const developmentConfiguration = {
watch: true,
output: {
pathinfo: true,
filename: "[name]-[chunkhash].js",
path: path.resolve("./.tmp")
},
devServer: {
port: 8081
},
plugins: [
new ExtractTextPlugin("[name]-[chunkhash].css"),
new webpack.optimize.CommonsChunkPlugin({
name: "vendor"
}),
new HtmlWebpackPlugin({
template: "./example/example.ejs",
inject: false
})
]
};
let environmentConfiguration = developmentConfiguration;
const configuration = {
...sharedConfiguration,
...environmentConfiguration
};
export default configuration;
And my project holds a folder structure like this.
// example.ejs
<!DOCTYPE html>
<html>
<head>
<title>Editor</title>
<script src="<%= htmlWebpackPlugin.files.chunks.vendor.entry %>"></script>
<link rel="stylesheet" href="<%= htmlWebpackPlugin.files.chunks.styles.css[0] %>">
</head>
<body>
<div id="root"></div>
<script src="<%= htmlWebpackPlugin.files.chunks.app.entry %>"></script>
</body>
</html>
// example.js
import React from 'react';
import ReactDOM from 'react-dom';
import Hello from '../source/index';
ReactDOM.render(<Hello />, document.getElementById('root'));
// source/index.js
import React, {Component} from 'react';
export default class Hello extends Component {
render () {
return (
<div>
Hello
</div>
);
}
}
Most of the articles I referred, indicated to CommonsChunkPlugin I tried rectifying it, but was in vain. Any help would be appreciated.