0

I am making the transition from gulp to webpack and I have images in a static/img folder that I want to process with image-webpack-loader and then copy to a build/public/img folder. Is file-loader what I want to use for this? The problem is that the images are not being copied. In fact it seems like this loader is being ignored during the build.

const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');

module.exports = {
  context: path.resolve(__dirname, 'static'),
  entry: ['./js/frontend.js','./sass/app.scss'],
  output: {
    path: path.join(__dirname, 'build/public'),
    filename: 'js/frontend.js'
  },
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif|svg)$/,
        loader: [
            'file-loader?name=img/[name].[ext]',
            'image-webpack-loader?bypassOnDebug&optimizationLevel=7&interlaced=false'
        ]
      },
      {
        test: /\.(sass|scss)$/,
        loader: ExtractTextPlugin.extract({
          use: [{
            loader: 'css-loader',
            options: {
              sourceMap: true
            }
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true
            }
          }]
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin({ 
      filename: 'css/styles.css',
      allChunks: true
    })
  ],
  devtool: 'source-map'
};
SmellydogCoding
  • 414
  • 8
  • 23

2 Answers2

1

If you don't require the images somewhere, Webpack doesn't know they exist and won't process them.

Put following code inside ./js/frontend.js to force Webpack to require every asset from the static/img folder:

// load assets
function requireAll(r) { r.keys().forEach(r); }
requireAll(require.context('img/', true));
Tom Van Rompaey
  • 3,556
  • 20
  • 22
  • When you say require the images do you mean that webpack is looking for IMG tags in HTML files? That would explain why webpack didn't find any since the code that I posted is actually part of a NodeJS application that uses Pug. – SmellydogCoding Aug 05 '17 at 00:36
  • That's correct. Webpack doesn't know your HTML is using these images. If you are building a website using React/Vue/Angular, you could import the image the same way as JavaScript modules `import logo from 'img/logo.png;'` and then they will be processed. In your case, you will need to use above solution to force Webpack to require/import your images. – Tom Van Rompaey Aug 05 '17 at 01:44
0

I'm not sure if this is a solution or a workaround, but what I did is use the CopyWebpackPlugin with the ImageminPlugin:

const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const path = require('path');

module.exports = {
  context: path.resolve(__dirname, 'static'),
  entry: ['./js/frontend.js','./sass/app.scss'],
  output: {
    path: path.join(__dirname, 'build/public'),
    filename: 'js/frontend.js'
  },
  module: {
    rules: [
      {
        test: /\.(sass|scss)$/,
        loader: ExtractTextPlugin.extract({
          use: [{
            loader: 'css-loader',
            options: {
              sourceMap: true
            }
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true
            }
          }]
        })
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin('build/public'),
    new ExtractTextPlugin({ 
      filename: 'css/styles.css',
      allChunks: true
    }),
    new CopyWebpackPlugin([
      {
        from: 'img', to: 'img'
      }
    ]),
    new ImageminPlugin({ test: /\.(jpe?g|png|gif|svg)$/i })
  ],
  devtool: 'source-map'
};
SmellydogCoding
  • 414
  • 8
  • 23