Загрузка изображений ng-src с помощью webpack

Я загружаю изображение с помощью angular, например.

<img ng-src="{{::path-to-image}}"/>

Когда я связываю свое приложение с webpack, URL-адрес изображения разрешается во время выполнения, поэтому он не связан с загрузчиками веб-пакетов.

Это загрузчик изображений, который я использую:

  {
    test: /\.(jpe?g|png|gif|svg)$/i,
    loader: 'url?limit=8192!img'
  } 

Как веб-пакет может объединить эти изображения во время выполнения?

Ответ 1

Потому что я также нуждался в такой функциональности и нашел, что исходный ответ был далеко не идеальным решением. Я закончил тем, что решил это самостоятельно.

Напишите функцию в контроллере:

$scope.loadImage = function(image) {
    return require('/images/' + image);
};

И используйте его в своем ng-src:

<img ng-src="{{loadImage('myImage')}}" />

После этого для динамического выполнения работы вы можете использовать context.

Например: https://github.com/webpack/webpack/tree/master/examples/require.context#examplejs

Ответ 2

Если вам нужен путь к изображению, который программно сгенерирован, это означает, что у вас есть какая-то логика, ожидающая существования этого образа. Другими словами, вы должны рассматривать этот образ как зависимость от этой части логики, поэтому вам нужно явно ее требовать.

В вашем JS-коде (например: контроллер)

this.imageUrl = require('path-to-image' + someDynamicValue + '.jpg');

В вашем шаблоне:

<img ng-src="{{::myCtrl.imageUrl}}"/>

Webpack достаточно умен, чтобы понимать динамический оператор require и связывать ваши изображения, которые будут соответствовать этому выражению. Подробнее см. Документацию: https://webpack.github.io/docs/context.html)

Ответ 3

Я создал директиву uiImage, в которой requires изображения.

 function uiImage() {
    return {
      restrict: 'A',
      link: function(scope, element, attr) {
        var src = attr.uiImage || attr.src;

        function loadImage(image) {
          return require(`Images/${image}`);
        }

        // required for webpack to pick up image
        element.attr('src', loadImage(src));
      }
    };
  }

  uiImage.$inject = [];
  export default uiImage;

Использование:

<img ui-image='myimage.png' />

webpack.config.js

У меня есть решение Webpack Images, которое указывает на расположение всех моих изображений.

resolve: {
  alias: {
   'Images': path.join(config.appDir, '/images')
  }
}

Ответ 4

Мне нужно было динамически разрешать изображения во время выполнения с хэшами, сгенерированными webpack, например, imgA.bd79a5ba.png.

{
  test: /\.png$/,
  loader: 'file-loader?name=images/[name].[hash].[ext]',
}

Я закончил создание модуля для псевдонима и потребовал изображения:

let map = {
  'imgA': require('./images/imgA.png'),
  'imgB': require('./images/imgB.png'),
  'imgC': require('./images/imgC.png')
}

В результате получается карта:

{
  'imgA': imgA.bd79a5ba.png,
  'imgB': imgB.e51f66a2.png,
  'imgC': imgC.d84ae37c.png
}

В моем компоненте я разрешил URL-адрес с карты:

self.link = function link(scope) {
  scope.imageUrl = function(name) {
    function return map[name];
  }
};

Тогда было тривиально загружать изображение:

 <img ng-src="{{ imageUrl('imgA') }}">

Вышеприведенное упрощено. Мне было сочтено создание модуля для карты:

export default {
  'imgA': require('./images/imgA.png'),
  'imgB': require('./images/imgB.png'),
  'imgC': require('./images/imgC.png')
}

затем импортируйте его в компонентный модуль:

import urlMap from './imageUrlMap'
console.log(urlMap.imgA)

> imgA.bd79a5ba.png

Ответ 5

я просто использую CopyWebpackPlugin и никаких накладных расходов вообще

const CopyWebpackPlugin = require('copy-webpack-plugin');
// WriteFilePlugin  needed only for webpack 3-4 and webpack dev-server
const WriteFilePlugin = require('write-file-webpack-plugin');
plugins: [
  ...
  new WriteFilePlugin(),
  new CopyWebpackPlugin([
        {from: 'files', to: 'files'},
        {from: 'images-2x', to: 'images-2x'},
        {from: 'images', to: 'images'},
      ]),
]