Webpack Not Serving React Component - reactjs

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.

Related

Can't load assets from public folder in development mode in webpack

I am new to webpack. I am trying to access my assets file outside of the src folder during development mode. The only solution I found in the internet is using copy-webpack-plugin. But I think that is for build. But since I am in development mode all things will load into memory. I might be wrong.
This is my file structure right now
File Sturcutre
And I am trying to access those file in index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="description" content="Fuse React - Material design admin template with pre-built apps and pages" />
<meta
name="keywords"
content="React,Redux,Material UI Next,Material,Material Design,Google Material Design,HTML,CSS,Firebase,Authentication,Material Redux Theme,Material Redux Template"
/>
<meta name="author" content="Withinpixels" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="theme-color" content="#000000" />
<base href
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<link href="%PUBLIC_URL%/assets/fonts/material-design-icons/MaterialIconsOutlined.css" rel="stylesheet" />
<!-- <link href="%PUBLIC_URL%/assets/fonts/material-design-icons/MaterialIcons.css" rel="stylesheet">-->
<!-- <link href="%PUBLIC_URL%/assets/fonts/material-design-icons/MaterialIconsRound.css" rel="stylesheet">-->
<!-- <link href="%PUBLIC_URL%/assets/fonts/material-design-icons/MaterialIconsSharp.css" rel="stylesheet">-->
<!-- <link href="%PUBLIC_URL%/assets/fonts/material-design-icons/MaterialIconsTwoTone.css" rel="stylesheet">-->
<link href="%PUBLIC_URL%/assets/fonts/meteocons/style.css" rel="stylesheet" />
<noscript id="jss-insertion-point"></noscript>
<title>Fuse React - Material Design Admin Template</title>
</head>
<body>
<noscript> You need to enable JavaScript to run this app. </noscript>
<div id="root" class="flex">
<!-- FUSE Splash Screen -->
<div id="fuse-splash-screen">
<div class="center">
<div class="logo">
<img width="128" src="assets/images/logos/fuse.svg" alt="logo" />
</div>
<!-- Material Design Spinner -->
<div class="spinner-wrapper">
<div class="spinner">
<div class="inner">
<div class="gap"></div>
<div class="left">
<div class="half-circle"></div>
</div>
<div class="right">
<div class="half-circle"></div>
</div>
</div>
</div>
</div>
<!-- / Material Design Spinner -->
</div>
</div>
<!-- / FUSE Splash Screen -->
</div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
And this is my webpack config file
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const PUBLIC_DIR = path.join(__dirname, './public');
const PUBLIC_URL = process.env.PUBLIC_URL || '/';
const HTML_TEMPLATE = 'index.html';
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, '/dist'),
filename: 'index_bundle.js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.(jpg|jpeg|png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000'
},
{
test: /\.css$/,
use: [
'style-loader',
// MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [require('tailwindcss'), require('autoprefixer')]
}
}
]
}
]
},
plugins: [
// new HtmlWebpackPlugin(),
new HtmlWebpackPlugin({
// template: `${PUBLIC_DIR}/${HTML_TEMPLATE}`,
template: './public/index.html',
filename: 'index.html',
templateParameters: {
PUBLIC_URL
}
})
// new MiniCssExtractPlugin()
],
resolve: {
alias: {
'#fuse': path.resolve(__dirname, './src/#fuse/'),
'#history': path.resolve(__dirname, './src/#history/'),
'#lodash': path.resolve(__dirname, './src/#lodash'),
i18n: path.resolve(__dirname, './src/i18n'),
app: path.resolve(__dirname, './src/app/')
}
}
};
NB: I am using react#17.0.2, webpack#4.43.0
Webpack just loads images that was in the webpack flow... If you want to copy extra assets you will need plugins like copy-webpack-plugin as you say.
loaders:
{
test: /\.(jpg|jpeg|png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000'
}
Just would copy the *..(jpg|jpeg|png|woff|woff2|eot|ttf|svg) files that are imported in tree generated by the entry (entry: './src/index.js'). In your case the image was imported in the index.html file, which is not in the file tree generated by the webpack entry. If you import that image on './src/index.js' you will see the image in the output folder dist

Webpack/React app setup failing - "React is not defined"

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']
}

React + Webpack: React.createElement: type should not be null, undefined, boolean, or number

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;

No Error so is why my component not rendering?

I am brand spanking new to this React stuff and stumbling around trying to understand all of the moving parts. I have started a server with the webpack dev server and attempting to render my code to http://localhost:8080/ but to no avail. It's just a simple form component. There are more than likely many things wrong with how I have things set up, but again, still learning! Thanks for any help anyone can offer. I have an index.html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Practicing Components</title>
</head>
<body>
<div id="app"></div>
<script type='text/babel'></script>
</body>
</html>
This index.html file is rendering my main.js file:
import React from 'react';
import ReactDOM from 'react-dom';
class Main extends React.Component {
render() {
return (
<div>
<h1>Welcome to the Name Board!</h1>
<Form />
<Button />
</div>
);
}
}
class Form extends React.Component {
constructor(props) {
super(props);
this.state= {value: 'Please type your name.'};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
return (
<input type="text" value={this.state.value} onChange={this.handleChange} />
);
}
}
class Button extends React.Component {
render() {
return (
<button value="Submit">
</button>
);
}
}
ReactDOM.render(<Main />, document.getElementById('app'));
I've set up my module loaders and entry point and all that in my webpack.config.js:
var path = require("path");
module.exports = {
entry: {
app: ["./main.js"]
},
output: {
path: path.resolve(__dirname, "build"),
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel',
exclude: /node_modules/,
query: {
cacheDirectory: true,
presets: ['react', 'es2015']
}
}
]
}
};
However, despite not having any error messages and my server being successfully connected, I am rendering nothing.
Looks like you're not even loading the bundle:
<script src="/build/bundle.js"></script>
It's not React. It's the HTML code. It doesn't seem to be telling the browser to load the bundle from anywhere, e.g. the <script> tag doesn't have an attribute src="/build/bundle.js".
So maybe to fix it, you'd have better luck after changing your HTML code to look like so?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Practicing Components</title>
</head>
<body>
<div id="app"></div>
<!-- See how "src" is now set to "app.bundle.js"? -->
<script src='/build/bundle.js'></script>
</body>
</html>

Split react code into react library bundle and components bundle

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.

Resources