CRA cli is no longer maintained, which alternative we should use?
Mahek Jariwala

Mahek Jariwala @mhjariwala

About: Hey there, This is Mahek Jariwala. I am a Senior Frontend Developer helping company to build complex and good looking web application and websites. I would love to read and write a blog.

Location:
Surat, India
Joined:
May 14, 2020

CRA cli is no longer maintained, which alternative we should use?

Publish Date: Mar 26
0 0

The CRA cli is no longer maintained. Most of the Software companies are using CRA(Create React App) CLI for development and to create build.
When web application codes grow, the CRA takes long time to run web application and to create build of the web application.

Now, It's time to migrate your project on new build tool. There is a tool called Rsbuild which we are going to use for our project. This build tool improve the development (application start time) and build time of your project.

What is Rsbuild?
Rsbuild is a build tool which is built using RsPack. The RsPack is bundler which is built using Rust programming language. The rust process your application code in parallel and create bundle file. RsPack provide webpack compatible syntax. Also, Rsbuild provide plugin based configuration which makes it easier to configure your web application. So, you can easily migrate from CRA to Rsbuild.

Note: Install node version 18 or above.

Migration steps:

  • Remove CRA based dependencies (react-scripts)
For yarn based project:
yarn remove react-scripts

For npm based project:
npm remove react-scripts
Enter fullscreen mode Exit fullscreen mode
  • Install rsbuild related dependencies as dev dependencies:
For yarn:
yarn add @rsbuild/core @rsbuild/plugin-react -D

For npm:
npm add @rsbuild/core @rsbuild/plugin-react -D
Enter fullscreen mode Exit fullscreen mode

@rsbuild/core: Provide core packages and methods to build webapps like defineConfig, loadEnv, etc.

@rsbuild/plugin-react: Provide react based plugin to add support of using react based feature in your application.

  • Replace react-scripts related development and build script with rsbuild related script in your package.json file:

Image description

 "start": "rsbuild dev",
 "build": "rsbuild build",
 "preview": "rsbuild preview"
Enter fullscreen mode Exit fullscreen mode
  • Create configuration file(rsbuild.config.ts or rsbuild.config.js) in same folder where you have package.json file.
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';

export default defineConfig({
  plugins: [pluginReact()],
});
Enter fullscreen mode Exit fullscreen mode

defineConfig: Provided by core package to define configuration for your project.
pluginReact: This is used to add react support in your project.
plugins: A list of plugins that your project need.

  • CRA inject Environment variable starts with REACT_APP_ into your source code, while RsBuild inject environment variable start with PUBLIC_ into your source code. If you want to keep using REACT_APP_ prefix for environment variable then you have to provide configuration to inject environment variable start with REACT_APP_ into your source code.
import { defineConfig, loadEnv } from '@rsbuild/core';

const { publicVars } = loadEnv({ prefixes: ['REACT_APP_'] });

export default defineConfig({
  source: {
    define: publicVars,
  },
});
Enter fullscreen mode Exit fullscreen mode

loadEnv: Provided by core package. This is used to get environment variables which have specific prefix. It returns an object that contain publicVars property that you can inject into your source code.

source.define: This config used to manually inject env variables into source code.

  • The CRA uses public/index.html file as a template file, where it will add bundle file. In rsbuild, you need to inform rsbuild that you want to use public/index.html file as a template file using html.template option..
export default defineConfig({
  html: {
    template: './public/index.html',
  },
});
Enter fullscreen mode Exit fullscreen mode
  • In CRA, There is %PUBLIC_URL% prefix used as part of assets public path in index.html file(available in public folder). To make it work with Rsbuild, You need to replace %PUBLIC_URL% with <%= assetPrefix %>.
  <link rel="icon" href="<%= assetPrefix %>/favicon.ico" />
Enter fullscreen mode Exit fullscreen mode
  • Now if your project have used assets like png,jpeg, etc. then, in you need to handle this assets by using asset loader(asset/resource) in rsbuild config. You can use tools.rspack to add this loader for partiular assets file.
import { defineConfig } from '@rsbuild/core';

export default defineConfig({
  tools: {
    rspack: {
      module: {
        rules: [
          {
            // Match .png asset
            // You can change this regular expression to match different types of files
            test: /\.png|jpg|jpeg$/,
            type: 'asset/resource',
            generator: {
              filename: 'static/media/[name].[hash][ext]',
            },
          },
        ],
      },
    },
  }
})
Enter fullscreen mode Exit fullscreen mode

generator.filename: Used to inform rsbuild about how to generated filename. Here, filename generated based on actual name, content of the file and extension of the file.

  • If you are using SVG as a ReactComponent(feature provided by CRA) then, you have to handle this using SVGR plugin.
// import svg as React Component.
import { ReactComponent as Logo } from './logo.svg';

const Header = () => (
  <div>
    <Logo />
  </div>
);
Enter fullscreen mode Exit fullscreen mode

To add a support of using SVG as React Component, you need to install and register @rsbuild/plugin-svgr plugin in plugin list.

Install:
yarn add @rsbuild/plugin-svgr -D

Register:
export default defineConfig({
  plugins: [pluginReact(), pluginSvgr({ mixedImport: true })],
})
Enter fullscreen mode Exit fullscreen mode

mixedImport: this option allow us to import svg as it is or allow svg to import as a ReactComponent.

Normal import:
import logoURL from './static/logo.svg';

Named import:
import { ReactComponent as Logo } from './logo.svg';
Enter fullscreen mode Exit fullscreen mode
  • By default, CRA put output files in build directory whereas rsbuild put output files in dist directory. You can change this configuration in rsbuild using following config.
export default defineConfig({
 output: {
    distPath: {
      root: 'build',
    },
  },
})
Enter fullscreen mode Exit fullscreen mode

output.distPath.root: This configuration tells rsbuild to put output files in build folder.

  • (Optional) If you are using css preprocessors like sass or less in CRA app then, you have to install and register related plugin in plugin list of rsbuild configuration.
For sass:
Install plugin:
yarn add @rsbuild/plugin-sass -D

Register:
export default defineConfig({
  plugins: [pluginSass()],
});
Enter fullscreen mode Exit fullscreen mode

-(Optional) Rsbuild is not performing type check while converting ts code to js code. If you want rsbuild to perform type check then there is a plugin called @rsbuild/plugin-type-check that you need to install it as a dev dependencies and add it in plugin list of configuration.

import { pluginTypeCheck } from "@rsbuild/plugin-type-check";

defineConfig({
  plugins: [pluginTypeCheck()],
});
Enter fullscreen mode Exit fullscreen mode

That is all you need to do to migrate from CRA to rsbuild. I know there are lots of steps involve but, You can see the difference in development and build time after you migrate your project to rsbuild.

Here is the final configuration file.

import { defineConfig, loadEnv } from "@rsbuild/core";
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginSvgr } from '@rsbuild/plugin-svgr';

// Get all the process.env variables start with REACT_APP_
const { publicVars } = loadEnv({ prefixes: ['REACT_APP_'] });

export default defineConfig({
  plugins: [pluginReact(), pluginSvgr()],
  html: {
    template: './public/index.html', // Use index.html of public dir as a template.
  },
  source: {
    define: publicVars // inject env variables to the the client code through source.define.
  },
  output: {
    distPath: {
      root: 'build' // Change the folder where you want to store you distributable file.
    }
  }
})
Enter fullscreen mode Exit fullscreen mode

Now you can install dependency using yarn or npm. If any dependency failed to install then, try to upgrade that dependency to the latest one and again install other deps. After that, run your application using yarn start (for yarn based project) or npm start(npm based project). Now your project is running using rsbuild.

If you face any issue in above steps, please do comment in below steps. I will try to help you in fixing that issue.

Comments 0 total

    Add comment