Inline image loading..webpack - reactjs

I am pulling my hair off...
Feels like I have tried everything.
This is my webpack config:
var publicConfig = {
context: path.join(__dirname, 'src'),
entry: [
'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000',
'./public.jsx',
],
output: {
path: path.join(__dirname, 'app'),
filename: 'publicBundle.js',
publicPath: '/assets/',
},
module: {
loaders: [
{ test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'},
//{ test: /\.css$/, loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]' },
// { test: /\.css$/, loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]' },
{ test: /\.css$/, loader: "style!css" },
{
test: /\.(jpg|png)$/,
loader: 'url?limit=25000'
},
{ test : /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/, loader : 'file-loader' }
]
},
resolve: {
extensions: ['', '.js', '.jsx', '.json']
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
};
When defining images in my css files the images gets added to the /assets/ folder, which is exactly what I want... However, I want to be able to call image paths from inline ( the html views aswell ). But the images doesnt get copied to /assets/ unless I target them from my css file.
I tried importing them by:
import logo from './images/animus_logo_blacktext.png'
But it still doesnt appear in my assets.
What is the best practice for image paths inline?

Is it possible the images are very small? The limit you configured in URL-loader means that all images under 25000 bytes will be inlined (as data URI's) instead of served as a file. Files larger than 25000 bytes will be treated by url-loader the same way file-loader treats them.

I think you want to try https://www.npmjs.com/package/copy-webpack-plugin. This is a webpack plugin that copies individual files or entire directories to the build directory.

Switch to the file-loader instead of the url loader. The images may be under your limit of 25000 (25kb).
Without modifying your webpack configuration you could try this:
import logo from 'file-loader!./images/animus_logo_blacktext.png'
You should see the image in your assets.

Related

Load images in React using webpack loader

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.

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
}
}
},

webpack file-loader options aren't recognized

Being new to webpack, the answer might be staring me down but I don't see it. No matter how I try to pass them along, the file-loader options aren't found.
I'm using file-loader and I'm trying to pass a publicPath (or simply anything, at first) along as an option. I went into the file loader source code and added a log for all the options it detected, but they always come up empty.
webpack.config.prod.js
var path = require('path')
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: [
'./src/index.js'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'idlink-1.1.1.js',
publicPath: ''
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.DefinePlugin({'process.env.NODE_ENV': '"production"'})
],
module: {
loaders: [
{
exclude: /node_modules/,
loader: 'babel',
query: { presets: ['react', 'es2015', 'stage-1'] }
},
{test: /\.css$/, loader: "style-loader!css-loader" },
{test: /\.scss$/, loaders: ["style", "css", "sass"]},
{test: /\.less$/, loader: "style-loader!css-loader!less-loader" },
{
test: /\.(jpe?g|png|gif|svg|pdf)$/i,
loader: "file",
options: { publicPath: 'https://apps.ixordocs.be/'}
},
{test: /\.gif$/, loader: "url-loader?mimetype=image/png" }
]
},
}
I've also tried with
loader: "file-loader"
as well as added the options as one string like this
loader: "file?name=[name].[ext]&publicPath=https://apps.ixordocs.be/"
Some context info:
I don't want to have a hardcoded publicPath defined in my output: {}, i want to grab it dynamically from a parameter placed on the div that my plugin is loaded into.
I've tried using the __webpack_public_path__ variable and it works, but not for images. The public path is grabbed from the parameter, set, and used to fetch a chunk. Somehow it has no effect on images though. If I hardcode a publicPath under output, it DOES work for images. This leads me to believe there is a problem with the loader's communication to the variable, so the idea is to get the options working and eventually try to pass a dynamic publicPath in there.
Your question is totally valid based on the documentation of the loader on both loader's GitHub repo and webpack docs. The problem is the publicPath and outputPath features are implemented in a pull request that is merged but not yet released to a new version of loader, and the README on npm doesn't mention the features for the same reason.
You can still use these features by installing from the GitHub repo with npm install webpack/file-loader --save-dev and your options should work. If not try replacing options with query.
{
test: /\.(jpe?g|png|gif|svg|pdf)$/i,
loader: "file-loader",
query: { publicPath: 'https://apps.ixordocs.be/'}
}
Using URLs for publicPath is also valid because it happens often that you want to load your assets from a CDN or another server.

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"
}
]
}
};

require is working jsx file but url() resolve is not wroking in sass file - webpack

I am facing this strange issue with Webpack. After spending hours couldn't find solution.
In my jsx file when I a try to set image source via this
let img = require('../../../img/imgN.png');
It is working perfectly but when I try to set the background image using scss via
$bg-img: url('../img/bg-img.png');
Image is not getting loading by webpack.
This is my webpack file
module.exports = {
devtool: 'source-map',
entry: {
main: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
'./src/index.js'
]
},
output: {
path: path.join(__dirname, 'public'),
publicPath: '/public/',
filename: 'bundle.js'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [
{
test: /\.jsx?$/,
include: path.join(__dirname, 'src'),
loader: 'react-hot!babel'
},
{
test: /\.scss$/,
include: path.join(__dirname, 'sass'),
loaders: ["style", "css?sourceMap", "sass?sourceMap"]
},
{
test: /\.(png|jpg)$/,
include: path.join(__dirname, 'img'),
loader: 'url-loader?limit=30000'
} // inline base64 URLs for <=30k images, direct URLs for the rest
]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
historyApiFallback: true,
contentBase: './'
}
}
Problem was occurring because of using sourceMap with style-loader.
There is some issue on github for the same problem.
Solution:
1 . While source-maps is enabled
Style-loader uses a Blob, so it requires absolute urls to work.
Changed publicPath: '/public/', to
publicPath: 'http://localhost:8080/public/',
It worked.
Without source-maps
Just remove source map from style loaders.
Now style-loader will use an inline style tag, so there is no problem.
{
test: /\.scss$/,
include: path.join(__dirname, 'sass'),
loaders: ["style", "css", "sass"]
},
Can you try to see if $bg-img: url('~/img/bg-img.png'); would work? When I was trying out webpack in my bootstrap.scss files I had to modify the font url's using ~ (I think I read it somewhere but ya just giving you something to try)

Resources