Reactjs hot-loader css files - html

I started new project with react-hot-boilerplate. Everything worked fine until i tried to add a css file to index.html.
<Link href="/style/main.css" rel="stylesheet">
Hot-loader doesnt read the css file. After some research i found out this line in server.js redirect all request to index.html
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
i changed it to
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
app.get('/style/main.css', function(req, res) {
res.sendFile(path.join(__dirname, 'style/main.css'));
});
and it worked. is there any better way to do that? do i need to map all the resources i servere.js?
I dont want to use style-loader or css-loader in webpack because i get a lot of errors and i cant simply use className="myCustomStyle".
var path = require('path');
var webpack = require('webpack');
var packageJSON = require('./package.json');
const PATHS = {
build: path.join(__dirname, 'target', 'classes', 'META-INF', 'resources', 'webjars', packageJSON.name, packageJSON.version)
};
module.exports = {
devtool: 'cheap-module-source-map',
resolve: {
extensions: ['', '.js', '.jsx', '.scss'],
alias: {
config: path.join(__dirname, 'src/config/dev.js'),
},
},
entry: [
'webpack-hot-middleware/client',
'./src/index'
],
output: {
path: PATHS.build,
filename: 'app-bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'src')
}, {
test: /\.css$/,
loader: 'style-loader!css-loader?modules=true&localIdentName=[name]__[local]___[hash:base64:5]'
}]
}
};

Loading the static files should not be handled on server side. So you should not insert your styling or js files in server else the loading time would be more and since you are using react so all your files would be js so if you write the resource to be sent on the server then it's of no use. so the best option is to write loaders in webpack.
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel',
exclude: /(node_modules|bower_components)/
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.(png|jpg)$/,
loader: 'file-loader'
}
]
}

If you want to do something like
<div className={styles.app}>
Then your component should be like
export default class Mycomponent extends Component{
let styles = {
app:{
'color': 'red',
}
}
return(){
render(
<div className={styles.app}>
)
}
}
This will solve your problem

Related

Webpack creates empty image files with FileLoader

I've just created a template for a webapp using Webpack.
Unfortunatly whenever I'm building the App to dev or Prod, the File-Loader does not fix there references images and it creates empty files.
My config looks like this:
webpack.common.config
// noinspection WebpackConfigHighlighting
const path = require('path');
require('html-webpack-plugin');
module.exports = {
entry: {
vendor: path.join(__dirname, 'Source', 'Vendor.ts'),
main: path.join(__dirname, 'Source', 'Index.tsx')
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: '/node_modules/',
include: [
path.resolve(__dirname, 'Source')
],
},
{
test: /\.worker\.ts$/,
loader: 'worker-loader',
options: {
esModule: false,
}
},
{
test: /\.(svg|png|jpg|gif|ico)$/i,
use: {
loader: 'file-loader',
options: {
name: '[name].[hash].[ext]',
outputPath: "Images"
}
}
},
{
test: /\.html$/,
use: ['html-loader']
}
]
}
};
webpack.dev.config
const path = require('path');
const common = require('./webpack.config');
const merge = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
module.exports = merge.merge(common, {
mode: 'development',
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'Build')
},
plugins: [
new MiniCssExtractPlugin(
{
filename: '[name].[contenthash].css'
}
),
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'Source', 'template.html'),
filename: 'Index.html'
})
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader'
]
},
{
enforce: "pre",
test: "/\.js$/",
loader: "source-map-loader"
}
]
},
devtool: 'source-map'
});
Once this is build my Output Folder looks like this:
1a901b56586b6444ae11.ico <-- these should no be here have 0 byte
c4f9748e8b8d4038f05c.png <-- these should no be here have 0 byte
Index.html
main.90957f37ae16dde06736.js
main.90957f37ae16dde06736.js.map
main.cf18790244b83b75a490.css
main.cf18790244b83b75a490.css.map
vendor.1ce4fff9da8447255aaf.js
Images\Favicon.fba6e1cd14b7ac368970b6418b5c67ac.ico
Images\Logo.86047b7e6019c39da248c24c90924f8c.png
The references in the htmls change like this
template.html
<link rel="icon" href="Images/Favicon.ico">
...
<img src="./Images/Logo.png">
Index.html
<link rel="icon" href="1a901b56586b6444ae11.ico">
...
<img src="c4f9748e8b8d4038f05c.png">
I've tested this with the a template I found here were it worked:
https://github.com/Colt/webpack-demo-app

CSS stylesheet isn't loading on html webpage after I type "npm run start"

I just installed react, webpack, and babel into one of my projects (I used this tutorial https://medium.com/swlh/a-complete-webpack-setup-for-react-e56a2edf78ae but I tweaked a bit of the webpack.config.js file because it was giving errors) and now my css stylesheet for my html file doesn't link (when I type npm run start) and I'm not exactly sure why
This is how I link my stylesheet
<link rel="stylesheet" type="text/css" media="screen" href="index-styles.css">
This is my webpack.config.js
const path = require("path");
const autoprefixer = require("autoprefixer");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
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/
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{ loader: "style-loader" },
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]"
},
sourceMap: true
}
},
{
loader: "postcss-loader"
// postcssOptions: {
// ident: "postcss",
// options: {
// }
// //plugins: () => [autoprefixer({})]
// }
}
]
},
{
test: /\.(png|jpe?g|gif)$/,
loader: "url-loader?limit=10000&name=img/[name].[ext]"
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: __dirname + "/src/index.html",
filename: "index.html",
inject: "body"
})
]
};
And right now my project structure is
assets
images
node_modules
src
|___index-styles.css (one I'm linking to index.html)
|___index.css (one used in index.js for tutorial)
|___index.html
|___index.js
.babelrc
package-lock.json
package.json
webpack.config.js

Webpack 4 not loading images from HTML files

For some reason my webpack configuration is loading the images that comes from my SCSS files but not the ones that come from the HTML files. Also when I run the BUILD command in order to deliver my prod archives it does not create the "img" folder. To be honest I'm pretty new with webpack 4 and I guess there's a couple of steps that I'm not including on the WP config file.
This is my webpack.dev.js
This is the prod folder structure that I would want to create:
dist
|----img
|----css
|----js
a.html
b.html
c.html
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
module.exports = {
entry: {
main: "./src/js/scripts.js"
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "js/[name].[hash].js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.scss$/,
use: [
"style-loader",
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader"
]
},
{
test: /\.(png|jpg|gif)$/,
use: ["url-loader"]
}
]
},
devServer: {
port: 8080
},
plugins: [
new CleanWebpackPlugin("dist", {}),
new MiniCssExtractPlugin({
filename: "css/style.[contenthash].css"
}),
new HtmlWebpackPlugin({
template: "./src/index.html",
inject: false,
hash: true,
filename: "index.html"
}),
new HtmlWebpackPlugin({
template: "./src/actualitat.html",
inject: false,
hash: true,
filename: "actualitat.html"
}),
new HtmlWebpackPlugin({
template: "./src/projectes.html",
inject: false,
hash: true,
filename: "projectes.html"
})
]
};
This is the way im loading both css and js on my html files:
<link
rel="stylesheet"
href="<%=htmlWebpackPlugin.files.chunks.main.css %>"
/>
<script src="<%= htmlWebpackPlugin.files.chunks.main.entry %>"></script>
I have a "scripts.js" js file where I import the files like this:
import "../scss/style.scss";
import "../img/searchBar-icon.png";
import "../img/townHall.png";
import "../img/icon-title.png";
UPDATE:
I have change the way im loading images using the "file-loader" loader:
{
test: /\.(png|jpg|gif)$/,
use: {
loader: "file-loader",
options: {
outputPath: "img/",
name: "[name][hash].[ext]"
}
}
}
Now all of my images are being copied to the "img" folder which is good, problem is that all the names of the files have hashes now (which make sense since I'm telling the loader to add them) and they're not loading on my html files.
Can you try the following for loading the images?
{
test: /\.(jpe?g|png|gif|ico)$/i,
use: ["file-loader?name=[name].[hash].[ext]"]
}

React/Webpack images not loading, but CSS does

So I just want to use some images in my React application, but images are not loading up. Some images are set up in CSS like that:
background-image: url('/../img/logo.png');
Another way I would like to use images in inside React components with
img tag, how would I go about doing this?
Here is my webpack config:
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = (env) => {
const isProduction = env === 'production';
return {
entry: './src/app.js',
output: {
path: path.resolve(__dirname, 'public', 'dist'),
filename: 'bundle.js'
},
module: {
rules: [{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
}, {
test: /\.s?css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it use publicPath in webpackOptions.output
publicPath: '../'
}
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}]
},
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "styles.css",
})
],
devtool: isProduction ? 'source-map' : 'inline-source-map',
devServer: {
contentBase: path.resolve(__dirname, 'public'),
historyApiFallback: true,
publicPath: '/dist/'
},
performance: {
hints: process.env.NODE_ENV === 'production' ? "warning" : false
},
}
};
index.html inside public folder:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Kinnisvara ABC</title>
<link rel="stylesheet" href="/dist/styles.css" type="text/css">
</head>
<body>
<div id="app"></div>
<script src="/dist/bundle.js"></script>
</body>
</html>
CSS is loading up, but images are not.
Pictures of my file structure:
Can anyone help me with that, please?
Have 2 way
Use webpack url-loader
Add this line to rules module in webpack file
{ test: /.(png|jpg|woff|woff2|eot|ttf|svg|gif)$/, loader: 'url-loader?limit=1024000' }
Use serve to point image
{
test: /\.(gif|png)$/, //Customise according to your need
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: PATH + '.[ext]' //Path will be assets or image path
}
}
]
}
configure url-loader in webpack configuration like this.
You didn't added image loader like css so try to add that
test: /\.(gif|jpe?g|png)$/,

Why webpack doesn't render CSS from components to vendor.css file?

I use this template It works well. As you can see on the screen, all lybrarys (like bootstrap) render their CSS into vendor.css, but my component renders it into html directly, just into the header part in the html file in tag. Can you tell me how to configure it right?
// webpack.config.js
var isDevBuild = process.argv.indexOf('--env.prod') < 0;
var path = require('path');
var webpack = require('webpack');
var nodeExternals = require('webpack-node-externals');
var merge = require('webpack-merge');
var allFilenamesExceptJavaScript = /\.(?!js(\?|$))([^.]+(\?|$))/;
//var ExtractTextPlugin = require('extract-text-webpack-plugin');
// Configuration in common to both client-side and server-side bundles
var sharedConfig = {
resolve: { extensions: ['', '.js', '.ts'] },
output: {
filename: '[name].js',
publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
module: {
loaders: [
{ test: /\.ts$/, include: /ClientApp/, loader: 'ts', query: { silent: true } },
{ test: /\.html$/, loader: 'raw' },
{ test: /\.css$/, loader: 'to-string!css' },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'url', query: { limit: 25000 } },
{ test: /\.(jpg1)$/, loader: 'file?name=[name].[ext]' }
]
}
};
// Configuration for client-side bundle suitable for running in browsers
var clientBundleConfig = merge(sharedConfig, {
entry: { 'main-client': './ClientApp/boot-client.ts' },
output: { path: path.join(__dirname, './wwwroot/dist') },
devtool: isDevBuild ? 'inline-source-map' : null,
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [] : [
// Plugins that apply in production builds only
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
])
});
// Configuration for server-side (prerendering) bundle suitable for running in Node
var serverBundleConfig = merge(sharedConfig, {
entry: { 'main-server': './ClientApp/boot-server.ts' },
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, './ClientApp/dist')
},
target: 'node',
devtool: 'inline-source-map',
externals: [nodeExternals({ whitelist: [allFilenamesExceptJavaScript] })] // Don't bundle .js files from node_modules
});
module.exports = [clientBundleConfig, serverBundleConfig];
and
// webpack.config.vendor.js
var isDevBuild = process.argv.indexOf('--env.prod') < 0;
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var extractCSS = new ExtractTextPlugin('vendor.css');
module.exports = {
resolve: {
extensions: ['', '.js']
},
module: {
loaders: [
{ test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, loader: 'url-loader?limit=100000' },
{ test: /\.css(\?|$)/, loader: extractCSS.extract(['css']) }
]
},
entry: {
vendor: [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router',
'#angular/platform-server',
'angular2-universal',
'angular2-universal-polyfills',
'bootstrap',
'bootstrap/dist/css/bootstrap.css',
'es6-shim',
'es6-promise',
'jquery',
'zone.js',
'angular2-modal'
]
},
output: {
path: path.join(__dirname, 'wwwroot', 'dist'),
filename: '[name].js',
library: '[name]_[hash]',
},
plugins: [
extractCSS,
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.DllPlugin({
path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
name: '[name]_[hash]'
})
].concat(isDevBuild ? [] : [
new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } })
])
};
It seems like you are using style-loader to load your component css. You can change it to be the same loader (most likely file-loader) as the vendor.css in your webpack.config
If you compare the two css loaders in your config files, you can see that webpack.config.vendor.js has this line:
{ test: /\.css(\?|$)/, loader: extractCSS.extract(['css']) }
under loaders. That is the line that takes the CSS and puts it in its own file. So if you change the CSS loader for your webpack.config.js and make sure to add:
var extractCSS = new ExtractTextPlugin('styles.css'); // or name it whatever you want
at the top of the file. It should work.