Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use images from sharp module in React and Webpack project

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

like image 634
Sam Avatar asked May 10 '21 19:05

Sam


People also ask

Can I use images in my react and typescript app?

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:

What are the basics of Webpack for react?

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:

How do I include an image in a react app?

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 }) => (

How do I add an image to a Webpack module?

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.)


Video Answer


2 Answers

You will need to make some changes:

Webpack.config.js

  1. Move 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

  1. The 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>
  );
}
like image 88
lissettdm Avatar answered Oct 25 '22 00:10

lissettdm


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) => { });
like image 20
MHIdea Avatar answered Oct 25 '22 00:10

MHIdea