Reputation: 18684
I am trying to create my a ReactJS project, but am struggling with some basics. I have a /dist/ folder, in which I have my index.html file, as well as the location for the bundle.js and anything else needed to run the application (in my case, an image).
This is my current folder structure: (full code; https://github.com/CraigInBrisbane/ReactLearning)
Below is my webpack.config.js file.
I cannot find how the index.html file is loaded, and why I have it. It sits in the /dist/ folder. How does react know to load the index file from here when I run the app locally? (npm run dev)
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.jsx',
output: {
path: path.join(__dirname, '/dist/'),
filename: 'bundle.js',
publicPath: ''
},
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['env', 'react'],
"plugins": ["transform-es2015-destructuring", "transform-object-rest-spread"]
}
},
{
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
},
{
test: /\.svg$/,
loader: 'babel-loader!svg-react-loader'
}
]
},
devServer : {
contentBase: './dist'
}
};
This is my packages.json. When I run webpack, it seems to update bundle.js and the image, but the html remains the same. This might be OK. Is this the right place to keep this file? I thought the /dist folder would be rebuilt when ever I run webpack. If I remove the index.html file from there- the app no longer loads.
Also, if I copy the dist folder to a web server (So, deploy it), I get a blank screen on load. I think I've got my folder structures wrong.
{
"name": "leantreact",
"version": "1.0.0",
"description": "A small project to try and learn ReactJS",
"main": "./src/index.jsx",
"scripts": {
"dev": "webpack-dev-server --progress --colors",
"build": "webpack -p --progress",
"test": "echo \"Error: no test specified\" && exit 1"
},
"license": "ISC",
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.7",
"file-loader": "^1.1.5",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-toastify": "^3.3.4",
"style-loader": "^0.19.0",
"svg-react-loader": "^0.4.5",
"url-loader": "^0.6.2",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.9.7"
}
}
If my folder structure valid for a project, and how would I 'publish' my app to my web server? I was hoping to just copy the /dist contents, but the html file doesn't seem to load the same way it does on my webpack-devserver.
Strangely, all that loads when I copy the files to my web server, is the footer! The console shows no error.
It's as if my 'Router' never gets loaded. My App.jsx is this:
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Home from './pages/home.jsx';
import About from './pages/about.jsx';
import Contact from './pages/contact.jsx';
import Footer from './components/footer.jsx';
import SignIn from './pages/signin.jsx';
import Register from './pages/register.jsx';
export default class App extends React.Component {
render() {
return (
<div>
<Router>
<div>
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
<Route path="/signin" component={SignIn} />
<Route path="/register" component={Register} />
</div>
</Router>
<Footer />
</div>
)
}
}
I think the way I am running my webpack dev server might be part of the issue. Because something else that happens is, when I go to a route (Such as mysite/signin), it works.. the sing in component is loaded. However, if I make a code change, the webpack rebuilds, and I get the error: Cannot GET /signin
I then have to remove the "signin" from the url in the browser, it the home screen loads. Note, when I go to my signin page (route?), the url changes to "http://localhost:8080/signin"
The HTML file is just:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<title>Learning Stuff</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
Upvotes: 1
Views: 569
Reputation: 3863
How does react know to load the index file from here when I run the app locally? (npm run dev)
React dev server knows where to look for index.html because you have the following lines in your webpack config:
devServer : {
contentBase: './dist'
}
With npm start dev
you are running the webpack-dev-server and it looks in the /dist folder for the index.html as a base of your react app.
Is this the right place to keep this file?
There are different opinions on that. Often people think that the dist folder should be purely generated, so you can delete it completely, run the build script and get the deployable version of the app from scratch. That would not work with your approach, since the index.html has been probably placed there manually and will not be there if you remove the /dist folder and run the build script again.
On the other hand, for small projects that might be a normal approach. Anyway, if you want the index.html to be generated as well, you should take a look at the html-webpack-plugin for webpack.
I was hoping to just copy the /dist contents, but the html file doesn't seem to load the same way it does on my webpack-devserver.
Can you give a little more info on that? Are there any errors in the console when you open the deployed app?
Upvotes: 2