」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 Rspack 和 Modern.js 的微前端

使用 Rspack 和 Modern.js 的微前端

發佈於2024-11-04
瀏覽:994

Photo by Markus Spiske on Unsplash

Introduction

Web developers are beginning to take a strong interest in the idea of Micro-Frontends. Remix and Next.js are two examples of React meta-frameworks that have a lot of useful capabilities, but they don't always give complete support for creating micro-frontends. By providing built-in support for micro-frontends, Modern.js fills this gap and enables developers to design modular, scalable, and flexible apps.

Modern.js Framework

ByteDance created Modern.js, a progressive web framework built on React. Giving developers an outstanding development experience and empowering applications to provide better user experiences simplifies the process of creating contemporary web applications. In addition to having built-in state management, data gathering, and routing capabilities, Modern.js offers all required setups and tools for React applications.

Key features of Modern.js include:

  • Rust Bundler: The primary bundler is Rspack, however, it can be switched to Webpack.
  • Progressive: Facilitates the incremental integration of features via templates and plugins.
  • Integration: Offers isomorphic CSR and SSR development in a unified development and production environment.
  • Out of the Box: Provides debugging tools, ESLint, default TypeScript support, and integrated build tools.
  • Ecology: Module packaging, micro-frontend support, and integrated state management.
  • Routing Modes: Allows for file-convention-based and self-controlled routing.
  • With integrated micro-frontend functionality, Modern.js facilitates scalable, maintainable, and flexible apps while streamlining the development process.

Rspack

Rspack is a high-performance JavaScript bundler written in Rust, designed to be compatible with the webpack ecosystem while providing significantly faster build speeds.

Why Rspack?
Rspack was created to solve performance issues at ByteDance, where large app projects had excessively long build and startup times. Rspack addresses these problems with:

  • Fast Dev Mode Startup: Ensures quick startup to maintain developer productivity.
  • Quick Builds: Reduces CI/CD pipeline build times, improving productivity and application delivery.
  • Flexible Configuration: Maintains webpack's flexibility, easing the transition for legacy projects.
  • Optimized Production Builds: Enhances production optimizations with Rust's multithreading capabilities.

Let's start

This guide will walk us through setting up a Modern.js project, enabling micro-frontend capabilities, and configuring multiple applications to work together seamlessly. We will use pnpm as our package manager and Rspack as the bundler. The shell app will act as the main application that dynamically loads micro-frontends.

Step-by-Step Instructions

1. Initialize the Repository
Start by initializing a new pnpm project in the root directory.

pnpm init

This will create a package.json file to manage dependencies and scripts for your project.

2. Create the Shell Application
Next, create the shell application using Modern.js.

npx @modern-js/create@latest shell-app

( Note: npx @modern-js/create@latest will also commit new changes. So you might have to manually remove .git folder and keep it only on the top level: rm -rf .git )

Select the following options:

  • Project type: Web App
  • Programming language: TS (TypeScript)
  • Package manager: pnpm

  • In the latest versions, Rspack is used as the default bundler.

3. Run the Shell Application
Navigate into the shell application directory and start the development server.

cd shell-app
pnpm start

Running the application ensures everything is set up correctly. You should see the default Modern.js application running in your browser.

4. Enable Micro-frontend Features
Enable micro-frontend features for the shell application.

pnpm run new

Select the following options:

  • Operation: Enable Features
  • Feature: Enable Micro Frontend

Enabling micro-frontend features configures the project to support dynamic loading and micro-frontend integration, allowing us to build modular and scalable applications.

5. Update modern.config.ts
Modify the configuration file to include necessary plugins and runtime settings.

// shell-app/modern.config.ts
import { appTools, defineConfig } from '@modern-js/app-tools';
import { garfishPlugin } from '@modern-js/plugin-garfish';

export default defineConfig({
  runtime: {
    router: true,
    state: true,
    masterApp: {},
  },
  plugins: [appTools(), garfishPlugin()],
});

This configuration enables the router and sets up the shell app as a main application using the garfishPlugin.
(Garfish, developed by the ByteDance team, is a micro-frontend framework similar to single-spa. Modern.js handles the rest under the hood, so we don't need to focus much on it.)

6. Create Custom Entry and Update App.tsx
Remove the default routes folder and create a new App.tsx file in the src directory.

// shell-app/src/App.tsx
import { Suspense } from 'react';
import { defineConfig } from '@modern-js/runtime';
import {
  BrowserRouter as Router,
  Routes,
  Route,
} from '@modern-js/runtime/router';
import styled from '@modern-js/runtime/styled';

const AppContainer = styled.div`
  text-align: center;
  padding: 20px;
  background-color: #f5f5f5;
`;

const Title = styled.h1`
  color: #333;
`;

const Loading = styled.div`
  font-size: 1.2em;
  color: #666;
`;

const App: React.FC = () => {
  return (
    Loading...}>
          Welcome to the Shell Application}
            />
          
  );
};

export default defineConfig(App, {
  masterApp: {
    manifest: {
      getAppList: async () => {
        // here we will add our mfe
        return [];
      },
    },
  },
});

Here, we set up the main component for the shell application, configuring it as the master application that will manage micro-frontends.

7. Create the First Micro-frontend Application
Navigate back to the root directory and create the first micro-frontend.

cd ..
npx @modern-js/create@latest mfe1

Select the following options:

  • Project type: Web App
  • Programming language: TS (TypeScript)
  • Package manager: pnpm

8. Enable Micro-frontend Feature for mfe1
Enable micro-frontend features for the first micro-frontend application.

cd mfe1
pnpm run new

Select the following options:

  • Operation: Enable Features
  • Feature: Enable Micro Frontend

9. Update modern.config.ts for mfe1
Update the configuration file for the micro-frontend.

// mfe1/modern.config.ts
import { appTools, defineConfig } from '@modern-js/app-tools';
import { garfishPlugin } from '@modern-js/plugin-garfish';

export default defineConfig({
  server: {
    port: 8081,
  },
  deploy: {
    microFrontend: true,
  },
  plugins: [appTools(), garfishPlugin()],
});

This configuration sets the port and enables micro-frontend features.

10. Create Custom Entry and Update App.tsx for mfe1
Remove the default routes folder and create a new App.tsx file in the src directory.

// mfe1/src/App.tsx
import React from 'react';
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Link,
} from '@modern-js/runtime/router';
import styled from '@modern-js/runtime/styled';

const Container = styled.div`
  font-size: 1.2em;
  color: #333;
`;

const AppContainer = styled.div`
  text-align: center;
  padding: 20px;
  background-color: #f5f5f5;
`;

const NavBar = styled.nav`
  margin-bottom: 20px;
  a {
    margin: 0 10px;
    color: #007acc;
    text-decoration: none;
  }
`;

const Contact: React.FC = () => {
  return Contact Page;
};

const Home: React.FC = () => {
  return Home Page;
};

const About: React.FC = () => {
  return About Page;
};

const App: React.FC = () => {
  return (
    Home
          About
          Contact
        } />
          } />
          } />
        
  );
};

export default App;

Here, we set up the micro-frontend application with its routes and navigation.

11. Update the Root package.json
Add a start script in the root package.json to run both the shell app and the micro-frontend simultaneously.

{
  "name": "micro-frontends-with-modern.js-and-rspack",
  "version": "1.0.0",
  "description": "",
  "scripts": {
     "start": "pnpm --filter shell-app --filter mfe1 --parallel start"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

12. Update App.tsx in shell-app to Load mfe1
Modify the App.tsx file in the shell application to dynamically load and integrate the micro-frontend.

// shell-app/src/App.tsx
import React, { Suspense } from 'react';
import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
import { defineConfig } from '@modern-js/runtime';
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Link,
} from '@modern-js/runtime/router';
import styled from '@modern-js/runtime/styled';

const AppContainer = styled.div`
  text-align: center;
  padding: 20px;
  background-color: #f5f5f5;
`;

const Title = styled.h1`
  color: #333;
`;

const Loading = styled.div`
  font-size: 1.2em;
  color: #666;
`;

const App: React.FC = () => {
  const { MApp } = useModuleApps();
  return (
    Welcome to the Shell ApplicationLoading...}>
          
MFE1
> } />
); }; export default defineConfig(App, { masterApp: { manifest: { getAppList: async () => { return [ { name: 'mfe1', entry: 'http://localhost:8081/index.js', activeWhen: path => path.includes('mfe1'), }, ]; }, }, }, });

The useModuleApps hook returns sub-app components and gives us full control of routing.

13. Run Both Applications
Navigate back to the root directory and run the start script to launch both applications.

pnpm start

This command will start both the shell-app and mfe1 concurrently, allowing you to access mfe1 inside the shell-app and navigate its subroutes.

Vertical vs Horizontal splits for micro-frontends

We looked at the vertical split of micro-frontends in the previous section. The horizontal divide with module federation will be discussed in the following section. What do these splits indicate, though?

A horizontal split is a pattern in which various application components—manufactured by separate teams—are merged into a single view or path. Every team is in charge of particular features or portions of the page, which are then smoothly integrated. Because teams may operate independently without impacting the program as a whole, this enables parallel development and speedier deployment.

On the other hand, a vertical split separates the application into discrete micro-frontends, each in charge of a separate feature or area of the system as a whole. These micro-frontends operate as distinct, feature-rich programs that can be accessed via several URLs. Because each micro-frontend can be designed, deployed, and updated individually, this approach improves modularity and scalability.

Micro-frontends with Rspack and Modern.js

Adding mfe2 with Module Federation for Horizontal Split

This section will create mfe2 using Module Federation, focusing on a horizontal split. This means mfe2 will handle a specific part of the application's UI, such as a shared component or feature, that can be dynamically loaded and shared across different parts of the shell application.

1. Create the Second Microfrontend Application
Navigate back to the root directory and create the second micro-frontend ( since it's module-federation we can use not only Modern.js ):

cd ..
npx @modern-js/create@latest mfe2

Select the following options:

  • Project type: Web App
  • Programming language: TS (TypeScript)
  • Package manager: pnpm

2. Update modern.config.ts for mfe2
Update the configuration file to include module federation settings.
We added some additional configurations to make module federation work with Modern.js. You can use a regular React app with Rspack instead of Modern.js as well. Additional examples you can find here module-fedration examples.

// mfe2/modern.config.ts
import { appTools, defineConfig } from '@modern-js/app-tools';

export default defineConfig({
  server: {
    port: 8082,
  },
  source: {
    enableAsyncEntry: true,
  },
  plugins: [appTools({ bundler: 'rspack' })],
  tools: {
    rspack: (config, { rspack, appendPlugins }) => {
      // just to remove noise form ts
      if (config.output) {
        config.output.publicPath = 'auto';
        config.output.uniqueName = 'mfe2';
      } else {
        config.output = {
          publicPath: 'auto',
          uniqueName: 'mfe2',
        };
      }

      if (config.optimization) {
        delete config.optimization.splitChunks;
        delete config.optimization.runtimeChunk;
      }

      appendPlugins([
        new rspack.container.ModuleFederationPlugin({
          name: 'mfe2',
          library: { type: 'var', name: 'mfe2' },
          filename: 'static/js/remoteEntry.js',
          exposes: {
            './MFE2Component': './src/MFE2Component.tsx',
          },
          shared: {
            react: { singleton: true },
            'react-dom': { singleton: true },
          },
        }),
      ]);
    },
  },
});

3. Create MFE2Component
Create a new component that will be exposed via module federation.

// src/MFE2Component.tsx
import React from 'react';
import styled from '@modern-js/runtime/styled';

const Container = styled.div`
  font-size: 1.2em;
  color: #007acc;
`;

const MFE2Component: React.FC = () => {
  return This is MFE2 Component!;
};

export default MFE2Component;

4. Update the Shell App modern.config.ts
We need to add module fedration configuration in the Shell App to consume what mfe2 produce.

import { appTools, defineConfig } from '@modern-js/app-tools';
import { garfishPlugin } from '@modern-js/plugin-garfish';

export default defineConfig({
  runtime: {
    router: true,
    state: true,
    masterApp: {},
  },
  source: {
    // automatically generated asynchronous boundary via Dynamic Import, allowing the page code to consume remote modules generated by the module federation.
    enableAsyncEntry: true,
  },
  output: {
    disableTsChecker: true,
  },
  tools: {
    rspack: (config, { rspack, appendPlugins }) => {
      appendPlugins([
        new rspack.container.ModuleFederationPlugin({
          name: 'host',
          remotes: {
            mfe2: 'mfe2@http://localhost:8082/static/js/remoteEntry.js',
          },
          shared: {
            react: { singleton: true },
            'react-dom': { singleton: true },
          },
        }),
      ]);
    },
  },
  plugins: [
    appTools({
      bundler: 'rspack',
    }),
    garfishPlugin(),
  ],
});

5. Update the Shell App to Load mfe2
Update the App.tsx in the shell-app to dynamically load mfe2.

// shell-app/src/App.tsx
...
import MFE2Component from 'mfe2/MFE2Component';
...
 Welcome to the Shell Application

In this updated App.tsx, we've added a link to mfe2 and included it in the manifest configuration.

6. Run Both Applications
Navigate back to the root directory, and update the script.

// package.json
...
"scripts": {
    "start": "pnpm --filter shell-app --filter mfe1  --filter mfe2 --parallel start"
  },
...

Run the start script to launch all applications.

pnpm start

This command will start both the shell-app, mfe1, and mfe2 concurrently, allowing you to access mfe2 inside the shell-app and navigate its subroutes.

Conclusion

We have barely scratched the surface of Modern.js by concentrating on just a couple of its features: integrated micro-frontend capabilities and module federation using Rspack. This is merely a simple illustration to help you get ideas for using Modern.js and creating micro-frontends for your applications.

? Find the code for this article on GitHub.

版本聲明 本文轉載於:https://dev.to/kyrylobashtenko/micro-frontends-with-rspack-and-modernjs-2l2d?1如有侵犯,請洽[email protected]刪除
最新教學 更多>
  • 網站 HTML 程式碼
    網站 HTML 程式碼
    我一直在嘗試建立一個與航空公司相關的網站。我只是想確認我是否可以使用人工智慧生成程式碼來產生整個網站。 HTML 網站是否相容於博客,或者我應該使用 JavaScript?這是我用作演示的程式碼。 <!DOCTYPE html> <html lang="en">[](url...
    程式設計 發佈於2024-11-05
  • 像程式設計師一樣思考:學習 Java 基礎知識
    像程式設計師一樣思考:學習 Java 基礎知識
    本文介紹了 Java 程式設計的基本概念和結構。它首先介紹了變數和資料類型,然後討論了操作符和表達式,以及控制流程。其次,它解釋了方法和類,然後介紹了輸入和輸出操作。最後,本文透過一個工資計算器的實際範例展示了這些概念的應用。 像程式設計師一樣思考:掌握Java 基礎1. 變數與資料型別 ]Java...
    程式設計 發佈於2024-11-05
  • PHP GD 可以比較兩個影像的相似性嗎?
    PHP GD 可以比較兩個影像的相似性嗎?
    PHP GD 可以確定兩個影像的相似度嗎? 正在考慮的問題詢問是否可以使用以下命令確定兩個圖像是否相同PHP GD 通過比較它們的差異。這需要獲取兩個影像之間的差異並確定它是否完全由白色(或任何統一的顏色)組成。 根據所提供的答案,雜湊函數(如其他回應所建議的)不適用於此情境。比較必須涉及圖像內容而...
    程式設計 發佈於2024-11-05
  • 使用這些鍵編寫進階測試(JavaScript 中的測試需求)
    使用這些鍵編寫進階測試(JavaScript 中的測試需求)
    在本文中,您將學習每個高級開發人員都應該了解的 12 個測試最佳實踐。您將看到 Kent Beck 的文章“Test Desiderata”的真實 JavaScript 範例,因為他的文章是用 Ruby 編寫的。 這些屬性旨在幫助您編寫更好的測試。了解它們還可以幫助您在下一次工作面試中取得好成績。...
    程式設計 發佈於2024-11-05
  • 透過將 matlab/octave 演算法移植到 C 來實現 AEC 的最佳解決方案
    透過將 matlab/octave 演算法移植到 C 來實現 AEC 的最佳解決方案
    完畢!對自己有點印象。 我們的產品需要迴聲消除功能,確定了三種可能的技術方案, 1)利用MCU偵測audio out和audio in的音訊訊號,編寫演算法計算兩側聲音訊號的強度,根據audio out和audio in的強弱在兩個通道之間進行可選的切換,實現半雙工通話效果,但現在市面上都是全雙工...
    程式設計 發佈於2024-11-05
  • 逐步建立網頁:探索 HTML 中的結構和元素
    逐步建立網頁:探索 HTML 中的結構和元素
    ?今天標誌著我軟體開發之旅的關鍵一步! ?我編寫了第一行程式碼,深入研究了 HTML 的本質。涵蓋的元素和標籤。昨天,我探索了建立網站的拳擊技術,今天我透過創建頁眉、頁腳和內容區域等部分將其付諸實踐。我還添加了各種 HTML 元素,包括圖像元素和連結元素,甚至嘗試在單頁網站上進行內部連結。看到這些部...
    程式設計 發佈於2024-11-05
  • 專案創意不一定是獨特的:原因如下
    專案創意不一定是獨特的:原因如下
    在創新領域,存在一個常見的誤解,即專案創意需要具有開創性或完全獨特才有價值。然而,事實並非如此。我們今天使用的許多成功產品與其競爭對手共享一組核心功能。讓他們與眾不同的不一定是想法,而是他們如何執行它、適應用戶需求以及在關鍵領域進行創新。 通訊應用案例:相似但不同 讓我們考慮一下 ...
    程式設計 發佈於2024-11-05
  • HackTheBox - Writeup 社論 [已退休]
    HackTheBox - Writeup 社論 [已退休]
    Neste writeup iremos explorar uma máquina easy linux chamada Editorial. Esta máquina explora as seguintes vulnerabilidades e técnicas de exploração: S...
    程式設計 發佈於2024-11-05
  • 強大的 JavaScript 技術可提升您的編碼技能
    強大的 JavaScript 技術可提升您的編碼技能
    JavaScript is constantly evolving, and mastering the language is key to writing cleaner and more efficient code. ?✨ Whether you’re just getting starte...
    程式設計 發佈於2024-11-05
  • 如何在 ReactJS 中建立可重複使用的 Button 元件
    如何在 ReactJS 中建立可重複使用的 Button 元件
    按鈕無疑是任何 React 應用程式中重要的 UI 元件,按鈕可能用於提交表單或開啟新頁面等場景。您可以在 React.js 中建立可重複使用的按鈕元件,您可以在應用程式的不同部分中使用它們。因此,維護您的應用程式將變得更加簡單,並且您的程式碼將保持 DRY(不要重複自己)。 您必須先在元件資料夾...
    程式設計 發佈於2024-11-05
  • 如何在 Apache HttpClient 4 中實作搶佔式基本驗證?
    如何在 Apache HttpClient 4 中實作搶佔式基本驗證?
    使用Apache HttpClient 4 簡化搶佔式基本驗證雖然Apache HttpClient 4 已經取代了早期版本中的搶佔式驗證方法,但它提供了替代方法以實現相同的功能。對於尋求直接搶佔式基本驗證方法的開發人員,本文探討了一種簡化方法。 為了避免向每個請求手動新增 BasicHttpCon...
    程式設計 發佈於2024-11-05
  • 例外處理
    例外處理
    異常是運行時發生的錯誤。 Java 中的異常處理子系統可讓您以結構化和受控的方式處理錯誤。 Java為異常處理提供了易於使用且靈活的支援。 主要優點是錯誤處理程式碼的自動化,以前必須手動完成。 在舊語言中,需要手動檢查方法傳回的錯誤碼,既繁瑣又容易出錯。 異常處理透過在發生錯誤時自動執行...
    程式設計 發佈於2024-11-05
  • 如何在不使用「dangerouslySetInnerHTML」的情況下安全地在 React 中渲染原始 HTML?
    如何在不使用「dangerouslySetInnerHTML」的情況下安全地在 React 中渲染原始 HTML?
    使用更安全的方法在React 中渲染原始HTML在React 中,您現在可以使用更安全的方法來渲染原始HTML ,避免使用危險的SetInnerHTML 。這裡有四個選項:1。 Unicode 編碼使用Unicode 字元表示UTF-8 編碼檔案中的HTML 實體:<div>{`Firs...
    程式設計 發佈於2024-11-05
  • PHP 死了嗎?不,它正在蓬勃發展
    PHP 死了嗎?不,它正在蓬勃發展
    PHP 是一種不斷受到批評但仍在蓬勃發展的程式語言。 使用率:根據 W3Techs 的數據,截至 2024 年 8 月,全球 75.9% 的網站仍在使用 PHP,其中 43% 的網站基於 WordPress。使用PHP作為開發語言的主流網站中,超過70%包括Facebook、微軟、維基百科、Moz...
    程式設計 發佈於2024-11-05
  • PgQueuer:將 PostgreSQL 轉變為強大的作業佇列
    PgQueuer:將 PostgreSQL 轉變為強大的作業佇列
    PgQueuer 簡介:使用 PostgreSQL 實現高效能作業佇列 社區開發者您好! 我很高興分享一個項目,我相信該項目可以顯著簡化開發人員在使用 PostgreSQL 資料庫時處理作業佇列的方式。 PgQueuer,這是一個 Python 函式庫,旨在利用 PostgreS...
    程式設計 發佈於2024-11-05

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3