Creating a Single Bundle Configuration for Create React App
In this guide, I'll walk you through the process of configuring a Create React App (CRA) based project to generate a single JavaScript file and inline all CSS and JavaScript directly into the index.html
. This is particularly useful when the application needs to be embedded in environments that do not support multiple file references, such as certain mobile application frameworks.
Background
By default, CRA splits the application code into various chunks to optimize load performance. However, this default behavior can be altered to bundle the entire application code into a single file. Additionally, Gulp is used to inline all the assets into index.html
, creating a self-contained application.
Steps
The configuration involves two main steps:
- Disabling Code Splitting in CRA.
- Inlining all assets into
index.html
using Gulp.
Step 1: Disabling Code Splitting
To prevent CRA from splitting the code into chunks, we use react-app-rewired
along with customize-cra
. These tools allow us to modify the internal webpack configuration without ejecting.
- Install
react-app-rewired
andcustomize-cra
:
npm install react-app-rewired customize-cra --save-dev
- Create a
config-overrides.js
file in the root directory with the following content:
// config-overrides.js
const { override } = require("customize-cra");
module.exports = override((config) => {
config.optimization.splitChunks = {
cacheGroups: {
default: false,
},
};
config.optimization.runtimeChunk = false;
return config;
});
Step 2: Inlining Assets with Gulp
Gulp automates the inlining of CSS and JS into index.html
.
- Install Gulp and related plugins:
npm install gulp gulp-inline-source gulp-replace gulp-cheerio --save-dev
- Set up the
gulpfile.js
:
// gulpfile.js
const gulp = require("gulp");
const inlineSource = require("gulp-inline-source");
const replace = require("gulp-replace");
const cheerio = require("gulp-cheerio");
gulp.task("default", () => {
return gulp
.src("./build/*.html")
.pipe(
cheerio(($) => {
const scriptTag = $("script[defer]");
$("body").append(scriptTag);
})
)
.pipe(replace('.js"></script>', '.js" inline></script>'))
.pipe(replace('rel="stylesheet">', 'rel="stylesheet" inline>'))
.pipe(
inlineSource({
compress: false,
ignore: ["png"],
})
)
.pipe(gulp.dest("./build"));
});
Step 3: Environment Variables
Use a .env
file to set environment variables for the build process:
INLINE_RUNTIME_CHUNK=false
GENERATE_SOURCEMAP=false
SKIP_PREFLIGHT_CHECK=true
Step 4: Modifying package.json
Update the package.json to use react-app-rewired
:
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build && npx gulp",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
Note: Ensure that you remove any code that forces chunks, such as the following, from your application:
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
Step 5: Running the Build
After setting up, run the build command to generate the single bundle and inline assets:
npm run build
The build script will create a production build with a single JavaScript file, and the Gulp command will inline all resources into the index.html
.
Conclusion
Following this configuration allows you to package a CRA application into a single index.html
file with all assets inlined. This setup is suitable for use cases that require a standalone file for the entire application. It is recommended to thoroughly test the application after these modifications to ensure functionality remains intact.
Feel free to reach out if you have any questions or run into issues. Happy coding!
Top comments (0)