中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React遠程動態組件怎么實現

發布時間:2023-03-27 14:25:21 來源:億速云 閱讀:157 作者:iii 欄目:開發技術

這篇文章主要介紹了React遠程動態組件怎么實現的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇React遠程動態組件怎么實現文章都會有所收獲,下面我們一起來看看吧。

    遠程動態組件實現

    遠程動態組件庫

    遠程動態組件庫項目結構如下所示:

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

    我們簡單實現了兩個組件 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 目錄下開啟一個靜態文件服務,則可以通過 http://localhost:8080/Button.js 獲取到打包后的代碼。

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

    接入遠程組件庫

    我們使用 create-react-app 創建一個 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 參數 fallback 之中的內容,最后會使用加載成功的組件進行替換。接下來看看 fetchComponent 是如何實現的:

    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}
    }

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

    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 庫打包進去,所以這里需要實現 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

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

    關于“React遠程動態組件怎么實現”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“React遠程動態組件怎么實現”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    雅江县| 宁城县| 双桥区| 平乡县| 田阳县| 吉林市| 喀喇沁旗| 平潭县| 乌兰浩特市| 黄骅市| 石楼县| 阳曲县| 大渡口区| 宁远县| 西青区| 保康县| 焉耆| 和硕县| 乐业县| 江华| 德化县| 石泉县| 繁昌县| 札达县| 班玛县| 济南市| 兖州市| 武强县| 瓦房店市| 浠水县| 商河县| 南靖县| 江都市| 石棉县| 嘉鱼县| 桓台县| 象山县| 隆化县| 申扎县| 象州县| 祁阳县|