My team moved all the images of company website into a CDN. (https://cdn.irobo.co.kr/images)
However, I'd like to use those images without changing current code base, which has a lot of: (reactjs code)
<image src={require('img/common/logo.jpg')} />
here's the webpack config for the website:
{
module: {
loaders:[{
test: /\.(png|jpg)$/,
loader: 'file-loader?name=[name].[ext]',
}],
}
...
resolve: {
alias: {
img: path.join(srcPath, 'app/img'),
}
}
}
Here's what I tried:
...
resolve: {
alias: {
img: 'https://cdn.irobo.co.kr/images',
}
}
}
Bundling assets from external urls with Webpack
The url-loader plugin for webpack gives you the ability to take use assets from external url by encoding them in base64.
The url loader works like the file loader, but can return a Data Url
if the file is smaller than a byte limit.
The limit can be specified with a query parameter. (Defaults to no
limit)
Remember to install the url-loader plugin as a project dependency.
npm install --save-dev url-loader
Configure the url-loader plugin
Here is a sample webpack config to set up the url-loader plugin.
webpack.config.js
module.exports = {
entry: './main.js',
output: {
path: './build', // This is where the images and js will go
publicPath: 'http://mycdn.com/', // used to generate URLs to e.g. images
filename: 'bundle.js'
},
module: {
loaders: [
// use ! to chain loaders
{ test: /\.less$/, loader: 'style-loader!css-loader!less-loader' },
{ test: /\.css$/, loader: 'style-loader!css-loader' },
// inline base64 URLs for <=8k images, direct URLs for the rest
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
]
}
};
Import the assets in your app
app.jsx
import image from '../build/image.jpg';
<img src={image} />
Related
I'm loading icons on my app.js
import bg from './icons/bg.png';
import br from './icons/br.png';
import rg from './icons/rg.png';
import ig from './icons/invert.png';
import bw from './icons/bw.png';
import by from './icons/by.png';
import gm from './icons/gm.png';
import rs from './icons/rs.png';
They work fine when i run the default react start script, but when i try to compile using this webpack:
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/js/index.js',
devtool: 'inline-source-map',
target: 'electron-renderer',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [[
'#babel/preset-env', {
targets: {
esmodules: true
}
}],
'#babel/preset-react']
}
}
},
{
test: [/\.s[ac]ss$/i, /\.css$/i],
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
}
]
},
resolve: {
extensions: ['.js'],
},
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'build', 'js'),
},
};
I get this errors for each image:
ERROR in ./src/js/icons/bg.png 1:0
Module parse failed: Unexpected character '�' (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
(Source code omitted for this binary file)
# ./src/js/App.js 2:0-32 230:9-11
# ./src/js/index.js 4:0-24 5:107-110
Which provably means that babel is trying to load the image as a javascript file, is there a way to load a image on React when compiling it with Babel?
As mentioned in webpack docs
Out of the box, webpack only understands JavaScript and JSON files.
So you need to use loader for png file as webpack don't know what to do with that file.
file-loader
More on Loaders
I have a common use case to load a spinner in the component. This is my folder structure.
src
/components
/table
-Table.js
-Spinner.js
I import spinner like this
const spinner = require('./spinner.gif');
When I console log spinner I got this
And call that in the component like this
<img src={spinner} alt='Data is loading...' />
But gif image is not loading. Instead I am getting the alt text.
How do I fix this with React?
My answer follows the documentation on webpack
In your folder add a package for image loader
npm install --save-dev file-loader
Then change your webpack.config.js or any other named config file as below.
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
],
},
// Added below -----------
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
],
},
// Added above ---------------
],
},
};
Then you can import images as usual by doing
import image from './image.gif';
Or
const image = require('./image.gif')
I am building a simple React app from scratch using Webpack.
I was finally able to run the dev server and when I tried to apply some styles via CSS, the files wouldn't load and I assume my Webpack 4 configuration is not right.
Here is the code:
webpack.config.js
// const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require('path');
module.exports = {
mode: 'development',
entry: ['./src/index.js'],
resolve: {
extensions: [".js", ".jsx"]
},
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist',
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 8080
},
module: {
rules: [
{
test: /\.js|.jsx$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: ["react"]
}
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.(png|jpg)$/,
loader: 'url-loader'
}
]
},
};
My project structure is like this, I will include only src because it lives in the root:
**src**
|_assets
|_componentns
|_styles
|_App.css
|_index.css
App.jsx
index.js
index.html
I would like to be able to add multiple css files for each component I have and apply them, and to be able to style the index the index.html.
Thank you very much for your help.
Your webpack configuration looks fine.
make sure you import the required css files in your components.
import "./App.css";
class App extends Component {
render() {
return (
<div>
<Child />
</div>
);
}
}
All you have to do is import the CSS files when needed as you would a JavaScript module. So if you want to have a style sheet for your whole application, you can import a global stylesheet in your index.js.
import './styles/index.css';
and you can do the same for each component with specific styles
import './styles/App.css'
in which case you might want to setup CSS modules to avoid overlapping class names.
Ok, rookie mistake here, the way I ahve set up webpack is I have to build it first and then run the dev server, no the other way around.
All answers above are valid and helpful, I just forgot to run build after changes.
I have a fairly basic webpack setup that runs babel and out comes my minified js with a source map.
Now when I run my source map in chrome I get the js before babel and before minification. However I would often like to have my source map after babel but before minification. Is this possible?
TL;DR I want source map to post-babel pre-minifcation. Possible?
For completeness
I run babel-loader 8 with webpack 4
Here is a screenshot from chrome showing the problem. As you can see the Dropzone tag indicates this is jsx (and so before babel)
Secondly here is my webpack config (not that it actually matters for my question).
const path = require('path');
module.exports = {
context: path.join(__dirname, 'Scripts', 'react'),
entry: {
client: './client'
},
output: {
path: path.join(__dirname, 'Scripts', 'app'),
filename: '[name].bundle.min.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: [require('#babel/plugin-proposal-object-rest-spread')],
presets: ["#babel/es2015", "#babel/react", "#babel/stage-0"]
}
}
}
]
},
resolve: {
extensions: ['.js', '.jsx']
},
externals: {
// Use external version of React (from CDN for client-side, or
// bundled with ReactJS.NET for server-side)
react: 'React'
},
devtool: 'source-map'
};
Running webpack with -d gives a second set of source maps in chrome that does the trick.
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
}
}
},