动态添加图像 React Webpack

Posted

技术标签:

【中文标题】动态添加图像 React Webpack【英文标题】:Dynamically Add Images React Webpack 【发布时间】:2015-12-13 07:04:19 【问题描述】:

我一直在尝试弄清楚如何通过 React 和 Webpack 动态添加图像。我在 src/images 下有一个图像文件夹,在 src/components/index 下有一个组件。我正在使用带有以下 webpack 配置的 url-loader

    
      test: /\.(png|jpg|)$/,
      loader: 'url-loader?limit=200000'
    

在组件中,我知道我可以在创建组件之前为文件顶部的特定图像添加 require(image_path),但我想让组件通用并让它具有一个属性带有从父组件传递的图像的路径。

我试过的是:

<img src=require(this.props.img) />

对于实际的属性,我已经尝试了几乎所有我能想到的从项目根目录、react 应用根目录和组件本身到图像的路径。

文件系统

|-- src
|   ` app.js
|   `--images
|      ` image.jpg
|      ` image.jpg
|   `-- components
|      `parent_component.js
|      `child_component.js

父组件基本上只是一个容纳多个子组件的容器,所以...

<ChildComponent img=data.img1 />
<ChildComponent img=data.img2 />
etc....

有什么方法可以使用带有 url-loader 的 react 和 webpack 来做到这一点,还是我只是走错了路来解决这个问题?

【问题讨论】:

【参考方案1】:

使用此处描述的 url-loader (SurviveJS - Loading Images),然后您可以在代码中使用:

import LogoImg from 'YOUR_PATH/logo.png';

<img src=LogoImg/>

编辑:精确,使用这种技术将图像内联在 js 存档中。它可以用于小图像,但要明智地使用该技术。

【讨论】:

我想知道如何从中加载此图像以及返回图像的 API。 我不确定:如果您希望用户浏览器从 API 加载图像,它与 webpack 无关。只需使用一个变量(可能在调用 API 之后定义)作为 src。这里的想法是将图像包含在您的源代码和 webpack 存档中。 (见***.com/questions/32612912/…) 谢谢,这很好用。您引用的文章最后还提到,如果您使用的是 React,那么您可以使用 babel-plugin-transform-react-jsx-img-import 自动生成导入。这样你就可以写 警告:url-loader 会将图像文件内联为 base64 ascii 字符串。这减少了加载页面所需的文件访问次数,但代价是下载更多字节。因此,使用 file-loader 进行生产可能会更好。 是的,图像是用这种技术内联的。这完全取决于文件的重量。对于小的(主要是给我的图标),它可能是值得的。我将编辑回复【参考方案2】:

如果您在服务器端捆绑您的代码,那么没有什么可以阻止您直接从 jsx 获取资源:

<div>
  <h1>Image</h1>
  <img src=require('./assets/image.png') />
</div>

【讨论】:

这是我在构建组件之前不知道图像文件的情况下需要使用的。我传入一个imageFilename 道具,然后使用&lt;img src=require(`./images/$imageFilename`) /&gt;。感谢发帖。 @BrendanMoore 但请记住,在您的情况下,捆绑器(例如 webpack)会将 images 文件夹中的所有图像添加到最终捆绑包中。 正是我想要的。谢谢@JamesAkwuh 如果这不起作用,则在 require() 之后添加 .default。例如:我正在使用 const src = require(assets/images/$name).default;【参考方案3】:

更新:这仅通过服务器端渲染(通用 javascript)测试,这是我的boilerplate。

仅使用文件加载器,您就可以动态加载图像 - 诀窍是使用 ES6 模板字符串,以便 Webpack 可以获取它:

这将工作。 :

const myImg = './cute.jpg'
<img src=require(myImg) />

要解决这个问题,只需使用模板字符串即可:

const myImg = './cute.jpg'
<img src=require(`$myImg`) />

webpack.config.js:

var htmlWebpackPlugin =  require('html-webpack-plugin')
var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')

module.exports = 
  entry : './src/app.js',
  output : 
    path : './dist',
    filename : 'app.bundle.js'
  ,
  plugins : [
  new ExtractTextWebpackPlugin('app.bundle.css')],
  module : 
    rules : [
      test : /\.css$/,
      use : ExtractTextWebpackPlugin.extract(
        fallback : 'style-loader',
        use: 'css-loader'
      )
    ,
      test: /\.js$/,
      exclude: /(node_modules)/,
      loader: 'babel-loader',
      query: 
        presets: ['react','es2015']
      
    ,
      test : /\.jpg$/,
      exclude: /(node_modules)/,
      loader : 'file-loader'
    ]
  

【讨论】:

对我来说缺少的是 webpack 配置中的测试。谢谢。【参考方案4】:

如果您正在寻找一种从图像中导入所有图像的方法

// Import all images in image folder
function importAll(r) 
    let images = ;
    r.keys().map((item, index) =>  images[item.replace('./', '')] = r(item); );
    return images;


const images = importAll(require.context('../images', false, /\.(gif|jpe?g|svg)$/));

然后:

<img src=images['image-01.jpg']/>

你可以在这里找到原帖:Dynamically import images from a directory using webpack

【讨论】:

【参考方案5】:

所以你必须在你的父组件上添加一个 import 语句:

class ParentClass extends Component 
  render() 
    const img = require('../images/img.png');
    return (
      <div>
        <ChildClass
          img=img
        />
      </div>
    );
  

在子类中:

class ChildClass extends Component 
  render() 
    return (
      <div>
          <img
            src=this.props.img
          />
      </div>
    );
  

【讨论】:

【参考方案6】:

您没有将图像嵌入到包中。它们是通过浏览器调用的。所以它的;

var imgSrc = './image/image1.jpg';

return <img src=imgSrc />

【讨论】:

但是如果您在构建时不知道映像怎么办?如果图像 URL 是在运行时组成的呢? 您使用的加载器的目标实际上是不在代码中使用 url,并且如果图像足够小(更好的性能),则可能能够将图像嵌入存档中【参考方案7】:

这里是代码

    import React,  Component  from 'react';
    import logo from './logo.svg';
    import './image.css';
    import Dropdown from 'react-dropdown';
    import axios from 'axios';

    let obj = ;

    class App extends Component 
      constructor()
        super();
        this.state = 
          selectedFiles: []
        
        this.fileUploadHandler = this.fileUploadHandler.bind(this);
      

      fileUploadHandler(file)
        let selectedFiles_ = this.state.selectedFiles;
        selectedFiles_.push(file);
        this.setState(selectedFiles: selectedFiles_);
      

      render() 
        let Images = this.state.selectedFiles.map(image => 
          <div className = "image_parent">

              <img src=require(image.src)
              />
          </div>
        );

        return (
            <div className="image-upload images_main">

            <input type="file" onClick=this.fileUploadHandler/>
            Images

            </div>
        );
      
    

    export default App;

【讨论】:

以上是关于动态添加图像 React Webpack的主要内容,如果未能解决你的问题,请参考以下文章

在 webpack 中动态添加全局常量

react 对象动态添加属性 setState

使用 React.lazy 与 webpack 动态导入?

使用 Parceljs 动态加载图像

react动态添加样式:style和className

vue中动态加载图片报错