cra-build-watch icon indicating copy to clipboard operation
cra-build-watch copied to clipboard

cra-build-watch with react-app-rewired

Open zonski opened this issue 5 years ago • 8 comments

I'm trying to use cra-build-watch with react-app-rewired because I need to disable the chunking of files and just have static files (among other config changes). This doesn't seem to work with cra-build-watch. Is there an option for this?

react-app-rewired cra-build-watch

Unknown script "cra-build-watch".

zonski avatar Mar 12 '19 06:03 zonski

I've never used react-app-rewired to be honest so I have no clue of how it works and cra-build-watch has never been tested with it so far (that I know of).

Nargonath avatar Mar 12 '19 08:03 Nargonath

@zonski I had a similar requirement, so I created a pull request that adds an option to disable code splitting / chunks. See https://github.com/Nargonath/cra-build-watch/pull/33.

Hopefully that meets your needs, or at least helps to show how you can implement something similar.

jordanmkoncz avatar Jul 22 '19 22:07 jordanmkoncz

@zonski I just released v2.0.0 which adds the feature developed by @jordanmkoncz. Does it fix your problem?

Nargonath avatar Aug 07 '19 07:08 Nargonath

I'll just close the issue for now. Feel free to tell me if it still persists and I'll reopen it.

Nargonath avatar Aug 13 '19 13:08 Nargonath

You are not fixing the actual issue. https://github.com/timarney/react-app-rewired allows you to modify the webpack config for the CRA-app. It also requires you to not run react-scripts start but you need to use the command react-app-rewired start which will then first patch the webpack.config.js by running it through the patch function you define in config-overrides.js.

As your project here also patches the webpack.config.js I guess it is not so easy to use both packages at the same time but what you did above has very little to do with the actual issue. @zonski patched his webpack.config.js to disable the chunk but I for example need to patch my webpack.config.js to have a second entry file...

levino avatar Dec 02 '19 07:12 levino

I have never used react-app-rewired but perhaps there is something that can be done in order to use them both. Might need some rewrite as both project act as a command to start your own project it seems.

Nargonath avatar Dec 02 '19 10:12 Nargonath

I managed to hack together a working setup for running cra-build-watch together with react-app-rewired. The issue boils down to the way create-react-app magically tricks other scripts to override the configuration passed to webpack. Another issue is that cra-build-watch per default adds entries to the webpack-config variable, these entries must not be there for the true power of react-app-rewired to do its job.

Given that I am extremely new to node, npm, and everything that has something to do with this sort of development environment I am sure that my way of doing things could be a lot cleaner. This is a "I have not slept for 2 days"-hack, so go easy on it.

When I have slept and have some time to spare I plan to either create a separate glue-npm module to make react-app-rewired and cra-build-watch work together, or submit clean pull-requests to both repos to make it easy to configure a dual setup (without the changes being too intrusive).


Two files were copied to my local $REPO_ROOT/scripts directory.

  • ORIG: node_modules/react-app-rewired/scripts/build.js => scripts/watch/index.js
          [email protected]
    
  •  ORIG: node_modules/cra-build-watch/scripts/index.js => scripts/watch/cra-build-watch.js
            [email protected]
    

The following changes makes things work (not the cleanest, mostly to show how things can be done).

From 96f0592e0087a2abacbcfc68fada1778d433761d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Filip=20Ros=C3=A9en?= <[email protected]>
Date: Wed, 13 Jan 2021 09:49:32 +0100
Subject: [PATCH] build: watch: react-app-rewired + cra-build-watch

---
 package.json                     |  3 +-
 scripts/watch/cra-build-watch.js | 68 +++++---------------------------
 scripts/watch/index.js           | 29 ++++++++++++--
 3 files changed, 37 insertions(+), 63 deletions(-)

diff --git a/package.json b/package.json
index 4eb5c68..9cc50bf 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,8 @@
     "start": "react-scripts start",
     "build": "react-app-rewired build",
     "test": "react-app-rewired test",
-    "eject": "react-scripts eject"
+    "eject": "react-scripts eject",
+    "watch": "node scripts/watch"
   },
   "eslintConfig": {
     "extends": "react-app",
diff --git a/scripts/watch/cra-build-watch.js b/scripts/watch/cra-build-watch.js
index 4686444..a5b9cd3 100644
--- a/scripts/watch/cra-build-watch.js
+++ b/scripts/watch/cra-build-watch.js
@@ -13,6 +13,14 @@ const ora = require('ora');
 const assert = require('assert');
 const exec = require('child_process').exec;
 
+const requireFoo = module => require(
+    path.resolve(
+        path.dirname(
+            require.resolve('cra-build-watch')
+        ) + '/' + module
+    )
+);
+
 const {
   flags: {
     buildPath,
@@ -25,8 +33,8 @@ const {
     afterInitialBuildHook,
     afterRebuildHook,
   },
-} = require('../utils/cliHandler');
-const { getReactScriptsVersion, isEjected } = require('../utils');
+} = requireFoo('../utils/cliHandler');
+const { getReactScriptsVersion, isEjected } = requireFoo('../utils');
 
 const { major, concatenatedVersion } = getReactScriptsVersion(reactScriptsVersion);
 
@@ -75,62 +83,6 @@ const resolvedBuildPath = buildPath ? handleBuildPath(buildPath) : paths.appBuil
 config.output.path = resolvedBuildPath;
 config.output.publicPath = publicPath || '';
 
-// Grab output names from cli args, otherwise use some default naming.
-const fileNameToUse = outputFilename || `js/bundle.js`;
-const chunkNameToUse = chunkFilename || `js/[name].chunk.js`;
-// If cli user adds .js, respect that, otherwise we add it ourself
-config.output.filename = fileNameToUse.slice(-3) !== '.js' ? `${fileNameToUse}.js` : fileNameToUse;
-config.output.chunkFilename =
-  chunkNameToUse.slice(-3) !== '.js' ? `${chunkNameToUse}.js` : chunkNameToUse;
-
-if (disableChunks) {
-  assert(major >= 2, 'Split chunks optimization is only available in react-scripts >= 2.0.0');
-  // disable code-splitting/chunks
-  config.optimization.runtimeChunk = false;
-
-  config.optimization.splitChunks = {
-    cacheGroups: {
-      default: false,
-    },
-  };
-}
-
-// update media path destination
-if (major >= 4) {
-  const oneOfIndex = 1;
-  config.module.rules[oneOfIndex].oneOf[0].options.name = `media/[name].[hash:8].[ext]`;
-  config.module.rules[oneOfIndex].oneOf[1].options.name = `media/[name].[hash:8].[ext]`;
-  config.module.rules[oneOfIndex].oneOf[8].options.name = `media/[name].[hash:8].[ext]`;
-} else if (major >= 2) {
-  // 2.0.0 => 2
-  // 2.0.1 => 3
-  // 2.0.2 => 3
-  // 2.0.3 => 3
-  // 2.0.4 to 3.0.0 => 2
-  const oneOfIndex = concatenatedVersion === 200 || concatenatedVersion >= 204 ? 2 : 3;
-  config.module.rules[oneOfIndex].oneOf[0].options.name = `media/[name].[hash:8].[ext]`;
-  config.module.rules[oneOfIndex].oneOf[7].options.name = `media/[name].[hash:8].[ext]`;
-} else {
-  config.module.rules[1].oneOf[0].options.name = `media/[name].[hash:8].[ext]`;
-  config.module.rules[1].oneOf[3].options.name = `media/[name].[hash:8].[ext]`;
-}
-
-let htmlPluginIndex = 1;
-let interpolateHtmlPluginIndex = 0;
-if (major >= 2) {
-  htmlPluginIndex = 0;
-  interpolateHtmlPluginIndex = 1;
-}
-
-// we need to override the InterpolateHtmlPlugin because in dev mod
-// they don't provide it the PUBLIC_URL env
-config.plugins[interpolateHtmlPluginIndex] = new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw);
-config.plugins[htmlPluginIndex] = new HtmlWebpackPlugin({
-  inject: true,
-  template: paths.appHtml,
-  filename: 'index.html',
-});
-
 spinner.succeed();
 spinner.start('Clear destination folder');
 
diff --git a/scripts/watch/index.js b/scripts/watch/index.js
index cbcfbda..5488bc0 100644
--- a/scripts/watch/index.js
+++ b/scripts/watch/index.js
@@ -1,12 +1,18 @@
 // ORIG: node_modules/react-app-rewired/scripts/build.js
 //       [email protected]
 
+
 process.env.NODE_ENV = 'production';
 
+const path = require('path');
+const requireFoo = module => require(
+    path.dirname(require.resolve('react-app-rewired')) + `/scripts/${module}`
+);
+
 const semver = require('semver');
 
-const { scriptVersion } = require('./utils/paths');
-const overrides = require('../config-overrides');
+const { scriptVersion } = requireFoo('./utils/paths');
+const overrides = requireFoo('../config-overrides');
 const scriptPkg = require(`${scriptVersion}/package.json`);
 
 const pathsConfigPath = `${scriptVersion}/config/paths.js`;
@@ -29,5 +35,20 @@ require.cache[require.resolve(webpackConfigPath)].exports = isWebpackFactory
   ? (env) => overrides.webpack(webpackConfig(env), env)
   : overrides.webpack(webpackConfig, process.env.NODE_ENV);
 
-// run original script
-require(`${scriptVersion}/scripts/build`);
+// override cra-build-watch/utils/cliHandler
+
+const cliHandler_path = require.resolve(
+    path.dirname(require.resolve('cra-build-watch')) + '/../utils/cliHandler'
+)
+
+require(cliHandler_path.replace(/\.js$/,''));
+require.cache[cliHandler_path].exports = {
+    flags: {
+        buildPath: 'build-cra/',
+        verbose: true,
+    }
+};
+
+// start cra-build-watch
+
+require('./cra-build-watch')
-- 
2.20.1

filiproseen-refp avatar Jan 13 '21 09:01 filiproseen-refp

@FilipRoseen-refp - thanks for that, it worked for me. It would be nice if there was an 'official' solution as this feels a little hacky and prone to breaking on updates to cra-build-watch and/or react-app-rewired

DicconTownsAngstrom avatar Sep 01 '21 15:09 DicconTownsAngstrom

Sorry I don't have time to maintain this project anymore so I'll archive it and add a note in the README. Feel free to fork it as you see fit.

Nargonath avatar Apr 24 '24 08:04 Nargonath