Images are loaded in external library, how to load them with webpack?

Viewed 1231

first and foremost I need to say that I know little of fundamentals of Webpack, and this is probably why I can't find a solution.

So I know in order to load images I need to require a path instead of just typing it as a string require('path/to/image')

Then I got an external library where I need to pass a path property, where lay multiple images. It doesn't seem to work, so how can I load them into my website?

 <CountrySelect
    multi={false}
    flagImagePath="../../../public/flags/" //folder with multiple images
  />

Webpack config:

const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');
 const CleanWebpackPlugin = require('clean-webpack-plugin');

 const outputDirectory = 'dist';

module.exports = {
  entry: './src/client/index.js',
  output: {
    path: path.join(__dirname, outputDirectory),
    filename: 'bundle.js',
    publicPath: '/',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.(png|woff|woff2|eot|ttf|svg|jpg|jpeg)$/,
        loader: 'url-loader?limit=100000'
      }
    ]
  },
  devServer: {
    historyApiFallback: true,
    port: 3000,
    open: true,
    proxy: {
      '/api': 'http://localhost:8080'
    }
  },
  plugins: [
    new CleanWebpackPlugin([outputDirectory]),
    new HtmlWebpackPlugin({
      template: './public/index.html',
      favicon: './public/favicon.ico'
    })
  ]
};
2 Answers

image-webpack-loader - automatically reduces/compress the bigger image.

url-loader - if image size is small it will included as part of bundle.js otherwise separate directory is created and images are placed inside of it.

npm install --save-dev image-webpack-loader url-loader file-loader

webpack.config.js

const config = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'bundle.js',
    publicPath: 'build/' //This is important to load your images.
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          { loader: 'babel-loader' },
        ]
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
         test: /\.(gif|png|jpe?g|svg)$/i,
         use: [
           {
              loader: 'url-loader',
              options: { limit: 40000 } //if image of size lessthan 40kb include it in bundle.js
           },
           'image-webpack-loader'
         ]
      }
    ]
  }
}

Sample Code.

import big from '../images/big.jpg';
import small from '../images/small.png';

const image = document.createElement('img');
image.src = small;

document.body.appendChild(image);


const bigimage = document.createElement('img');
bigimage.src = big;

document.body.appendChild(bigimage);

you can learn more about webpack from Handling Images with Webpack.

I solved the problem by using CopyWebpackPlugin.

plugins: [
   new CleanWebpackPlugin([outputDirectory]),
   new HtmlWebpackPlugin({
     template: './public/index.html',
     favicon: './public/favicon.png'
   }),
   new CopyWebpackPlugin([{ from: './public/flags', to: 'flags', toType: 'dir' 
   }]),
]

and in CountrySelect:

flagImagePath="/flags/"

So that in the time of production, where static directory is dist, flags are derived from dist directory.

Related