How to Correctly Set Up Webpack Image Loader in your Node app

Home/Development/Javascript/How to Correctly Set Up Webpack Image Loader in your Node app

How to Correctly Set Up Webpack Image Loader in your Node app

Setting up your webpack.config.js file can be tediously complicated work. I stumbled upon this again myself as I was configuring my own webpack file to handle images. While I’ve been working with React, Node, and webpack for some time now, I’ll nevertheless run across issues that take me a while to fix. One common webpack error we can overcome through the use of the Webpack image loader. If you run across this error when you try to implement images into your project you’re in the right place:

Module parse failed: some\directory\some_image.jpg Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type.

This brief tutorial will help you get webpack.config.js set up with images then get you on your way much faster. So, if this error looks familiar, buckle up, and let’s get to work!

A brief summary of loaders

As described in the Webpack docs, a loader transforms files written in a specific programming language into JavaScript. In our case here, we can use a loader to take our images and make them available in our minified js file. Loaders have a wide variety of features that make them robust and powerful; they can be chained together, run synchronously or asynchronously, and even give other loaders more features, to name just a few of them.

Downloading the webpack image loader

We are going to be using webpack image loader to do the preprocessing of our images, but we’ll also need to make use of file-loader, so get them installed into your project:

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

The file-loader allows us to configure custom filename templates, which will be important when we start configuring our webpack.config file. Now that we have these installed and saved to our dev dependencies we can open our webpack.config file and add our image-webpack-loader to it.

One of the amazing things about image-webpack-loader is that it also does us the favor of compressing our images as well so that we are always delivering the smallest possible package to our clients.

Adding the loader to our webpack.config

The next part of the process involves telling Webpack to use the loader we just installed. So inside our webpack.config.js file let’s get started by importing webpack. At the top of your configuration make sure you have:

var webpack = require('webpack')

Underneath this let’s set up our module.exports, this is where we’ll be configuring webpack:

module.exports = {
  context: __dirname, 
  entry: "./src/index.js",
  module: {
    loaders: [
      //we'll add loaders here shortly
    ]
  },
  //your output, plugins, and devServer if applicable
};

This general layout should look familiar. Inside the module object you should already have a loader, much like the one below:

module: { 
  loaders: [ { 
    test: /\.js|.jsx?$/, 
    exclude: /(node_modules|bower_components)/, 
    loader: 'babel-loader', 
  } ] 
}

This loader is testing for files ending in .js and .jsx excluding anything in the “node modules” or “bower components” folders and is using the babel-loader to preprocess them. What we want to do now is add our image loader right beneath this loader, but still within our loaders object:

module: { 
  loaders: [ { 
    test: /\.js|.jsx?$/, 
    exclude: /(node_modules|bower_components)/, 
    loader: 'babel-loader', 
  }, { 
    test: /\.(jpe?g|png|gif|svg)$/i, 
    loaders: [ 
      'file?hash=sha512&digest=hex&name=[hash].[ext]', 
      'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false' 
    ] 
  } ] 
}

Notice that we’ve added a comma after our first loader, and added a second loader that now tests for jpeg, png, gif, and SVG files. Our new loader also contains it’s own set of sub-loaders (thanks to our file-loader module) that will preprocess our images and give our compiled JavaScript the references it needs to display them. These referenced images will be minified, and ready for our clients to view them.

Adding images to your project to utilize our new loader

Now that you’ve got your loader all setup, you can start requiring images in your project files. Webpack image loader will take all of the images in your project folder and minify them. Then it will take the references to the images in your code and bridge the connection between the intended image and the minified one. You would use it quite simply by doing this:

<img src={require("../../images/some-filepath/some-image.png")} />

Working with webpack configuration files can be a daunting task, and is often a process of trial and error, but with a little practice, you’ll be able to set them up quickly, effectively and with outstanding results.

Thanks for reading, let me know if there’s anything you’d like me to cover, or if I missed something here in this article and I’ll get to it. I would like to keep these articles as accurate and up to date as possible so your feedback is always welcome.

Until next time!

By | 2017-01-20T17:33:12+00:00 May 10th, 2016|Development, Javascript|11 Comments

About the Author:

React.js developer, web designer, devops engineer, and business owner.
  • Gabriel Mičko

    Nice tutorial. Thank you. I think it would be more helpful if you include how to put it to a css file (background-image) or to a image component.

    • Thanks for reading Gabriel! I’ll definitely do that and let you know when it’s finished. I really appreciate the feedback!

  • JoshuaTenner

    I was just looking for a tool like this for my visual novel engine project! Thank you for the article!

    • That’s great, I am glad it was of some help to you! Best of luck on your project Josh!

  • Gabriel Santos

    It’s works for me, but I could not get the img like this :

    I had to created something like this in my controller:

    img:String = require(‘../../assets/images/back-arrow.svg’);

    then

    So, How would it? am I doing something wrong? probably yes, but what?

  • Gabriel Santos

    It’s works for me, but I could not get the img like this :

    I had to created something like this in my controller:

    img:String = require(‘../../assets/images/back-arrow.svg’);

    then

    So, How would it work? am I doing something wrong? probably yes, but what?

  • Andrea Falzetti

    Really helpful article, thank you very much! 🙂

    If someone is having my same issue, I have followed this steps and the browser displays a broken image, I’ve found a reason here: https://github.com/webpack/file-loader/issues/35

    Just remove “file-loader” if you are already using “babel-loader” and it will work.

    • Glad it was helpful! I appreciate you helping out the community as well 🙂

  • Michael Stokes

    Thank you!

    I’ve done import logo from ‘../assets/images/logo.png’;

    and then

  • ∆ [c0d3r28] ∆

    This fails to explain (like most similar examples) how this resolves within css url().

  • skube

    Not to miss the point entirely, but isn’t the first loaders’ regex test incorrect?
    Shouldn’t it simply be:

    test: /.jsx?$/,