Why i get hashed .jpeg file when running 'npm run build' with webpack - reactjs

Im a new beginner on develop react app.
Im trying to figure out how to set up my webpack.config.js file.
I have following ended up with this structure as you can see on the picture link below.
My question is: When im running 'npm run build' , its hashing the picture and put it into the /dist folder. How can i configure so it does not?
Because im using copyWebpackPlugin() to copy my images and push it to the dist folder, but i dont want the picture which i marked with arrow.
If anyone have some advice just bring it on.
This is how my webpack.config.js file look like:
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
module.exports = {
entry: "./src/index.js",
mode: "development",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader"
},
{
test: /\.s?css$/,
loader: ["style-loader", "css-loader"]
},
{
test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
loader: "url-loader?limit=100000"
}
]
},
resolve: { extensions: [".js", ".jsx"] },
output: {
path: path.resolve(__dirname, "dist/"),
filename: "bundle.js"
},
devtool: "cheap-module-eval-source-map",
devServer: {
contentBase: path.join(__dirname, "public/"),
proxy: {
"/api/*": {
target: "http://localhost:3000/",
secure: "true"
}
},
port: 4000,
publicPath: "http://localhost:4000/dist/",
hotOnly: true,
historyApiFallback: true
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin(["dist"]),
new HtmlWebpackPlugin({
filename: "index.html",
template: "./public/index.html"
}),
new CopyWebpackPlugin([{ from: "public/images", to: "images" }])
]
};

I would suggest instead of copy-webpack-plugin use file-loader to copy images
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [{
loader: 'file-loader',
options: {
name: 'images/[name].[ext]',
}
}]
}
if you want hash instead of name
name: 'images/[hash].[ext]',
Package
npm install --save-dev file-loader

It is because the url-loader has a default fallback to file-loader. So if your image is bigger than the limit you have set for url-loader, it does not rewrite the image to base64 data:image in your css, instead gives it to file-loader and it copies that image to your dist folder (output path).
So if you do not want this, disable the fallback option for url-loader
But I also think you should have configure your webpack to copy the files with file-loader properly instead that copy plugin. But you know...
I would give you an example based on your config but I am currently on mobile so I can't code right now.

Related

Why does %PUBLIC_URL% not get replaced in Webpack bundled index.html?

I am trying to deploy the front-end of my web application, but when I deploy to my hosting platform (currently AWS Amplify/S3) - no content displays on the website
I created the application using create-react-app, so the project structure follows their standard (public, src folders etc.).
When I run the application locally it works fine.
From the console errors, and looking at the index.html page that is generated by webpack, it looks like it is not replacing the %PUBLIC_URL% field that should be replaced with the public directory on build.
Please can someone explain how to fix this issue?
I have included my webpack.config file below and the full repo can be found here
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const config = {
entry: ['react-hot-loader/patch', './src/index.js'],
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.svg$/,
use: 'file-loader',
},
{
test: /\.png$/,
use: [
{
loader: 'url-loader',
options: {
mimetype: 'image/png',
},
},
],
},
{
test: /\.(ttf|eot|woff|woff2)$/,
use: 'file-loader',
},
],
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
'react-dom': '#hot-loader/react-dom',
},
},
devServer: {
contentBase: './build',
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve('./public/index.html'),
}),
],
}
module.exports = config
Turns out this was an issue with me trying to add a custom Webpack configuration to a create-react-app project.
I've removed the Webpack config now, and instead used the dist files created when using the create-react-app build process.

Images are loaded in external library, how to load them with webpack?

first and foremost I need to say that I know little of fundamentals of Webpack, and this is probably why I can't find a solution.
So I know in order to load images I need to require a path instead of just typing it as a string require('path/to/image')
Then I got an external library where I need to pass a path property, where lay multiple images. It doesn't seem to work, so how can I load them into my website?
<CountrySelect
multi={false}
flagImagePath="../../../public/flags/" //folder with multiple images
/>
Webpack config:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const outputDirectory = 'dist';
module.exports = {
entry: './src/client/index.js',
output: {
path: path.join(__dirname, outputDirectory),
filename: 'bundle.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|woff|woff2|eot|ttf|svg|jpg|jpeg)$/,
loader: 'url-loader?limit=100000'
}
]
},
devServer: {
historyApiFallback: true,
port: 3000,
open: true,
proxy: {
'/api': 'http://localhost:8080'
}
},
plugins: [
new CleanWebpackPlugin([outputDirectory]),
new HtmlWebpackPlugin({
template: './public/index.html',
favicon: './public/favicon.ico'
})
]
};
image-webpack-loader - automatically reduces/compress the bigger image.
url-loader - if image size is small it will included as part of bundle.js otherwise separate directory is created and images are placed inside of it.
npm install --save-dev image-webpack-loader url-loader file-loader
webpack.config.js
const config = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
publicPath: 'build/' //This is important to load your images.
},
module: {
rules: [
{
test: /\.js$/,
use: [
{ loader: 'babel-loader' },
]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
{
loader: 'url-loader',
options: { limit: 40000 } //if image of size lessthan 40kb include it in bundle.js
},
'image-webpack-loader'
]
}
]
}
}
Sample Code.
import big from '../images/big.jpg';
import small from '../images/small.png';
const image = document.createElement('img');
image.src = small;
document.body.appendChild(image);
const bigimage = document.createElement('img');
bigimage.src = big;
document.body.appendChild(bigimage);
you can learn more about webpack from Handling Images with Webpack.
I solved the problem by using CopyWebpackPlugin.
plugins: [
new CleanWebpackPlugin([outputDirectory]),
new HtmlWebpackPlugin({
template: './public/index.html',
favicon: './public/favicon.png'
}),
new CopyWebpackPlugin([{ from: './public/flags', to: 'flags', toType: 'dir'
}]),
]
and in CountrySelect:
flagImagePath="/flags/"
So that in the time of production, where static directory is dist, flags are derived from dist directory.

Webpack production build file paths are off

I'm running this command to try & generate a production webpack build:
rimraf ./build/* && webpack -p --progress --config webpack.production.js
However, when I open up the build/index.html, it's failing to load a lot of files because the locations are off.
It fails to put the correct location for the bundle.js file. It loads it like this: /bundle.js. However the bundle.js file is actually in the same directory as the index.html file in the build folder so it should load it like this ./bundle.js
If I correct the bundle.js path, it's still putting an incorrect route for the assets:
What's interesting is that my app currently works with the webpack dev server when I run: webpack-dev-server --inline --progress --config webpack.dev.js.
Here is what my current webpack.production.js file looks like:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'source-map',
devServer: {
historyApiFallback: true, // This will make the server understand "/some-link" routs instead of "/#/some-link"
},
entry: [
'./src/scripts' // This is where Webpack will be looking for the entry index.js file
],
output: {
path: path.join(__dirname, 'build'), // This is used to specify folder for producion bundle
filename: 'bundle.js', // Filename for production bundle
publicPath: '/'
},
resolve: {
modules: [
'node_modules',
'src',
path.resolve(__dirname, 'src/scripts'),
path.resolve(__dirname, 'node_modules')
], // Folders where Webpack is going to look for files to bundle together
extensions: ['.jsx', '.js'] // Extensions that Webpack is going to expect
},
module: {
// Loaders allow you to preprocess files as you require() or “load” them.
// Loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle frontend build steps.
loaders: [
{
test: /\.jsx?$/, // Here we're going to use JS for react components but including JSX in case this extension is preferable
include: [
path.resolve(__dirname, "src"),
],
loader: ['react-hot-loader']
},
{
loader: "babel-loader",
// Skip any files outside of your project's `src` directory
include: [
path.resolve(__dirname, "src"),
],
// Only run `.js` and `.jsx` files through Babel
test: /\.jsx?$/,
// Options to configure babel with
query: {
plugins: ['transform-runtime'],
presets: ['es2015', 'stage-0', 'react'],
}
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(), // Webpack will let you know if there are any errors
// Declare global variables
new webpack.ProvidePlugin({
React: 'react',
ReactDOM: 'react-dom',
_: 'lodash'
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
hash: true
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
]
}
And just in case, this is what my current webpack.dev.js file looks like:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'cheap-module-source-map',
devServer: {
historyApiFallback: true, // This will make the server understand "/some-link" routs instead of "/#/some-link"
},
entry: [
'babel-polyfill',
'webpack-dev-server/client?http://127.0.0.1:8080/', // Specify the local server port
'webpack/hot/only-dev-server', // Enable hot reloading
'./src/scripts' // This is where Webpack will be looking for the entry index.js file
],
output: {
path: path.join(__dirname, 'build'), // This is used to specify folder for producion bundle
filename: 'bundle.js', // Filename for production bundle
publicPath: '/'
},
resolve: {
modules: [
'node_modules',
'src',
path.resolve(__dirname, 'src/scripts'),
path.resolve(__dirname, 'node_modules')
], // Folders where Webpack is going to look for files to bundle together
extensions: ['.jsx', '.js'] // Extensions that Webpack is going to expect
},
module: {
// Loaders allow you to preprocess files as you require() or “load” them.
// Loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle frontend build steps.
loaders: [
{
test: /\.jsx?$/, // Here we're going to use JS for react components but including JSX in case this extension is preferable
include: [
path.resolve(__dirname, "src"),
],
loader: ['react-hot-loader']
},
{
loader: "babel-loader",
// Skip any files outside of your project's `src` directory
include: [
path.resolve(__dirname, "src"),
],
// Only run `.js` and `.jsx` files through Babel
test: /\.jsx?$/,
// Options to configure babel with
query: {
plugins: ['transform-runtime', 'transform-decorators-legacy'],
presets: ['es2015', 'stage-0', 'react'],
}
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // Hot reloading
new webpack.NoEmitOnErrorsPlugin(), // Webpack will let you know if there are any errors
// Declare global variables
new webpack.ProvidePlugin({
React: 'react',
ReactDOM: 'react-dom',
_: 'lodash'
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
hash: false
})
]
}
Any ideas what I'm doing wrong?
faced a similar issue. setting output.publicPath: "/" in webpack.dev.js and output.publicPath: "./" in webpack.prod.js, did the trick for me.
Got the same error when running npm run watch, local dev still worked, but after deploying to demo server the app crashed on wrong js-file url.
Cause:
Some changes in my webpack.mix.js started compiling a index.html file that was found by the browser, instead of the app.blade I was using.
Fixed the paths by setting: publicPath: './public/'
(Note that it's a relative path). Also, I removed the generated url by setting inject: false, in the HtmlWebpackPlugin({ section and used the asset('/...') logic.

Webpack with babel-loader for react corrupts image files

I am using webpack with babel-loader to transform .jsx react files.
However, adding a file-loader or style- and css-loader does not correctly process the images required() in the react components or style sheets.
They get recognized by webpack and copied to the dist folder. The path to the image file is correct, I've verified this in the css and js output.
The server is also able to display the files, I've checked with some manually copied ones.
What is happening is that the images themselves get corrupted. No image viewer nor the browser can display the image which results in an invisible image in the browser.
What I've tried so far:
using only babel-loader as suggested in: https://github.com/webpack/file-loader/issues/35, results in Error: No handler for file type.
using file-loader directly
using image-webpack-loader (which seems to be using file-loader under the hood)
using IsomorphicLoaderPlugin (https://github.com/jchip/isomorphic-loader) which seems to be a simpler alternative to webpack-isomorphic-tools
using css background-images with url() and ExtractTextPlugin('style-loader", 'css-loader')
All of the above steps resulted in either errors with webpack not finding an appropriate handler or corrupted image files.
Here is my current webpack config for reference (I've included all of it in case there are any problems/conflicts I am overlooking):
var ExtractTextPlugin = require('extract-text-webpack-plugin'),
webpack = require('webpack');
IsomorphicLoaderPlugin = require("isomorphic-loader/lib/webpack-plugin");
module.exports = {
context: __dirname + '/client',
entry: ['babel-polyfill', './index.jsx'],
output: {
filename: 'app.js',
path: __dirname + '/dist',
publicPath: '/'
},
resolve: {
ignore: /node_modules/,
extensions: ['', '.js', '.jsx']
},
devtool: 'source-map',
plugins: [
new ExtractTextPlugin('styles.css'),
new IsomorphicLoaderPlugin({ keepExistingConfig: false }),
new webpack.DefinePlugin({
"process.env": {
BROWSER: JSON.stringify(true)
}
})
],
module: {
preLoaders: [
{
loaders: ['isomorphine']
}
],
loaders: [
{
test: /\.jsx?$/,
loader: 'babel',
exclude: /node_modules/,
query: {
cacheDirectory: true,
plugins: ['transform-runtime', 'transform-decorators-legacy', 'transform-class-properties', 'transform-object-rest-spread'],
presets: ['react', 'es2015', 'stage-0']
}
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: "file!isomorphic"
}
]
}
};

How to get sourcemaps working for React Css Modules?

I'm trying to setup a React project with react-css-modules, webpack and Hot Module Replacement. Everything is working like a charm but I can't get the CSS sourcemaps to work.
I followed this guide to make HMR work. It involves a BrowserSync setup to update the css file after Webpack writes it to disk.
I use (as suggested by react-css-modules) the ExtractTextPlugin to extract all of the css:
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style','css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass')
}
But if I change this to sourcemaps, as suggested here
loader: ExtractTextPlugin.extract('style', 'css?sourceMap!sass-loader outputStyle=expanded&sourceMap=true&sourceMapContents=true')
I get the error: "root" CSS module is undefined. in my browser console.
You can find my example repo here, but here's the full webpack config I'm using for development.
var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var WriteFilePlugin = require('write-file-webpack-plugin').default;
module.exports = {
entry: {
bundle: [
'webpack/hot/dev-server',
'webpack-hot-middleware/client',
'./index.js'
]
},
devtool: 'cheap-module-source-map',
debug: true,
devServer: devServer,
context: path.resolve(__dirname, './src'),
output: {
path: path.resolve(__dirname, './builds'),
filename: '[name].js',
publicPath: '/builds/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.OldWatchingPlugin(),
new WriteFilePlugin(),
new ExtractTextPlugin('[name].css', {
allChunks: true
})
],
module: {
loaders: [
{
test: /\.js$/,
loaders: ['react-hot', 'babel-loader'],
exclude: /node_modules/
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style','css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass')
}
]
},
resolve: {
extensions: ['', '.js', '.json']
}
};
How to make the sourcemap work?
Use this:
ExtractTextPlugin.extract('style','css?sourceMap&modules&importLoaders=1&localI‌​dentName=[name]__[local]___[hash:base64:5]!sass?sourceMap')
i.e. add the sourceMap param to both css & sass loaders. It said so in sass-loader docs.
This is how I have my css modules set up:
'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!',

Resources