I am using webpack to set up a React app.
When I serve my app locally using webpack-dev-server I get VM1086 bundle.js:9812 Uncaught ReferenceError: React is not defined in the console.
I have know idea what is going on as there aren't any other errors or information to go on, as webpack seems to compile ok.
index.html
<html>
<head>
<script src="./dist/bundle.js" ></script>
</head>
<body>
<div id="mount"></div>
</body>
</html>
webpack config
var path = require('path');
module.exports = {
entry: [
'./src/App.js',
],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: ['node_modules'],
loader: 'babel-loader',
query: {
babelrc: true,
},
}
]
}
}
app.js
import React from 'react';
import ReactDOM from 'react-dom';
console.log('Hello World!');
class App extends React.Component {
render() {
return (<div>314159263</div>);
}
}
ReactDOM.render(<App />, document.getElementById('mount'))
try to define bundle.js after <div id="mount"></div> because may be your bundle compiles your code and it does not find where to render the code
</head>
<body>
<div id="mount"></div>
<script src="./dist/bundle.js" ></script>
</body>
</html>
and also in your webpack add this
query: {
presets: ['es2015', 'react']
}
Related
I have created my webpack config file below:
const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/main.js',
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: '/node_modules/',
use: [
{
loader: 'babel-loader'
}
]
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: {minimize: true}
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
filename: './index.html'
})
]
};
and added all the necessary packages babel with env and react presets. I have my index.html file and TestComponent like below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React 16 Webpack Setup</title>
</head>
<body>
<script src="bundle.js" type="text/javascript"></script>
<div id="test">
</div>
</body>
</html>
and component code:
import React, { Component } from 'react';
export default class TestComponent extends Component {
render(){
return (
<div>
<h2>React Setup</h2>
</div>
)
}
}
Here's my main.js file where I'm hosting the component:
import React from "react";
import ReactDOM from "react-dom";
import Test from './TestComponent';
ReactDOM.render(<Test/>, document.getElementById("test"));
The problem is that when I run this script from package.json, I don't get any output/dist folder and also the component doesn't render in the browser. On which url do I have to visit to see the output just like with create-react-app?
Import your <script> at the bottom of the <body> tag in the HTML.
In your case, the browser is reading through the DOM and finding the <script> tag before it is finding the <div id="text"> node. What this means is that the browser will read through your script, and then try and render your <Test/> component into an HTML node with the id="test". The browser can't find the HTML node with the id="test" though because it hasn't read it yet, so it fails.
Make sense? See below...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React 16 Webpack Setup</title>
</head>
<body>
<div id="test"></div>
{* import scripts at the bottom of the body *}
<script src="bundle.js" type="text/javascript"></script>
</body>
</html>
Hope this helps, let me know if you're still running into issues.
I just finished learning ReactJS and was trying to go start learning webpack. I was curious if I could turn my existing website (server-side) structure into react type website (SPA). But my only issue is that I am using a lot of vendor js and css files.
<!doctype html>
<html lang="en">
<head>
<!-- Fonts Online -->
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800,300' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
<!-- Style Sheet -->
<link rel="stylesheet" href="css/owl.carousel.css">
<link rel="stylesheet" href="css/main-style.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<!-- Scripts -->
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="js/jquery-2.1.3.min.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/plugins/superfish.min.js"></script>
<script src="js/jquery.ui.min.js"></script>
<script src="js/plugins/rangeslider.min.js"></script>
<script src="js/plugins/jquery.flexslider-min.js"></script>
<script src="js/uou-accordions.js"></script>
<script src="js/uou-tabs.js"></script>
<script src="js/plugins/select2.min.js"></script>
<script src="js/owl.carousel.min.js"></script>
<script src="js/gmap3.min.js"></script>
<script src="js/scripts.js"></script>
<script>
</script>
</body>
</html>
Now I want to make it like this:
<!doctype html>
<html lang="en">
<head>
<!-- Fonts Online -->
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800,300' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
</head>
<body>
<div id="#root"></div>
</body>
</html>
This is my current webpack config:
const path = require('path');
const autoprefixer = require('autoprefixer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
chunkFilename: '[id].js',
publicPath: ''
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query:
{
presets:['react']
}
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
autoprefixer({
browsers: [
"> 1%",
"last 2 versions"
]
})
]
}
}
]
},
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'url-loader?limit=8000&name=images/[name].[ext]'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: __dirname + '/src/index.html',
filename: 'index.html',
inject: 'body'
})
]
};
The online tutorials kind of confuse me as a beginner in Webpack. So if someone could help me out in this particular use-case, it will help me better understand webpack in general.
I have following configuration
webpack.config.js:
var webpack = require("webpack");
var path = require("path");
var DIST_DIR = path.resolve(__dirname,"dist");
var SRC_DIR = path.resolve(__dirname,"src");
var config = {
entry:
{
'index':SRC_DIR + "/app/index.js",
'home':SRC_DIR + "/app/home.js",
'profile':SRC_DIR + "/app/profile.js"
},
output: {
path: DIST_DIR + '/app',
filename: "[name].bundle.js",
publicPath: "/app/"
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "common",
chunks: ["index", "home","profile"]
})],
module:{
loaders:[
{
test: /\.js?/,
include: SRC_DIR,
loader: "babel-loader",
query:{
presets:['react','es2015','stage-2'],
}
}
]
},
devServer: {
historyApiFallback: true
}
}
module.exports = config;
Now, I want to load common.bundle + index.bundle in case of index.js, common.bundle + profile.bundle in case of profile.js and so on.
I have only one index.html file, I want to load these three bundles separately whenever corresponding url is hit.
<!DOCTYPE html>
<html>
<head>
<title>Reactjs Basic</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-offset-2 col-md-8">
<div id="app"></div>
</div>
</div>
</div>
<script src="/app/index.bundle.js"></script>
</body>
</html>
Is it possible with only one index.html file? Do I need more than one html?
Why am I getting that error in the console of the chrome ?
My code:
index.html
<!DOCTYPE html>
<html>
<head>
<title>hello React</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div id="root">
<!-- my app renders here -->
</div>
<script src="../react-15.3.1/build/react.js"></script>
<script src="../react-15.3.1/build/react-dom.js"></script>
<script src="./dist/bundle.js"></script>
</body>
</html>
main.js
import SalutaMondo from './salutamondo';
var UnaProva = React.createClass({
render: function(){
return (
<div>
<SalutaMondo/>
<div>Ciao Emiliano</div>
</div>
);
},
});
ReactDOM.render(<UnaProva />, document.getElementById("root"));
salutamondo.js
var SalutaMondo = React.createClass({
render: function(){
return (
<h1>Hello World</h1>
);
}
});
module.export = SalutaMondo;
webpack.config.js
const webpack = require('webpack')
const path = require('path')
module.exports = {
entry: [ './src/salutamondo.js', './src/main.js' ],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015']
}
}
]
}
}
In your webpack config, you're using the babel-loader. This implies that you're using ES6 style modules. In salutamondo.js, you're using CommonJS style modules. As a result, the babel-loader isn't picking up the module. Can you try:
export default SalutaMondo;
instead of:
module.export = SalutaMondo;
This is likely due to salutamondo.js using CommonJS module format, while main.js is using ECMAScript module. I recommend keeping everything in ECMAScript modules:
var SalutaMondo = React.createClass({
render: function(){
return (
<h1>Hello World</h1>
);
}
});
export default SalutaMondo;
I have the following configuration for webpack (integrated with grunt):
var path = require('path');
var webpack = require('webpack');
module.exports = {
run_webpack: {
entry: {
react: "./static/src/jsx/react.jsx",
index: "./static/src/jsx/index.jsx"
},
output:{
path: "./static/js/",
filename: "[name].bundle.js",
},
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
},
},
};
My react.jsx and index.jsx:
// react.jsx
var React = require('react');
var ReactDOM = require('react-dom');
// index.jsx
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('app')
);
And then I embed those bundles into html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Kanban app</title>
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<script type="text/javascript" src="{% static 'js/react.bundle.js' %}"></script>
<script type="text/javascript" src="{% static 'js/index.bundle.js' %}"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
My problem that it doesn't render <h1>Hello, world!</h1>. The error is 'ReactDOM is not defined'. How can I overcome that issue? It works when I merge react.jsx and index.jsx, but still would like to keep them separately to accelerate code compiling.
Your index.jsx simply has to depend on react and react-dom for the code to work. To achieve what you want, you can load them using externals, though. You could set up something like this for the target generating index:
externals: {
'react': {
commonjs: 'react',
commonjs2: 'react',
amd: 'React',
root: 'React'
},
'react-dom': 'react-dom'
},
This way webpack won't bundle react and react-dom to your index bundle.