Search
⌘K
    to navigateEnterto select Escto close

    Bring React.js to Rails

    Adding React.js to Rails

    We will be building our application's frontend in React.js, and for this, we will be using react-rails gem to bring React to our Ruby on Rails application and hook it into the webpacker compilation system.

    Add the following line to the end of the Gemfile:

    1gem 'react-rails'

    Then install the newly added gem:

    1bundle install

    Now execute the following command to setup the Webpacker base:

    1bundle exec rails webpacker:install # enter n when prompted

    In the above command, enter n (no) when prompted and continue with the rest of its execution. This should be done to discard the overwriting of the existing config/webpacker.yml file that was generated during the project setup.

    Webpacker and webpack-dev-server compatibility issues

    Running the last command to install webpacker might have upgraded the webpack-dev-server version to v^4.x. If the webpacker version installed is v5.x then it might lead to compatibility issues with webpack-dev-server v^4.x.

    To workaround this issue, please follow the steps mentioned in setting a specific Webpacker version section.

    After re-installing the compatible versions for webpacker and webpack-dev-server check if the correct versions are installed using the following command:

    1yarn list --pattern "{webpacker,webpack-dev-server}"

    Setup React Webpacker pipeline

    Webpacker also contains support for integrating many of the popular JavaScript frameworks and tools. Here we are going to integrate ReactJS into our environment.

    When integrating ReactJs, the following commands will prompt you to overwrite the babel.config.js, since it works on adding the babel presets for React.

    Press y when prompted for this specific case, when running the following command:

    1bundle exec rails webpacker:install:react # enter y when prompted

    Please note that the overwrite made by the above command has removed a couple of entries from the plugins section of babel.config.js which was added while setting up the react environment.

    Let's first complete setting up the React-Webpacker pipeline by running the following command:

    1bundle exec rails generate react:install

    And now we have successfully added React.js support to our application.

    We have to delete the components folder which was automatically created upon running the above command, since we will be creating the same folder in the appropriate path later.

    Run the following from the root of project to delete the components folder:

    1rm -rf app/javascript/components

    Update the babel config

    Before committing the changes, let's also add the js-logger back into the plugins array of babel.config.js file, like so:

    1  plugins: [
    2      "js-logger",
    3      "babel-plugin-macros",
    4      "@babel/plugin-syntax-dynamic-import",
    5      isTestEnv && "babel-plugin-dynamic-import-node",
    6      "@babel/plugin-transform-destructuring",
    7      ...
    8  ]

    Remove unnecessary pack files

    Let's remove the unwanted files which were generated after running the above commands:

    1rm -rf app/javascript/packs/server_rendering.js app/javascript/packs/hello_react.jsx

    Keeping src folder as the entry point

    Running the previous Webpacker commands might have redeclared componentRequireContext with components as the argument in the application.js file.

    We have to remove those redeclaration's from packs/application.js if it exists.

    Thus fully replace app/javascript/packs/application.js with the following lines of code:

    1import "../stylesheets/application.scss";
    2
    3require("@rails/ujs").start();
    4require("@rails/activestorage").start();
    5require("channels");
    6
    7var componentRequireContext = require.context("src", true);
    8var ReactRailsUJS = require("react_ujs");
    9
    10ReactRailsUJS.useContext(componentRequireContext);

    We are retaining the declaration with src folder because src folder is the entry point in our application to load React components. Removing this declaration will lead to the failure of the app since the App component wouldn't be within the scope of our Rails view pipeline.

    Directory structure

    The src folder is where the JavaScript code specific to the application is handled at. This includes apis, commons etc.

    In upcoming chapters, when we create the components folder, we will be adding it under the src folder.

    This is done so as to handle all the JavaScript/client code under a single path and have more control over it.

    With the last change we made to application.js, we have ensured that Webpacker knows that our application relevant code and its context should be loaded from the src folder.

    The require.context statement within the packs/application.js is used to get the src folder context.

    If you want to load components or JavaScript files from a different directory, then override the path by calling ReactRailsUJS.useContext with a different argument. If require of such a path fails to find any relevant files or folder, then ReactRailsUJS falls back to the global namespace.

    Note: npm install command would add package-lock.json which isn't required as we are using Yarn. Thus avoid using npm install. If executed then please don't commit the package-lock.json file. Add package-lock.json to the .gitignore file. Use yarn add command for installing new packages.

    Now let's commit the changes:

    1git add -A
    2git commit -m "Added React.js to the project"
    Previous
    Next