css file not getting linked in index.html file served from webpack - reactjs

Hi I have the folder structure like as follows:-
node_modules
src
|____components
|____index.css
|____index.html
|____index.js
|____index.scss
.babelrc
package.json
webpack.config.js
content of my webpack.config.js file is as below:-
const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const ExtractTextPlugin = require("extract-text-webpack-plugin")
module.exports = {
entry: {
"index": "./src/index.js",
},
output: {
path: path.join(__dirname, "/dist"),
filename: "[name].js",
},
resolve: {
alias: {
components: path.resolve(__dirname, "src/components")
},
extensions: [".js", ".jsx", ".json"],
mainFiles: ["index"]
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(s*)css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader", "sass-loader"]
})//["style-loader", "css-loader", "sass-loader"]
}
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
}),
new ExtractTextPlugin({
filename: "bundle.css"
})
],
watch: true,
}
content of my index.html file as follows:-
<!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" type="text/css" href="./index.css">
<title>React Boilerplate</title>
</head>
<body>
<div id="root">
</div>
</body>
</html>
..
<link rel="stylesheet" type="text/css" href="./index.css">
the above line is not loading my index.css into browser while inside src/components level, i do have css files, whichare properly getting bundeled and delivered in bundle.css file.
Any help would be of great help

The link to the css should be:
<link rel="stylesheet" type="text/css" href="/index.css">
This should be like this due to the publicPath. Since it is not set, it is by default /.

The link to the css should be:
<link rel="stylesheet" type="text/css" href="../src/index.css">

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 Not Serving React Component

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.

Converting an existing HTML to React using Webpack

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.

Using multiple entries for reactjs SPA

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?

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