Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add the CopyWebpackPlugin to create-react-app without ejecting?

I am building a react application and I want to copy all image files from the source destination to the build destination. I am following some tutorials and so far managed to use react-app-wired and the CopyWebpackPlugin

I am getting no errors and no files are being copied.

This is my 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;
};

This is my 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"
  }
}

My folder structure is

src/images src/images/file.jpg src/images/slider/1.png src/images/slider/2.png public/images (empty) so far

like image 232
TheBlackBenzKid Avatar asked Aug 20 '18 01:08

TheBlackBenzKid


2 Answers

Assuming you just want to move files from -/src/<somewhere> to ./<somewhereElse> at build time.

You could just add an extra step to your build script in package.json. The step below is completely in your control and does not mess with any create-react-app scripts or configuration.

For example, I used the ncp package, but if you want more granular control, you can also create your own "step" with ncp or even with raw node fs api.

Here is a way to replicate what I did:

Setup

npx create-react-app img-upload
cd img-upload/
yarn add --dev ncp

Test Data create src/images/ folder structure and put in files

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

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

Package.json

I only edited the part: "build": "ncp './src/images' './public/images' && 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"
  }
}

Test: Before running build:

ls public
favicon.ico  index.html  manifest.json

After running build: 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

Suggestion I am assuming you ultimately need these files in build directory. If so, you can just switch your build script.

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

That way you won't pollute your public folder, which you may want to keep in your source control.

like image 200
dubes Avatar answered Sep 18 '22 08:09

dubes


I think the problem is because you are using webpack-dev-server together with copy-webpack-plugin. If that's true, the copy-webpack-plugin will copy files to virtual directory which webpack-dev-server works. So that, In this situation, you need to add one more plugin to make it happen

If you want webpack-dev-server to write files to the output directory during development, you can force it with the write-file-webpack-plugin.

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

webpack config:

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

You can visit the official document for more information: https://webpack.js.org/plugins/copy-webpack-plugin/

Hope this works!

like image 45
Dat Tran Avatar answered Sep 21 '22 08:09

Dat Tran