Load images in React using webpack loader - reactjs

I am unable to display images within a React component. After many trials (attempted this, this, this, this, this, this, this and this) and only errors, I am requesting for help. I'm in the development build (not production build).
I still get this error:
Module parse failed: /project/src/images/net.png Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
Component
import thumbnail from '../images/net.png';
<img src={thumbnail}/>
Webpack config:
devtool: 'cheap-module-eval-source-map',
entry: [
'eventsource-polyfill',
'webpack-hot-middleware/client',
'./src/index'
],
target: 'web',
output: {
path: path.resolve(__dirname, 'dist'),
task `npm run build`.
publicPath: 'http://localhost:3000/',
filename: 'bundle.js'
},
devServer: {
contentBase: './src'
},
plugins: [new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin()],
module: {
rules: [
{
test: /\.js$/,
include: path.join(__dirname, 'src'),
loader: 'babel-loader'
},
{
test: /(\.css)$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { sourcemap: true }
}
]
},
{
test: /\.(svg|png|jpg|jpeg|gif)$/,
include: './src/images',
use: {
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
outputPath: paths.build
}
}
}
]
}
Directory Structure
Project
-- src
-----components
-----images
-----index.js
How can I display the image ?
Sample code here: githublink
See /src/components/home/HomePage.js
What can I do to see the image on the home page ?

Have you tried this webpack configuration
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}

I am using url-loader instead.
{
test: /\.(png|jpg)$/,
use: {
loader: 'url-loader',
options: {
limit: 25000 // Max file size = 25kb
}
}
}
I am not sure. But, I think you should install it first as devDependencies e.g. yarn add -D url-loader.

test: /\.(jpe|jpg|woff|woff2|eot|ttf|svg)(\?.*$|$)/,
Try using this with your file-loader loader.
notice the (?.*$|$) instead of a plain $.

{
test: /.(png|jp(e*)g|svg|gif)$/,
use:[{
loader: 'url-loader?limit=8192'
}]
}
I loaded png with url-loader instead inside webpack. You need to rebuild webpack as well.

Related

Module parse failed getting error in webpack

I am working on webpack in react, when i run this command npx webpack --config webpack.config.js , i am getting below error
ERROR in ./node_modules/react-toastify/dist/ReactToastify.css 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
here i have attached my webpack.config.js , can anyone please help me why i am getting this error ?
const path = require('path')
module.exports = {
entry: path.resolve(__dirname, 'src', 'index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(jsx|js)$/,
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {
presets: [
['#babel/preset-env', {
"targets": "defaults"
}],
'#babel/preset-react'
]
}
}]
}
]
}
}
You'll need to install style-loader and css-loader:
npm install --save-dev style-loader css-loader
Then add the loaders to your webpack config. For example:
webpack.config.js
const path = require('path')
module.exports = {
entry: path.resolve(__dirname, 'src', 'index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(jsx|js)$/,
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {
presets: [
['#babel/preset-env', {
"targets": "defaults"
}],
'#babel/preset-react'
]
}
}]
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
}
]
}
}
Try adding
"babel": { "presets": ["#babel/preset-env"] }
To the end of your package.json file - after devDependencies (you may need to add #babel/preset-env via Yarn as well.)

Webpack doesn't create right paths for images in production css file

To add images into the project i'm using content: url() css property inside sass file and specify relative path to src folder e.g. content: url('/images/right-arrow.svg');.
The problem is that in production build i need to get rid of the first slash to have such path ('images/right-arrow.svg') inside of a bundled css file.
The only way i could get desired behaviour is to use url: false option for css-loader, and writing path without slash in sass file: content: url('/images/right-arrow.svg'), but such option don't add necessary file from node_modules e.g. fonts and images.
Webpack Config:
return {
entry: ['babel-polyfill', './src/app.js'],
output: {
path: path.join(__dirname, 'public/'),
filename: '[name].[hash].js',
},
mode: isProduction || 'development',
module: {
rules: [
{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
},
{
test: /\.s?css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
{
loader: 'css-loader',
options: {
url: true
}
},
'sass-loader'
]
},
{
test: /\.(svg|gif|png)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images'
}
}
},
{
test: /\.(otf|woff2|ttf|eot|woff)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
}
]
}
What am i missing in webpack config to achieve paths to work correcty?
Ok, I've solved the issue. I was using resolve-url-loader with no results, before #Ujin suggested to use it. After his comment I've clarified what resolve-url-loader does and cofigured it propertly to solve my issue. The main problem is that I've missed to read important paragraph of resolve-url-loader docs, which says:
source-maps required for loaders preceding resolve-url-loader (regardless of devtool).
Also I didn't use root option of resolve-url-loader plugin. So, webpack config for .scss files looks like this:
test: /\.s?css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
{
loader: 'resolve-url-loader',
options: {
root: path.join(__dirname, 'src')
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
sourceMapContents: false
}
}
]
}
Check the documentation about problems with url(...).
It suggests using resolve-url-loader.
Also you can try to use copy-webpack-plugin

Cannot import semantic-ui-css

when I import the semantic ui react css module in my index.js file I get the following error.
ERROR in ./~/semantic-ui-css/themes/default/assets/fonts/brand-icons.svg
Module parse failed: C:\Users\dimal\Documents\Work\sample-app\node_modules\semantic-ui-css\themes\default\assets\fonts\brand-icons.svg Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| <?xml version="1.0" standalone="no"?>
| <!--
| Font Awesome Free 5.0.8 by #fontawesome - https://fontawesome.com
# ./~/css-loader!./~/semantic-ui-css/semantic.min.css 7:196806-196862
# ./~/semantic-ui-css/semantic.min.css
# ./src/index.js
My webpack config is as following
var path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'index.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
exclude: /(node_modules|bower_components|build)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
},{
test: /\.(css|less)$/,
use: ["style-loader", "css-loader", "less-loader"]
}]
},
externals: {
'react': 'commonjs react'
}
};
What am I doing wrong in this?
The semantic UI CSS file has references to other files like images and fonts, so webpack has to have loaders for those types of files as well.
Ensure you have url-loader and file-loader packages installed and add these loaders to your webpack config:
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve("url-loader"),
options: {
limit: 10000,
name: "static/media/[name].[hash:8].[ext]",
},
},
{
test: [/\.eot$/, /\.ttf$/, /\.svg$/, /\.woff$/, /\.woff2$/],
loader: require.resolve("file-loader"),
options: {
name: "/static/media/[name].[hash:8].[ext]",
},
}
(you can change the folder path as you desire)

How to get Images from bundled app

I have a bundled app with webpack with this script. This script alsa exports files as well.
I import this app from another app. The bundled app works pretty well inside the paretn app but I couldn't find how to display and use this exported images in the parent app. They aren't shown. My guess is webpack doesn't see the images as module.
module.exports = {
devtool: 'source-map',
entry: './src/App.js',
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js',
libraryTarget: 'commonjs2'
},
plugins: commonConfig.plugins.concat([
new webpack.optimize.OccurrenceOrderPlugin()
]),
resolve: commonConfig.resolve,
module: {
rules: commonConfig.module.rules.concat({
test: /\.less$/,
use: [
'style-loader',
'css-loader?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!postcss-loader',
'less-loader'
]
})
},
externals: {
'react': 'commonjs react'
}
};
The solution I found for now is include images (small svg and png files) to bundle with this kind of configs. it may be a better solution with code splitting.
{
test: /.*\.(svg)$/i,
include: path.resolve(mainPath, 'ui/svg/inline'),
use: "svg-inline-loader"
},
{
test: /.*\.(svg)$/i,
include: path.resolve(mainPath, 'ui/svg/default'),
use: {
loader: "url-loader",
options: {
limit: 100000
}
}
},

Using multiple Webpack loaders to transform SVGs into React components

I am trying to combine several Webpack loaders together to load my SVG assets, transform them for inline usage and finally to convert the result into an actual React component that can be used in the application.
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.jsx?$/,
include: path.resolve(__dirname, 'src'),
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
browsers: supportedBrowsers,
modules: false
}]
]
}
}
},
{
test: /\.svg$/,
include: path.resolve(__dirname, 'src'),
use: [
{
loader: 'svg-inline-loader',
options: {
removeTags: true
}
},
{
loader: 'svg-react-loader'
}
]
}
]
}
}
If svg-react-loader is used on it's own the loader works as expected, however a lot of SVG assets have unneeded elements and attributes I would like to strip out using svg-inline-loader.
When the configuration is used as above the result will be loaded as text instead of executable JavaScript.
I am using the following loaders in my attempt to accomplish this:
https://github.com/webpack-contrib/svg-inline-loader
https://github.com/jhamlet/svg-react-loader
Would it be ok to use other loaders? You can combine svgo-loader with svg-inline-loader and use all the possible options provided by svgo.
If so just do npm i -D svgo-loader
And change your webpack config to this:
{
test: /\.svg$/,
use: [
'svg-react-loader',
{
loader: 'svgo-loader',
options: {
plugins: [
{cleanupAttrs: true}
]
}
}
],
exclude: /node_modules/
}

Resources