如何在不弹出的情况下向create-react-app添加CopyWebpackPlugin?

11

我正在构建一个React应用程序,我想将源目标中的所有图像文件复制到构建目标中。我正在遵循一些教程,并成功使用了react-app-rewiredCopyWebpackPlugin

我没有收到任何错误消息,也没有复制任何文件。

这是我的config-overrides.js

const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = function override(config, env) {
   if (!config.plugins) {
    config.plugins = [];
  }
  config.plugins.push(
    new CopyWebpackPlugin(
    [
      {
        from: 'src/images',
        to: 'public/images'
      }
    ])
  );
  return config;
};

这是我的package.json

{
  "name": "public",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "axios": "^0.18.0",
    "copy-webpack-plugin": "^4.5.2",
    "css-loader": "^1.0.0",
    "prop-types": "^15.6.2",
    "react": "^16.4.2",
    "react-app-rewired": "^1.5.2",
    "react-axios": "^2.0.0",
    "react-dom": "^16.4.2",
    "react-router-dom": "^4.3.1",
    "react-scripts": "1.1.4",
    "react-slick": "^0.23.1",
    "slick-carousel": "^1.8.1",
    "typeface-montserrat": "0.0.54",
    "webfontloader": "^1.6.28"
  },
  "scripts": {
    "build-css": "node-sass-chokidar src/ -o src/",
    "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
    "start-js": "react-app-rewired start",
    "start": "npm-run-all -p watch-css start-js",
    "build-js": "react-app-rewired build",
    "build": "npm-run-all build-css build-js",
    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {
    "npm-run-all": "^4.1.3",
    "style-loader": "^0.22.1"
  }
}

我的文件夹结构是:

src/images src/images/file.jpg src/images/slider/1.png src/images/slider/2.png public/images(目前为空)


1
你只需要像 https://ant.design/docs/react/use-with-create-react-app 高级指南中所示的那样做即可。 - user158
问题:1. 你需要使用webpack插件吗?你不能在package.json的build中添加脚本吗?2. 你是使用CRA还是react-app-rewired?问题标题说是CRA,但代码中写的是react-app-rewired。3. CRA默认应该将所有图像放在build/static/media中,这个路径对你不起作用吗? - dubes
几天前刚看了一个视频教程,也许这可以帮到你(不确定是否需要会员才能观看)? https://egghead.io/lessons/react-customize-create-react-app-cra-without-ejecting-using-react-app-rewired - Joshua
@dubes 我认为你需要执行 import image1 from './component/file.jpg' 才能使其正常工作,并且它会压缩并附加一个随机名称。 - TheBlackBenzKid
我发现将create-react-app项目弹出后,处理类似这样的配置特性会更加容易,因此这可能是最好的方法。 create-react-app仅旨在作为起点,而不是React项目在其整个生命周期中的规范配置。 - nnyby
顺便提一下,有关通用自定义配置的中央上游讨论似乎在 https://github.com/facebook/create-react-app/issues/6303。 - Ciro Santilli OurBigBook.com
4个回答

9
假设您只想在构建时从-/src/<somewhere>移动文件到./<somewhereElse>,您可以在package.json的build脚本中添加一个额外的步骤。该步骤完全由您控制,不会影响任何create-react-app脚本或配置。
例如,我使用了ncp ,但如果您想要更精细的控制,也可以使用ncp或原始节点fs api创建自己的“步骤”。
以下是复制我所做的方法: 设置
npx create-react-app img-upload
cd img-upload/
yarn add --dev ncp

测试数据 创建src/images/文件夹结构并放入文件

ls -R src/images/
src/images/:
badge.jpg  folder1

src/images/folder1:
applause.gif  blank.png

Package.json

我只编辑了这一部分:"build": "ncp './src/images' './public/images' && react-scripts build"

本文讲解了如何编辑package.json文件,其中详细介绍了如何将图片从源目录复制到公共目录,并在构建时运行react-scripts build命令。
{
  "name": "img-upload",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.4.2",
    "react-dom": "^16.4.2",
    "react-scripts": "1.1.5"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "ncp './src/images' './public/images' &&  react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {
    "ncp": "^2.0.0"
  }
}

测试: 在运行构建之前:

ls public
favicon.ico  index.html  manifest.json

执行构建命令后:yarn build
ls public
favicon.ico  images  index.html  manifest.json

ls -R public/images
public/images/:
badge.jpg  folder1

public/images/folder1:
applause.gif  blank.png

ls build
asset-manifest.json  favicon.ico  images  index.html  manifest.json  service-worker.js  static

ls -R build/images
build/images/:
badge.jpg  folder1

build/images/folder1:
applause.gif  blank.png

建议 我假设您最终需要这些文件在build目录中。如果是这样,您只需切换您的build脚本即可。

"build": "react-scripts build && ncp './src/images' './build/images'",

这样,您就不会污染您的公共文件夹,您可能希望将其保留在源代码控制中。


我最终在 startbuild 中添加了这个,但我做了 "ncp": "ncp src/images public/images" 并只是添加了 ncp 作为参考。有没有办法在开发过程中监视文件夹?否则每次都必须杀死节点并运行 npm startnpm build - TheBlackBenzKid
我有一些想法,但这取决于你想要实现什么。我需要更了解你的流程。我们明天试着开始聊天。 - dubes
只需一种方法,npm将监视并始终复制到图像文件夹,确保如果我重命名,它会重命名,如果我删除,它会删除-完全同步实时监视。 - TheBlackBenzKid
我正在寻找可以完成的方法。另一个想法是:你不能只将它们保存在公共文件夹中吗?你是如何在React组件中导入这些图像的? - dubes
我之前一直使用<img src='/images/file.jpg'/>,以前是用import来写的,但当你有大型幻灯片或大型图像内容时,我决定直接调用它们。我还有一个axios JSON API,其中链接了这些变量和对象中的图像。 - TheBlackBenzKid

5
不建议修改node_modules/react-scripts/config/webpack.config.dev.js文件,因为更新该特定包时会出现问题。而且,你的版本控制系统中很可能忽略了node_modules,这意味着此配置不会在开发者之间共享或备份。
尽管我个人没有亲身尝试过,但你可以使用像https://github.com/timarney/react-app-rewired这样的工具来覆盖Webpack配置。
你可以查看这里的教程:https://medium.com/@timarney/but-i-dont-wanna-eject-3e3da5826e39

感谢迄今为止的回答,我更新了我的问题,目前已经准备好插件架构和文件准备工作,但是没有复制文件或产生错误。 - TheBlackBenzKid

5
我的工作方式如下:
const { override, addWebpackPlugin } = require('customize-cra');
module.exports = {
webpack: override(
    addWebpackPlugin(
        new CopyWebpackPlugin({
            patterns: [
                { from: 'src/config', to: 'config' }
            ],
        })
    )
)

因此,我将config文件夹的内容复制到build文件夹中,并将其命名为config。


2
我认为问题出在您同时使用了webpack-dev-servercopy-webpack-plugin。如果是这样,copy-webpack-plugin会将文件复制到虚拟目录中,而webpack-dev-server正在使用该目录。因此,在这种情况下,您需要添加一个插件才能实现它。

如果您希望在开发过程中让webpack-dev-server将文件写入输出目录,可以使用write-file-webpack-plugin来强制执行。

import WriteFilePlugin from 'write-file-webpack-plugin';

Webpack配置:

config.plugins.push(
    new CopyWebpackPlugin(
    [
      {
        from: 'src/images',
        to: 'public/images'
      }
    ])
  );
config.plugins.push(new WriteFilePlugin());

您可以访问官方文档以获取更多信息:https://webpack.js.org/plugins/copy-webpack-plugin/

希望这能帮到您!


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