Can I turn off create-react-app chunking mechanism?
Asked Answered
I

6

17

I am setting up my React app project using create-react-app.

I was wondering if there is a way to turn-off the chunking mechanism that is built-in into the react scripts. The thing is that I need to fix the name of the bundle created on the build.

Interviewer answered 29/4, 2019 at 19:2 Comment(3)
Why do you have to fix the name?Commonly
I am developing VS Code extension and I need to import bundle. So, I need to know the name of it.Interviewer
Has anyone been able to do this with react-scripts 5.0.0 ?Apeak
B
16

It can be done by extending your CRA with react-app-rewired package which allows you to modify webpack config.

Changes needed to remove hash in build file names.

  1. Install react-app-rewired

npm install react-app-rewired --save-dev

  1. create config-overrides.js file in your root folder (where package.json is)

  2. place the following code to the config-overrides.js file. It keeps all CRA settings, only remove the hash part from filenames.

    module.exports = function override(config, env) {
        config.output = {
            ...config.output, // copy all settings
            filename: "static/js/[name].js",
            chunkFilename: "static/js/[name].chunk.js",
        };
        return config;
    };
  1. use the new config. In the package.json file in scripts section replace "build": "react-scripts build", with "build": "react-app-rewired build",

Unless you are going to change more configuration, it is enough to only use react-app-rewired in build. Otherwise replace react-scripts with react-app-rewired in others scripts except eject

Bonnette answered 2/9, 2020 at 10:38 Comment(3)
Any idea how to change CSS assets too?Hornsby
same problem here, how to change CSS assets?Pendragon
See my answer below for a suggested version that also handles css and media filesHabergeon
H
8

As others have pointed out you can try this with react-app-rewired instead of ejecting. Here is a version that also handles css and media files:

After installing npm install react-app-rewired --save-dev I created a config-overrides.js with the following content:

module.exports = function override(config, env) {
    if (env !== "production") {
        return config;
    }

    // Get rid of hash for js files
    config.output.filename = "static/js/[name].js"
    config.output.chunkFilename = "static/js/[name].chunk.js"

    // Get rid of hash for css files
    const miniCssExtractPlugin = config.plugins.find(element => element.constructor.name === "MiniCssExtractPlugin");
    miniCssExtractPlugin.options.filename = "static/css/[name].css"
    miniCssExtractPlugin.options.chunkFilename = "static/css/[name].css"

    // Get rid of hash for media files
    config.module.rules[1].oneOf.forEach(oneOf => {
        if (!oneOf.options ||  oneOf.options.name !== "static/media/[name].[hash:8].[ext]") {
            return;
        }
        oneOf.options.name = "static/media/[name].[ext]"
    });

    return config;
};
Habergeon answered 4/1, 2022 at 8:33 Comment(0)
I
7

I've found that you can disable chunking by setting splitChunks webpack configuration. For more details check https://github.com/facebook/create-react-app/issues/5306#issuecomment-431431877

However, this does not remove the contenthash part from the bundle name and you will still have that random string in the name.

To remove this, go to your webpack.config and edit the bundle name

'static/js/[name].[contenthash:8].js' => 'static/js/[name].js'

Interviewer answered 30/4, 2019 at 9:50 Comment(1)
Thanks, you probably saved us the ability to use the embedded React app in our project. Worked like a charm for issues related to embedding React app inside iframe.Jackpot
T
7

This is extended and improved version of Darko's answer. I created it mostly to save time for others who is not fully satisfied with solution mentioned in this comment and didn't have a patience to dig to this comment that solved the issue in much nicer way.

Main idea of this "hacky" approach is to re-write standard react-scripts's webpack configuration on the fly and inject it back to original scripts.

For that you would need to install rewire package from npmjs.org, like so:

npm install rewire --save-dev

Then you create separate build script that will will "wrap" original react build script and make sure that it will relieve corrected webpack configuration. Conventional way is to save this file inside ./scripts folder. So let's call it ./scripts/build.js. It's content:

const rewire = require('rewire');
const path = require('path');

// Pointing to file which we want to re-wire — this is original build script
const defaults = rewire('react-scripts/scripts/build.js');

// Getting configuration from original build script
let config = defaults.__get__('config');

// If we want to move build result into a different folder, we can do that!
// Please note: that should be an absolute path!
config.output.path = path.join(path.dirname(__dirname), 'custom/target/folder');

// If we want to rename resulting bundle file to not have hashes, we can do that!
config.output.filename = 'custom-bundle-name.js';

// And the last thing: disabling splitting
config.optimization.splitChunks = {
    cacheGroups: {
        default: false,
    },
};
config.optimization.runtimeChunk = false;

Then, we should use this build script instead of standard one in our packages.json, something like so:

...
  "scripts": {
    "start": "react-scripts start",
    "build": "node ./scripts/build.js",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
...
Teresiateresina answered 6/8, 2020 at 9:12 Comment(0)
C
4

There is a hack without needing eject:

  1. yarn add --dev rewire

  2. create file in root and name it build-non-split.js

  3. fill inside it by below codes:

    const rewire = require('rewire');
    const defaults = rewire('react-scripts/scripts/build.js');
    let config = defaults.__get__('config');
    
    config.optimization.splitChunks = {
        cacheGroups: {
            default: false,
        },
    };
    
    config.optimization.runtimeChunk = false;
    
  4. change the build script inside your package.json to:

    "build": "node ./scripts/build-non-split.js",
    
  5. yarn build

Chantalchantalle answered 24/2, 2021 at 14:17 Comment(3)
Possible source of this solution: github.com/facebook/create-react-app/issues/…Sumba
how do you make it work for css files as well ?Apeak
@MichelHua, I used css-in-js, if you want use other CSS methods, thats ok, you should import CSS as css-modules, like: import styles from './styles.css'; and then in using you must use it like: <Comp className={styles.container}>.Chantalchantalle
C
3

I don't know how to turn off chunking but what you could do try achieve you goal

Update to latest react and react-dom , run 'yarn react@next react-dom@next' (or npm command to do same)

You should now have the latest react versions - so you can code split using React.lazy/React.Suspense, use hooks and so on.

So now you can name your chunks using (component or dependency examples below)

 const MyComp = lazy(() =>   import(/* webpackChunkName: 'MyChunkNmame'
*/ './MyComp'), );

const myLib= await import(/* webpackChunkName: "myLib" */ 'myLib');

If you have an issue with errors when using the import syntax you need to use the babel-plugin-syntax-dynamic-import plugin. Put the "babel" field in your package json.

Now you can name your chunks and implement the latest way to code split - hope that helps. Here is a link to React.lazy React.Suspense - https://reactjs.org/blog/2018/10/23/react-v-16-6.html

Cly answered 30/4, 2019 at 8:55 Comment(1)
It is not what I am looking for but, thank you. Naming the chunks can definitely come handy in some cases. I've actually found a couple of GitHub discussions with similar questions. I'll write an answer soon.Interviewer

© 2022 - 2024 — McMap. All rights reserved.