Пример части конфигурации для webpack версии 4 (но и на предыдущих работает):
output: {
    path: resolve(__dirname, './dist'),
    publicPath: mode === 'development' ? '/' : 'static/',
    filename: '[name].js'
  },
  module: {
    rules: [
      {
        test: /\.(png|jpg|jpeg|gif|svg|woff|ico|woff2|ttf|eot)(\?.*$|$)/,
        loader: 'file-loader',
        exclude: /node_modules/,
        options: {
          name: '[path][name].[ext]?[hash]',
          publicPath: mode === 'development' ? '' : './static'
        }
      },
      {
        test: /\.(png|jpg|jpeg|gif|svg)(\?.*$|$)/,
        loader: 'file-loader',
        options: {
          regExp: /node_modules/,
          name: '[name].[ext]?[hash]',
          publicPath: mode === 'development' ? '' : './static/img',
          outputPath: 'static/img'
        }
      }
    ]
  }
Первый лоадер для собственных ассетов, второй для node_modules.
В моем случае нужно было переместить статику и получить правильные пути для неё в css из такого (без второго лоадера):
{
  background: transparent url(./static/_/node_modules/fancybox/dist/img/blank.gif);
}
В такое:
{
  background: transparent url(./static/img/blank.gif);
}
Эта конфигурация простая, статики не много и у меня не стояло задачи каким то образом ее оптимизировать (использовать url-loader например, разделять шрифты и графику и т.п.).