【问题标题】:Loading ng-src images with webpack使用 webpack 加载 ng-src 图像
【发布时间】:2016-03-29 23:08:29
【问题描述】:

我正在加载带有角度的图像,例如

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

当我将我的应用程序与 webpack 捆绑在一起时,图像 URL 会在运行时解析,因此不会被 webpack 的加载器捆绑。

这是我正在使用的图像加载器:

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

webpack 如何捆绑那些在运行时解析的图像?

【问题讨论】:

    标签: angularjs webpack


    【解决方案1】:

    我只是使用 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'},
          ]),
    ]
    

    【讨论】:

      【解决方案2】:

      我需要在运行时使用 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
      

      【讨论】:

        【解决方案3】:

        因为我也需要这样的功能,并且发现原来的答案远不是一个完美的解决方案,所以我最终自己解决了。

        在控制器中写一个函数:

        $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

        【讨论】:

        • 聪明的解决方案!感谢分享
        • 非常适合我。再次感谢
        • 你错过了ng-src中的{{ }}
        • 你是对的!感谢您的反馈,我已修复它。
        • 为什么和DOM相关?加载例如 json 文件或图像有什么区别?
        【解决方案4】:

        我创建了一个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')
          }
        }
        

        【讨论】:

          【解决方案5】:

          如果您需要以编程方式生成的图像路径,这意味着您有一些逻辑期望该图像存在。换句话说,您应该将此图像视为该逻辑的依赖项,因此您需要明确要求它。

          在你的 JS 代码中(例如:控制器)

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

          在您的模板中:

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

          Webpack 足够聪明,可以理解动态的require 语句,并捆绑匹配该表达式的图像。 查看文档了解更多详情:https://webpack.github.io/docs/context.html)

          【讨论】:

          • 您的建议在控制器中传播视图逻辑,这以前不知道视图(html 文件)是否以及如何呈现数据。这对我来说更像是 WebPack 的限制,即它无法处理在运行时解析的资源。我想我会求助于 gulp 将我的静态资产复制到 dist/ 文件夹。谢谢。
          • 确实,对此我的感受很复杂。但实际上 Webpack 可以处理它(通过我展示的 require() 调用)。这更像是一个 html-loader 限制,因为它没有考虑 src(或 ng-src)属性中的角度表达式。
          • 还有一句话:通过依赖外部工具来复制/构建资产,您隐藏了代码 (html) 和图像之间的依赖关系。对我来说,这就像在全局范围内使用 $ (并期望它在那时已经定义)而不是使用 var $ = require('jquery'); 明确要求它我们不习惯对那种资产(字体、图像、样式)这样想但毕竟,这就是 css 和其他文件加载器的用途。
          • 我同意,但这又归结为装载机。如果我将加载器配置为散列文件内容,那么我无法在 html 中反映它。另一方面,我不想为静态和动态引用的图像配置不同的加载器,加上其他开发人员的开销。这种类型的“全局”依赖使我的代码库和开发过程更简单
          • “::”的前缀是什么?
          猜你喜欢
          • 2021-04-24
          • 2017-04-07
          • 1970-01-01
          • 2018-02-13
          • 1970-01-01
          • 2013-07-26
          • 2015-07-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多