如何处理Rails/Webpacker/React应用程序中的图片?

26

我正在使用Rails 5.1.4中的Webpacker来尝试React、Redux和react-router-dom。

我有一个位于app/javascript/src/components/Navbar.jsx组件需要显示一张图片,但我无法访问存储在app/assets/images/中的图片。

我已经尝试了以下方法:

<img src="logo.png" alt="Logo" />
<img src="assets/logo.png" alt="Logo" />
<img src="assets/images/logo.png" alt="Logo" />

从根路径开始,最后一个尝试起作用是因为/assets/images/logo.png存在,但当我导航到/posts/:id时,它会给出以下错误:

从根路径开始,最后一个尝试可以正常工作,因为/assets/images/logo.png存在,但是当我导航到/posts/:id时,它会给出以下错误:

logo.png:1 GET http://localhost:3000/posts/assets/images/logo.png 404 (Not Found)

你能帮助我吗?另外,在那种混合React/Rails应用程序中,你处理图像的方式是什么?

谢谢

5个回答

39

只需编辑文件config/webpacker.yml并替换此行:

resolved_paths: []

用这个:

resolved_paths: ['app/assets']

接下来,将图像放在app/assets/images文件夹中,并按照以下方式加载:

import React from 'react'
import MyImage from 'images/my_image.svg'

const MyComponent = props => <img src={MyImage} />

export default MyComponent

2
我有完全相同的情况,我已经尝试了上述方法,但是我仍然得到了无法解析图像的错误。 - Logic Artist
我能够在不将 app/assets 添加到 resolved_paths 中的情况下实现此解决方案。 - Fabrizio Bertoglio
第11行是什么?你能更新一下,显示整个文件吗? - wuliwong
1
这对我在Rails 6中有效...与下面的回复不同,我需要添加'app/assets'来解决路径。如果我想要使用资产文件夹,我想CSS也一样需要这样做。 - David Hersey
如果您使用此方法并在视图中调用image_tag中的图像,则会加载两次图像。 - Edward

4
If we leave resolved_path as [] in webpacker.yml also it works.

Example = 

# Additional paths webpack should lookup modules
  # ['app/assets', 'engine/foo/app/assets']
  resolved_paths: []

  static_assets_extensions:
    - .jpg
    - .jpeg
    - .png
    - .gif
    - .tiff
    - .ico
    - .svg
    - .eot
    - .otf
    - .ttf
    - .woff
    - .woff2

你甚至可以在你的组件中创建一个图片文件夹。像下面这样在组件文件中加载它-

import React from 'react';
import MyImage from '${imagePath}/example1.png'

export class MyComponent extends React.Component {
  render() {
    return (
     <React.Fragment>
       <img src={MyImage} alt="Image text"/>
     </React.Fragment>     
    )
  }
}

WebPacker内部将这些图像路径转换为包。

3

2021年更新(Rails 6.1.4),resolved_paths键已更改为additional_paths

所以,修改为:

# config/webpacker.yml

default: &default
  resolved_paths: []

into:

# config/webpacker.yml

default: &default
  additional_paths: ['app/assets']

关于Daniel's回答后续部分


0

非常感谢,你让我的一天变得美好了。这比你分享的文章中说的还要简单。我所需要做的就是通过 yarn install file-loader 安装 file-loader,然后引入我的图片 import Logo from '../../../assets/images/logo.png'; 并使用它 <img src={Logo} alt="Logo" />。太棒了! - adesurirey
为了添加新的依赖项,install 已被替换为 add。请运行 "yarn add file-loader"。 - Manish

-1

对于仍然遇到此问题的人,请尝试以下方法:

将您的图像放在app/assets/images中。在此示例中,我的图像名为“logo.png”。

在您的application.html.erb文件中,在head标签中添加以下内容:

<script type="text/javascript">
   window.logo = "<%= image_url('logo.png') %>"
</script>

现在在你的组件中渲染图片:

return (
  <div>
    <a href="/">
      <img src={window.logo}/>
    </a>
  </div>
);

希望这能有所帮助。

虽然这样做可以实现功能,但在JS中向window对象添加内容是不好的编程习惯。它会使单元测试变得更加困难,允许页面上的任何脚本更改您的图像,从而可能打开XSS向量,并且您必须为每个要添加的图像遵循该过程。 - dkimot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接