React 组件库无法加载自己的静态资源

React component library can not load its own static asset

我有一个react app(使用create react app),然后是一个组件库(直接使用webpack)。组件库中的一个组件需要在它导出的组件之一中加载一个 png 文件。在组件库的 webpack 配置中,我有一个部分,例如:

      {
        test: /\.(png|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },

这成功地在组件库输出目录中生成了如下文件:29b6b66cf1a691be2b3f.png。问题是,当 应用程序 使用该组件并且该组件尝试加载图像时,img 元素是 <img ... src="29b6b66cf1a691be2b3f.png" /> 并且加载失败,因为该图像 实际上 位于组件库文件夹中(此时在 React 应用程序的 node_modules/component-library/ 中)。

我已尽我所能搜索互联网,但似乎无法找出最佳解决方案。任何帮助表示赞赏。如果需要,我会尽快提供说明。

更新: 我发现了 CopyWebpackPlugin 但很不幸,这需要我从 create react app 中弹出“父”应用程序。我非常希望避免的事情。

UPDATE2: 目前的计划是尝试按照解释的内容进行操作 here. The jist of it is to utilize something like rewire 以避免需要弹出并仍然能够通过类似的方式编辑 webpack 配置:

// in ./build.js
const rewire = require('rewire');
const defaults = rewire('react-scripts/scripts/build.js');
const config = defaults.__get__('config');

// edit webpack config values here

...如果我发现这种方法有效,我会在这里回答我自己的问题。

好吧,这感觉比它需要的要混乱得多,但我能够找到一种方法来完成它。作品如下。

首先,需要安装 copy-webpack-plugin。这并不像听起来那么简单,因为我需要找到一个不会与我的 react-scripts(创建 React 应用程序)所需的 webpack 版本冲突的版本。我确定 copy-webpack-plugin@6.4.1 是支持 webpack v4 的最后一个版本,所以我安装了它,然后将以下内容添加到我的 package.json:

  "overrides": {
    "copy-webpack-plugin": {
      "webpack": "4.44.2"
    }
  },

这确保它会使用我的 react-scripts 安装所期望的 webpack 版本。

然后,我还需要安装 rewire,并将以下内容添加到名为 build.js 的文件中:

const rewire = require('rewire');
const defaults = rewire('react-scripts/scripts/build.js');
const config = defaults.__get__('config');
const CopyPlugin = require("copy-webpack-plugin");


const patterns = [
  { 
    context: "node_modules/component-library/path/",
    from: "*.png", 
    to: "." 
  },
]


if(config.plugins === undefined){
  config.plugins = [new CopyPlugin({patterns})]
}else{
  config.plugins.push(new CopyPlugin({patterns}))
}

// below lets it work in dev mode too
if(config.devServer === undefined){
  config.devServer = {
    writeToDisk: true
  }
}else{
  config.devServer.writeToDisk = true;
}

最后,不得不将我的构建脚本更新为:

  "scripts": {
    ...
    "build": "node ./build.js",
    ...
  },