Skip to content

Latest commit

 

History

History

react-rspack-tractor-2.0

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Tractor 2.0 + Rspack + MF + Zephyr Sample

A micro frontends sample implementation of The Tractor Store built with Module Federation and React. It's based on the Piral version.

Live Demo: TODO

About This Implementation

Technologies

List of techniques used in this implementation.

Aspect Solution
🛠️ Frameworks, Libraries React, Module Federation, Rspack
📝 Rendering SPA
🐚 Application Shell react-router
🧩 Client-Side Integration Module Federation
🧩 Server-Side Integration none
📣 Communication Custom Events, Slots
🗺️ Navigation SPA, One MF per Team, react-router
🎨 Styling Self-Contained CSS (No Global Styles)
🍱 Design System None
🔮 Discovery Zephyr Cloud
🚚 Deployment Static Page
👩‍💻 Local Development Rspack's devServer

Limitations

This implementation is deliberately kept simple to focus on the micro frontends aspects. URLs are hardcoded, components could be more DRY and no linting, testing or type-safety is implemented. In a real-world scenario, these aspects should be addressed properly.

Performance

Several performance optimizations could still be applied, however, in the out-of-the-box state with three micro frontends and multiple components / pages included we'll end up with a lighthouse score of 100/100, which is great.

How to run locally

Installation

Fork this repository. Then use pnpm to bootstrap the mono repo. Make sure to have pnpm (v9) installed for this.

Run the following command inside the repository:

pnpm install

Running the Code

  1. Build the explore app first

Because this project has recursive dependencies, you must comment out remotes that's yet build, and build the remotes first -- otherwise Zephyr won't be able to map your remotes against your host applications (or the application consumes it).

Note that each build command will trigger a deployment with Zephyr.

In the rspack.config.ts of explore, comment out the remotes (it's not built yet):

 new ModuleFederationPlugin({
      name,
      filename: 'remoteEntry.js',
      shared: ['react', 'react-dom', 'react-router', 'react-router-dom'],
      // remotes: {
      //   tractor_v2_checkout: 'tractor_v2_checkout@http://localhost:3001/remoteEntry.js',
      // },
      exposes: {
        './HomePage': path.resolve(__dirname) + '/src/HomePage.tsx',
        './CategoryPage': path.resolve(__dirname) + '/src/CategoryPage.tsx',
        './StoresPage': path.resolve(__dirname) + '/src/StoresPage.tsx',
        './Recommendations': path.resolve(__dirname) + '/src/Recommendations.tsx',
        './StorePicker': path.resolve(__dirname) + '/src/StorePicker.tsx',
        './Header': path.resolve(__dirname) + '/src/Header.tsx',
        './Footer': path.resolve(__dirname) + '/src/Footer.tsx',
      },
    }),

and run

WITH_ZE=true pnpm --filter tractor_v2_explore run build
  1. Build checkout app

At this point explore app has been build and checkout app is only consuming explore, we build the checkout app next:

WITH_ZE=true pnpm --filter tractor_v2_checkout run build
  1. Uncomment checkout in explore app

Run explore app's build again to build it to a full app, but uncomment the remotes in configuration file:

new ModuleFederationPlugin({
      name,
      filename: 'remoteEntry.js',
      shared: ['react', 'react-dom', 'react-router', 'react-router-dom'],
       remotes: {
         tractor_v2_checkout: 'tractor_v2_checkout@http://localhost:3001/remoteEntry.js',
       },
      exposes: {
        './HomePage': path.resolve(__dirname) + '/src/HomePage.tsx',
        './CategoryPage': path.resolve(__dirname) + '/src/CategoryPage.tsx',
        './StoresPage': path.resolve(__dirname) + '/src/StoresPage.tsx',
        './Recommendations': path.resolve(__dirname) + '/src/Recommendations.tsx',
        './StorePicker': path.resolve(__dirname) + '/src/StorePicker.tsx',
        './Header': path.resolve(__dirname) + '/src/Header.tsx',
        './Footer': path.resolve(__dirname) + '/src/Footer.tsx',
      },
    }),
WITH_ZE=true pnpm --filter tractor_v2_explore run build
  1. Build decide

Since explore and checkout are both being built, you can run this command to build decide (decide consumes explore and checkout, they are both built at this point ):

WITH_ZE=true pnpm --filter tractor_v2_decide run build
  1. Build app

All the remotes are being built now and Zephyr will be able to map your remote application in output bundle, you can build app directly by running:

WITH_ZE=true pnpm --filter tractor_v2_app run build

Deploy to Zephyr Cloud

You can deploy to Zephyr Cloud building the packages:

WITH_ZE=true pnpm build

Or deploy to cloud on each save by running:

WITH_ZE=true pnpm serve
We have now deployed everything! You can open our Chrome Extension,

Select this application on Chrome Extension, toggle on Live reload to inspect file changes while running WITH_ZE=true pnpm serve

More Information

The Piral documentation page has a tutorial on the sample that this example was based on. Make sure to follow and understand the tutorial before going deep into this sample.