【问题标题】:How to reference image in React Component NPM module?如何在 React Component NPM 模块中引用图像?
【发布时间】:2016-01-09 02:15:36
【问题描述】:

我在 react 中创建了一个日期选择器,我正在尝试将其上传到 NPM,它使用外部 svg,但我无法正确引用该 svg。

所以我的文件目录是这样的:

+-- imgs
|   +-- arrow.svg
+-- src
|   +-- Datepicker.jsx
|   +-- index.js

然后在 Datepicker.jsx 我有
<object style={STYLES.arrow} data="../imgs/arrow.svg" type="image/svg+xml" />

但是当我通过 npm 安装它并尝试在项目中使用它时,它说:
GET http://localhost:8000/imgs/arrow.svg 404 (Not Found)

它看起来像是在项目的根目录中而不是在模块本身中寻找 imgs 目录,但我不知道如何解决这个问题。

【问题讨论】:

    标签: javascript node.js reactjs npm


    【解决方案1】:

    我可能会在编译之前使用webpack 来简单地require 数据:

    const data = require('../imgs/arrow.svg');
    
    <object style={STYLES.arrow} data={data} type="image/svg+xml" />
    

    您需要执行npm install --save-dev webpack url-loader 或类似的操作。 webpack 文档应该让你知道你需要什么(上面链接)。

    你的问题是它试图在 runtime 找到数据路径,而更好的方法是在 compile time 找到数据路径。

    【讨论】:

    • 我正在为我的项目使用 webpack,但是对于这个模块,因为我将它放在 NPM 上以便其他人可以使用,所以我只是将它转换为 ES5,所以你是说我会使用 webpack 捆绑所有的 js 和图像,然后将该捆绑包上传到 npm?
    • 这是一个很常见的模式(比如说,有一个srcdist 文件夹,其中dist 包含编译后的输出)。许多现有的模块都遵循这种模式,特别是因为它可以减少使用该模块的用户的依赖要求。
    • 所以,是的,我会说最好为src 提供所有预编译文件,然后提供一个文件夹dist 与编译输出。
    【解决方案2】:

    接受的答案在这里确实帮助了我,只是想展示我如何让它为我工作。我有几个 React 项目需要共享一个组件,所以我在它自己的独立库中构建了该组件。最初,我一直在通过“典型”src 方法引用库中的一些图像,其中这些静态文件是从公共目录中获取的,例如&lt;img src='icons/down-arrow.svg' /&gt;,但是,正如 OP 所指出的那样,当该库被导入到父项目中,因为父项目最终会根据自己的根目录查找图标,而不是库的根目录。

    导入这些图标并将这些导入设置为 src 属性就行了 -

    // src/components/component.js
    import React from 'react';
    import downArrow from '../../../public/icons/down-arrow.svg';
    import rightArrow from '../../../public/icons/right-arrow.svg';
    
    const MyComponent = (props) => {
        const icon = props.selected ? downArrow : rightArrow;
    
        return (
            <div>
                <img src={icon} />
            </div>
        );
    };
    
    export default MyComponent;
    

    在这种情况下,组件位于/src/components/component.js,其中一个图标位于/public/icons/down-arrow.svg

    或者,您可以像这样在 Webpack 配置中为 public 目录设置别名

    // ...
        resolve: {
            alias: {
                public: path.resolve(__dirname, 'public/')
            }
        },
    // ...
    

    并从导入路径中删除前导 ../s。

    【讨论】:

    • 你能分享一下你的组件库的结构我面临同样的问题
    • @Abhi 我添加了关于文件结构的注释,希望对您有所帮助。
    【解决方案3】:

    创建一个分离的组件:

    export function BaseIcon(props: any) {
      return (
        <div>
          <img
            src={
              require(`../node_modules/cryptocurrency-icons/svg/color/${props.name}.svg`)
                .default.src
            }
          />
        </div>
      );
    }
    

    并且从组件中,您可以通过传递名称直接访问它

    <BaseIcon name={item.name} />
    

    很少解释require(../node_modules/cryptocurrency-icons/svg/color/${props.name}.svg) 返回的内容,这是一个对象,是default 的属性之一。有时,在答案中,您可以在末尾看到default。我相信这不仅限于cryptocurrency-icons,这是在寻找解决方案时得出的结论。在我的例子中,default 是一个对象,它具有 src 键和源文件的直接路径。

    不需要额外的依赖项,至少在Next.js 上,如url-loader,是不需要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      • 2015-11-24
      • 1970-01-01
      • 2019-06-27
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多