欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React 遠程動態(tài)組件實踐示例詳解

 更新時間:2023年03月27日 13:00:34   作者:Aaaaaaaaaaayou  
這篇文章主要為大家介紹了React 遠程動態(tài)組件實踐示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

背景

想象有這樣一個場景:A 團隊開發(fā)了一套組件庫,B 和 C 團隊都在各自的業(yè)務項目中使用了該組件庫。現(xiàn)在 A 團隊需要對某個組件進行更新(比如修改顏色),按照以往的做法,A 團隊需要先發(fā)布一個新的版本,然后其他兩個團隊各自更新業(yè)務項目中所依賴的組件庫的版本后發(fā)布上線。

有沒有更快速的方法呢?比如能否做到只更新組件庫,其他依賴它的項目可以自動獲取到其最新的版本,即實現(xiàn)遠程動態(tài)組件。答案是有的,Webpack 5 新增的 Module Federation 就可以實現(xiàn)這個需求,但是今天我們要討論的是另外一種方法。

遠程動態(tài)組件實現(xiàn)

遠程動態(tài)組件庫

遠程動態(tài)組件庫項目結構如下所示:

.
├── babel.config.js
├── package.json
├── rollup.config.js
└── src
    ├── Button.js
    ├── Text.js

我們簡單實現(xiàn)了兩個組件 ButtonText

import React from 'react'
export default ({children}) => {
  return <button style={{color: 'blue'}}>{children}</button>
}
import React from 'react'
export default ({children}) => {
  return <span style={{color: 'blue'}}>{children}</span>
}

我們使用 rollup 對其進行打包,之所以用 rollup 是因為其打包出來的代碼非常簡潔,方便我們查看,rollup 配置為:

import babel from 'rollup-plugin-babel'
import fs from 'fs'
const components = fs.readdirSync('./src')
export default components.map((filename) => {
  return {
    input: `./src/${filename}`,
    output: {
      file: `dist/${filename}`,
      format: 'cjs',
    },
    plugins: [babel()],
  }
})

打包后的結果如下所示:

.
├── dist
│   └── Button.js
│   └── Text.js

其中 Button.js 如下所示:

'use strict'
var React = require('react')
function _interopDefaultLegacy(e) {
  return e && typeof e === 'object' && 'default' in e ? e : {default: e}
}
var React__default = /*#__PURE__*/ _interopDefaultLegacy(React)
var Button = function (_ref) {
  var children = _ref.children
  return /*#__PURE__*/ React__default['default'].createElement(
    'button',
    {
      style: {
        color: 'blue',
      },
    },
    children
  )
}
module.exports = Button

然后我們使用 http-server 在 dist 目錄下開啟一個靜態(tài)文件服務,則可以通過 http://localhost:8080/Button.js 獲取到打包后的代碼。

遠程組件庫介紹完畢,接下來介紹業(yè)務項目中如何使用。

接入遠程組件庫

我們使用 create-react-app 創(chuàng)建一個 React 應用,并新增一個 DynamicComponent 組件:

const DynamicComponent = ({name, children, ...props}) => {
  const Component = useMemo(() => {
    return React.lazy(async () => fetchComponent(name))
  }, [name])
  return (
    <Suspense
      fallback={
        <div style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
          <span style={{fontSize: 50}}>Loading...</span>
        </div>
      }>
      <Component {...props}>{children}</Component>
    </Suspense>
  )
}
export default React.memo(DynamicComponent)

這里使用到了 React 中的 Suspense 組件和 React.lazy 方法,關于他們的用法這里不做過多解釋,整個 DynamicComponent 組件的含義是遠程加載目標組件,這個過程該組件會渲染傳入 Suspense 參數(shù) fallback 之中的內容,最后會使用加載成功的組件進行替換。接下來看看 fetchComponent 是如何實現(xiàn)的:

const fetchComponent = async (name) => {
  const text = await fetch(
    `http://127.0.0.1:8080/${name}.js?ts=${Date.now()}`
  ).then((a) => {
    if (!a.ok) {
      throw new Error('Network response was not ok')
    }
    return a.text()
  })
  const module = getParsedModule(text, name)
  return {default: module.exports}
}

該方法會發(fā)起網(wǎng)絡請求得到組件的代碼,并交給 getParsedModule 去解析,最后得到模塊返回。我們來看一下 getParsedModule 是怎么實現(xiàn)的:

const packages = {
  react: React,
}
const getParsedModule = (code) => {
  let module = {
    exports: {},
  }
  const require = (name) => {
    return packages[name]
  }
  Function('require, exports, module', code)(require, module.exports, module)
  return module
}

這里使用 Function 來運行傳入的代碼,因為打包遠程組件的時候并沒有將 react 庫打包進去,所以這里需要實現(xiàn) require 這個方法。

我們結合之前打包得到的 Button.js 來看這段代碼,它其實同下面這個代碼是等價的:

const packages = {
  react: React,
}
const getParsedModule = (code, moduleName) => {
  let module = {
    exports: {},
  }
  const require = (name) => {
    return packages[name]
  }
  ;((require, exports, module) => {
    'use strict'
    var React = require('react')
    function _interopDefaultLegacy(e) {
      return e && typeof e === 'object' && 'default' in e ? e : {default: e}
    }
    var React__default = /*#__PURE__*/ _interopDefaultLegacy(React)
    var Button = function (_ref) {
      var children = _ref.children
      return /*#__PURE__*/ React__default['default'].createElement(
        'button',
        {
          style: {
            color: 'blue',
          },
        },
        children
      )
    }
    module.exports = Button
  })(require, module.exports, module)
  return module
}

最后我們可以按照如下方式來使用 DynamicComponent 組件:

import DynamicComponent from './DynamicComponent'
function App() {
  return (
    <div>
      <DynamicComponent name='Button'>Click Me</DynamicComponent>
      <DynamicComponent name='Text'>Remote Component</DynamicComponent>
    </div>
  )
}
export default App

現(xiàn)在我們嘗試修改遠程動態(tài)組件庫中的組件,重新打包后就可以馬上看到修改后的效果了。

總結

本文介紹了一種實現(xiàn)遠程動態(tài)組件的方式,不過比較簡陋,事實上我們還有很多優(yōu)化的空間。比如按照現(xiàn)在的實現(xiàn)方式,如果頁面上面使用了兩個 Button,會發(fā)起兩次請求,這顯然不合理。針對這個問題,我們可以通過提前加載以及模塊緩存的方式來解決。

以上就是React 遠程動態(tài)組件實踐示例詳解的詳細內容,更多關于React 遠程動態(tài)組件的資料請關注腳本之家其它相關文章!

相關文章

  • React拖拽調整大小的組件

    React拖拽調整大小的組件

    這篇文章主要為大家詳細介紹了React拖拽調整大小的組件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • React?狀態(tài)管理工具優(yōu)劣勢示例分析

    React?狀態(tài)管理工具優(yōu)劣勢示例分析

    這篇文章主要為大家介紹了React?狀態(tài)管理工具優(yōu)劣勢示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • React SSR樣式及SEO的實踐

    React SSR樣式及SEO的實踐

    這篇文章主要介紹了React SSR樣式及SEO的實踐,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • React+Mobx基本使用、模塊化操作

    React+Mobx基本使用、模塊化操作

    React 和 MobX 是一對強力組合,React 通過提供機制把應用狀態(tài)轉換為可渲染組件樹并對其進行渲染,而MobX提供機制來存儲和更新應用狀態(tài)供 React 使用,這篇文章主要介紹了React+Mobx基本使用、模塊化,需要的朋友可以參考下
    2022-09-09
  • 基于webpack4.X從零搭建React腳手架的方法步驟

    基于webpack4.X從零搭建React腳手架的方法步驟

    這篇文章主要介紹了基于webpack4.X從零搭建React腳手架的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • React父組件調用子組件中的方法實例詳解

    React父組件調用子組件中的方法實例詳解

    最近做一個React項目,所有組件都使用了函數(shù)式組件,遇到一個父組件調用子組件方法的問題,下面這篇文章主要給大家介紹了關于React父組件調用子組件中方法的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • React中的useState和setState的執(zhí)行機制詳解

    React中的useState和setState的執(zhí)行機制詳解

    這篇文章主要介紹了React中的useState和setState的執(zhí)行機制,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • React中引入less、less-loader問題

    React中引入less、less-loader問題

    這篇文章主要介紹了React中引入less、less-loader問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 使用React+SpringBoot開發(fā)一個協(xié)同編輯的表格文檔實現(xiàn)步驟

    使用React+SpringBoot開發(fā)一個協(xié)同編輯的表格文檔實現(xiàn)步驟

    隨著云計算和團隊協(xié)作的興起,協(xié)同編輯成為了許多企業(yè)和組織中必不可少的需求,本文小編就將為大家介紹如何使用React+SpringBoot簡單的開發(fā)一個協(xié)同編輯的表格文檔,感興趣的朋友一起看看吧
    2023-11-11
  • ReactNative實現(xiàn)弧形拖動條的代碼案例

    ReactNative實現(xiàn)弧形拖動條的代碼案例

    本文介紹了ReactNative實現(xiàn)弧形拖動條,本組件使用到了react-native-svg和PanResponder,結合示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-02-02

最新評論