0.0.7 • Published 24 days ago

bossjob-remote v0.0.7

Weekly downloads
-
License
-
Repository
-
Last release
24 days ago

Bossjob 远程模块构建连接库

创建远程模块

  • 1 创建远程模块,远程模块基于vite。
yarn create vite
  • 2 安装bossjob-remote:
yarn add bossjob-remote
  • 3 在根目录下创建bossjob.config.js 一个工程可以包含多个模块
export default {
    remotePoints: [
        {
            id: 'chat',       // 模块唯一id
            ssr: false,       // 是否启用服务端渲染
            root: 'src/chat'  // 模块根目录,建议src/[module_id]
        },
        {
            id: 'chat-service',
            ssr: false,
            root: 'src/chat-service'
        }]
}
  • 4 为每个远程模块创建代码文件,以chat为例:
// src/chat/index.tsx
import App from "./App"
import { getInitialProps } from 'bossjob-remote/dist/clientStorage'
import React from "react"
import { createRoot } from 'react-dom/client';

function render() {
    const props = getInitialProps('chat')
    const container = document.getElementById('chat');
    const root = createRoot(container);
    root.render(<App {...props} />);
}
render()

如果启用ssr则改为:

// src/chat/index.tsx
import App from "./App"
import { getInitialProps } from 'bossjob-remote/dist/clientStorage'
import React from "react"
import { hydrateRoot } from 'react-dom/client';

function render() {
    const props = getInitialProps('chat')
    const container = document.getElementById('chat');
    hydrateRoot(container, <App {...props} />);
}
render()

界面主节点:

// src/chat/App.tsx
import React, { useState } from 'react';

function App() {
  const [count, setCount] = useState(0)
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  )
}

export default App

为每个module创建一个html入口文件: src/chat/index.html

<!doctype html>
<html >
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <div id="chat"></div>
    <script type="module" src="/src/chat/index.tsx"></script>
  </body>
</html>

如果使用了ssr 还需添加服务器文件用于编译:

// src/chat/renderer.js
import  { default as serverRenderer} from 'bossjob-remote/dist/serverRenderer'

export default serverRenderer

开发模式则添加:

// src/chat/renderer-dev.js
import  { default as serverRenderer} from 'bossjob-remote/dist/serverRenderer-dev'

export default serverRenderer

在命令行中执行编译:

bossjob build

完成编译后启动服务:

bossjob start

连接远程模块

  • 1 主工程中安装bossjob-remote:
yarn add bossjob-remote
  • 2 配置连接器,以next为例
// helpers/bossjobRemoteClient
import { getClient } from 'bossjob-remote/dist/client'
import Script from 'next/script'

const client = getClient({
    parseScript: (script, baseUrl) => {
        return <Script
            key={script.src + script.textContent}
            type="module"
            async
            crossOrigin={'anonymous'}
            src={script.src ? `${baseUrl}${script.src}` : undefined}>
            {script?.textContent?.replaceAll('\n', ';') ?? ''}
        </Script>
    },
    parseLink: (link, baseUrl) => <link
        key={link.href}
        rel={link.rel}
        href={`${baseUrl}${link.href}`}>
    </link>
})

export default client
  • 3 在页面的根layout中连接远程模块,可在同一页面连接多个模块,以chat,third为例,其中third为ssr模块
app/(chat-page)/layout.tsx
import bossjobClient from 'helpers/bossjobRemoteClient'

export default async function PublicLayout(props: any) {
  const config = { }
  const lang = ''
  const chatDictionary = { chat: {}}
  const userDetail = {}
  const data = {
    config,
    lang,
    chatDictionary: dictionary?.chat ?? {},
    chat_id,
    userDetail: userDetailRes?.data?.data
  }
  const chatModule = await bossjobClient.connectModule({
    id: 'chat',
    baseUrl: 'http://localhost:3000',
    initialProps: data,       // 传给远程组件初始化的props
    initalSharedData: {        
      CHAT_ID: +chat_id ? chat_id : null,
    }
  })
  const thirdModule = await bossjobClient.connectModule({
    id: 'third',
    baseUrl: 'http://localhost:3000',
    ssr: true
  })

  return (
    <html lang={lang} translate='no'>
      <head >
        {chatModule.inHead}
        {thirdModule.inHead}
      </head>
      <body >
        {thirdModule.inBody}
        {chatModule.inBody}
        <div id='next-app'>
          {thirdModule.component}
          {chatModule.component}
          {children}
        </div>
      </body>
    </html>
  )
}

数据通信

  • 主工程在连接子模块时可以传递initalProps
 const data = {
    config,
    lang,
    chatDictionary: dictionary?.chat ?? {},
    chat_id,
    userDetail: userDetailRes?.data?.data
  }
  const chatModule = await bossjobClient.connectModule({
    id: 'chat',
    baseUrl: 'http://localhost:3000',
    initialProps: data,       // 传给远程组件初始化的props
    initalSharedData: {        
      CHAT_ID: +chat_id ? chat_id : null,
    }
  })  
  • 子模块可以在入口文件使用getInitialProps接收此状态
// src/chat/index.tsx
import App from "./App"
import { getInitialProps } from 'bossjob-remote/dist/clientStorage'
import React from "react"
import { hydrateRoot } from 'react-dom/client';

function render() {
    const props = getInitialProps('chat')
    const container = document.getElementById('chat');
    hydrateRoot(container, <App {...props} />);
}
render()
  • 每个模块都可以发布共享状态,共享状态由id标记,相同id的状态会覆盖旧数据。
import { publishSharedData } from 'bossjob-remote/dist/clientStorage'

function publishChatId(chatId) {
  publishSharedData('CHAT_ID', chatId) 
}

其他节点可以用 useSharedData 监听数据变化。

import { useSharedData } from 'bossjob-remote/dist/clientStorage'
import { useEffect } from 'react'
const Page = () => {
    const chatId = useSharedData('CHAT_ID')
    useEffect(() => {
       ...
    }, [chatId])

    return (
        <>
        </>
    );
}
export default Page

其他节点可以用 useSharedData 监听数据变化。

import { watchSharedData } from 'bossjob-remote/dist/clientStorage'
 
function watchChatIdChange() {
    watchSharedData('CHAT_ID', (newChatId) => {
        ...
    });
}
export default Page
0.0.7

24 days ago

0.0.6

1 month ago

0.0.4-fix9

2 months ago

0.0.4-fix10

2 months ago

0.0.4-fix11

2 months ago

0.0.5

2 months ago

0.0.4-fix8

6 months ago

0.0.4-fix7

7 months ago

0.0.4-fix6

7 months ago

0.0.4-fix5

7 months ago

0.0.4-fix4

7 months ago

0.0.4-fix3

7 months ago

0.0.4-fix2

7 months ago

0.0.4-fix1

7 months ago

0.0.4

7 months ago

0.0.3-fix8

7 months ago

0.0.3-fix7

7 months ago

0.0.3-fix6

7 months ago

0.0.3-fix5

7 months ago

0.0.3-fix4

7 months ago

0.0.3-fix3

8 months ago

0.0.3-fix2

8 months ago

0.0.3-fix1

8 months ago

0.0.3

8 months ago

0.0.2-fix6

8 months ago

0.0.2-fix5

8 months ago

0.0.2-fix4

8 months ago

0.0.2-fix3

8 months ago

0.0.2-fix2

8 months ago

0.0.2-fix1

8 months ago

0.0.2

8 months ago

0.0.1-fix12

8 months ago

0.0.1-fix11

8 months ago

0.0.1-fix10

8 months ago

0.0.1-fix9

8 months ago

0.0.1-fix8

8 months ago

0.0.1-fix7

8 months ago

0.0.1-fix6

8 months ago

0.0.1-fix5

8 months ago

0.0.1-fix4

8 months ago

0.0.1-fix3

8 months ago

0.0.1-fix2

8 months ago

0.0.1-fix1

8 months ago

0.0.1

8 months ago