Here is a codesandbox I would like the image in it to be processed by the sharp module. I want it to do this because I want this module to web optimize all the images in my React project, and to convert them to webm.
Here's the same codesandbox where I attempt to use ImageSharp
In the last post, we added CSS to our Webpack configuration for our React and TypeScript app. In this post, we will extend this Webpack configuration so that images can be used in the app. If we run the app in dev mode ( npm start ), we see that the image isn’t found:
In this tutorial we will see the basics of Webpack for React to get you started, including React Router, Hot Module Replacement (HMR), Code Splitting by Route and Vendor, production configuration and more. Before we start, here’s the full list of features we are going to set up together in this tutorial:
For instance, in React you can include an image the following way by using an img HTML element and its src attribute: import React from 'react'; import MyImage from './assets/images/myimage.jpg'; const App = ({ title }) => (
Base on the publicPath in your webpack.config Check the example1 from my repo. 2. Use the url-loader and html-loader, then load the image synchronously The image will be encoded into base64 string, and insert into your module. (So it will be loaded synchronously.)
You will need to make some changes:
Webpack.config.js
sharp-loader
to rules
:const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
module: {
rules: [
...
{
test: /\.(gif|jpe?g|png|svg|tiff)(\?.*)?$/,
loader: "sharp-loader",
query: {
name: "[name].[hash:8].[ext]",
cacheDirectory: true,
presets: {
// Preset 1
thumbnail: {
format: ["webp", "jpeg"],
width: 200,
quality: 60
},
// Preset 2
prefetch: {
// Format-specific options can be specified like this:
format: { id: "jpeg", quality: 30 },
mode: "cover",
blur: 100,
inline: true,
size: 50
}
}
}
}
]
},
devServer: {
...
},
plugins: [
...
]
};
If you are using Webpack 5:
Rule.query is deprecated in favor of Rule.options and UseEntry.options.
Home.js
sharp-loader
will transform logo into an array of one object because of this "outputs":[{"width": 500}]
. You will need to use the corresponding object:import React from "react";
import logo from '../../react-logo.png?{"outputs":[{"width": 500}]}';
export default function Home() {
return (
<div>
<h2>Home</h2>
<img src={logo[0].url} />
</div>
);
}
If you are using require.context
it works the same way:
import React from "react";
function importAll(r) {
return r.keys().reduce((curr, key) => ((curr[key] = r(key)), curr), {});
}
const images = importAll(require.context('./images/?{"outputs":[{"width": 200}, {"width": 150}]}', true, /\.png$/));
export default function Home() {
return (
<div>
<h2>Home</h2>
<img src={images['./react-logo.png'][0].url} />
</div>
);
}
I would create a convert.js in root directory to do the file conversion. check sharp docs.
Then in package.json simply add 'node convert' before any script which needs image conversion specially start and build
"start": "node convert && react-scripts start",
"build": "node convert && react-scripts build",
Now any time you start local server or build your app, it first converts the images and then does the rest.
Here is a simple example where convert.js only converts a file named 1.jpeg to output.webp with dimension 320x240. It's all up to you how you like to organize image sizes, folders and files in project so that covert.js can find them and properly convert them.
const sharp = require('sharp');
sharp('1.jpeg')
.resize(320, 240)
.toFile('output.webp', (err, info) => { });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With