8000 GitHub - Shiung/inno-im-monorepo
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Shiung/inno-im-monorepo

Repository files navigation

IM-Monorepo


Related Document


Requirement

Build Tool : Turbo ≥ 1 Package Manager : Pnpm ≥ v8 Environment : Node ≥ v16.x

Pnpm v.s Node Version Compatibility

turbo 需要安裝在電腦全域的 npm module (或許能只安裝在專案內,需測試)


Folder Structure

apps

For more detail see README .

packages

For more detail see README .


Release Flow

For more detail see README .


Version

im 上版後要在線上環境確認版號,可以透過下面方式:

  1. 進到平台的線上環境

https://en-vd004-tiger-portal.innodev.site/

  1. 進到平台廣場

im

  1. 打開 devtool 輸入 _version_,便可查到現在線上版本以及 git commit sha

im

細節:apps/library/src/utils/versionInfo.ts

Mock Data Server

For more detail see README .


LocalStorage

目前有一些供測試或是與 universe-portal-wap/ 相關的 localStorage 變數在使用:

  1. imVIPNotify : 記錄專家頁面隱藏金色鎖頭的過期時間
  2. dev : 設為 true 打開 ws 的 debug mode,可以參考 聊天室文件
  3. locale : im 內的語系,會與平台的 locale.current 同步
  4. mock : 設為 true 改打 mock data server
  5. dev_login : 設為 true 可以在 im 專案執行平台登入動作
  6. imAllowTranslate : 是否打開翻譯的參數 allow = 是, not-allow = 否, default = 看預設值

目前散落在專案各處,未來可以統整在一起。


Local Development

因為 im-monorepo 是打包後被平台透過 npm 安裝下來的, 在本地若需測試兩個專案一起的話, 是透過 vite watch mode 的方式將專案打包至本地 universe-portal-wap 底下的 node_modules/im-library,是透過 .env 設定來控制打包路徑。

操作方式:

  1. 將專案底下 apps/library/.env.development 複製一份並取名 .env
cp ./apps/library/.env.development ./apps/library/.env
  1. .env 檔案內的 PLATFORM_OUT_DIR 參數修改成自己電腦裡 universe-portal-wapnode_modules/im-library 路徑
PLATFORM_OUT_DIR="{UNIVERSE_PORTAL_WAP_PROJECT_PATH}/node_modules/im-library"
  1. apps/library/ 底下執行指令以 watch mode 形式打包到 universe-portal-wap
cd apps/library

pnpm run build:library-watch
  1. 啟動 universe-portal-wap 專案

  2. 只要 im-monorepo 中有檔案異動,都會重新打包一次放到平台底下


Embedded In Platform

For more detail see README .


Theme

theme map

在專案啟動的時候根據 env-config 中的業主代號去抓該業主的主題色 mapping。

目前只有分谷歌瑞銀兩主題色,其他業主都會是這兩個其中之一。

// packages/utils/vdThemeGenerator/map.ts

const themeMap = {
  vd001: theme.ruiYin,
  vd002: theme.guGe,
  vd003: theme.guGe,
  vd004: theme.ruiYin,
  // vd005: theme.guGe,
  vd006: theme.guGe,
  vd007: theme.ruiYin,
  vd008: theme.guGe,
  vd009: theme.ruiYin
}

ruiYin: {
  primary: '76 158 234', // #4C9EEA
  secondary: '80 189 255' // #50BDFF
},
guGe: {
  primary: '12 24 108', // #0C186C
  secondary: '80 84 255' // #5054FF
}

取到對應的主題色 mapping 表後,用 js 將 mapping 表 轉換成 css 變數表 並以 <style></style> 包裹後插入至 <head></head>

<style>:root {--im-monorepo-primary:76 158 234;
--im-monorepo-secondary:80 189 255;
}</style>

因為專案也有使用 tailwindcss,所以也會定義 extend color。 細節: packages/tailwind-config/tailwind.present.cjs.

colors: {
  imprimary: {
    DEFAULT: 'rgb(var(--im-monorepo-primary))'
  },
  imsecondary: {
    DEFAULT: 'rgba(var(--im-monorepo-secondary))'
  }
}

getVendorTheme utils

這個 utils function 主要是用來取圖片用的,有些分業主的圖片檔會放在 vd002 / vd004 的資料夾內,這個 utils 會去決定要去哪個資料夾底下拿。

// packages/utils/getVendorTheme/index.ts
switch (VENDORID) {
  case 'vd001':
  case 'vd004':
  case 'vd007':
  case 'vd009':
    return 'vd004'
  case 'vd002':
  case 'vd003':
  case 'vd006':
  case 'vd008':
    return 'vd002'
  default:
    return
}

Locales

script

For more detail see README .

global storage

For more detail see README .

anchor

主播有一個語系機制比較特別:

  1. 因為廣場資料來源是串接 51 第三方,而第三方語系跟我們的語系有差異,需要做對應
  2. 後台可以控制哪些語系的主播可以呈現在前台,又分為指定語系與預設語系
flow chart

anchor-language-mechanism


Device

im 專案也有做 rwd 的設計,而實作方式基本上與 universe-portal-wap 的機制相同。

  • md: 375px (手機)
  • lg: 600px (平板)
  • xl: 1024px (電腦)
  1. 在專案啟動時透過 vite.config 將裝置尺寸設定從 tailwind.config 讀取進來
  2. 將設定透過 vite.configdefine 功能定義至 process.env.SCREENS 變數
  3. 註冊一個全域的 resize 事件監聽當前畫面尺寸,再跟上述設定值做比對分辨現在屬於哪一種裝置。

兩種根據尺寸做調整樣式/功能的方法:

  1. tailwind responsive design
  2. 全局 svelte/store, isMd, isLg, isXldeviceSize
// tailwind
<div class='color-red lg:color-blue xl:color-green'></div>

// svelte(js) 
{#if $isXl}
  <div>我是電腦版看到的</div>
{:else if $isLg}
  <div>我是平板看到的</div>
{:else}
  <div>我是手機版看到的</div>
{/if}

Chatroom

For more detail see README .


Postcss Root Selector

im 專案與 universe-portal-wap 專案都有在使用 tailwindCSS 寫樣式,之前遇到一個問題:

平台的樣式因為 RWD 的需求會有 media-query 的樣式覆寫:

<div class='color-red-500 lg:color-blue-500 xl:color-white'></div>

可是 media-query 與一般樣式是屬於同層級的選擇器,只因載入順序與尺寸影響。 所以如果有一個一模一樣的樣式在載入順序上比平台的更後面時,會導致就算平台有使用 media-query,還是會被同名的樣式覆蓋。

EX:

// 載入 bundled CSS 的順序:
// 1. 平台 color-red-500 
// 2. 平台 lg:color-blue-500
// 3. 平台 xl:color-white
// 4. im color-red-500 

<div class='color-red-500 lg:color-blue-500 xl:color-white'></div>

這時候前面的 media-query 的樣式就會因為載入順序的關係被 im 的樣式覆蓋。

workaround:

引入 postcss-add-root-selector 套件,將 im 打包的 css 全部都加上 .im-library 的前綴,以此來跟平台的樣式區隔開,平台就不會在同名的 class 去引入 im 的樣式。

drawbacks:

所有會在平台底下使用的 im 組件都必須包裹一個有 .im-library 的外層 html 元素,包含會 portal 到 body 的也是。

如果有些 im 暴露出去的元素是套件 (ex: mobile-select.js),且能確保套件的樣式不會影響到平台,可以在 postcss.config.cjs 加上 exclude option 去濾掉某些樣式檔不用加前綴這件事。

// postcss.config.cjs
module.exports = {
  plugins: {
    // ...
    'postcss-add-root-selector': {
      rootSelector: '.im-library',
      exclude: ['mobile-select.css']
    }
  }
}

Unit Testing

專案有用 testing-library, vitest 做單元測試。

跑測試會涵蓋 library,ui,utils 及 api 底下的 *.{test,spec}.{ts,js...} 的檔案。

# testing
pnpm run test

# testing in watch mode
pnpm run test:watch

unit-testing 目前大多用來測試 function, class 的正確性,比較少用來測試組件。 因為 unit-testing 不好用來測試有異步行為邏輯的組件 (ex: 在生命週期下執行業務邏輯的行為),組件多半是測試傳入 props 後的行為、event 觸發行為等等。

測試範例可以參考: packages/utils/amount/amount.test.ts


Issues

  1. type declaration

    現在打包到平台使用的 svelte 組件沒有做 .d.ts 檔的宣告,所以只能暴力的使用 //@ts-ignore 去忽略報錯。

    svelte 官方提供的套件包 svelte-package/svelte2tsx 是針對某個根路徑去產生底下所有的 .d.ts,但是 im 專案只有導出特定模組,就算針對根目錄 platform/ 去跑指令,底下的模組又會引用其他非 platform/ 底下的模組,產生出來的 .d.ts 路徑 也會有問題。

    詳情可參考檔案: apps/library/env_scripts/generateDts.mjs

    # apps/library/
    pnpm run dts-generate

    workaround:

    1. 跑完官方提供套件後透過 shell 腳本去解決路徑問題並放到 release/ 底下。
    2. 手動定義 .d.ts 宣告

  1. Version Control

    現在專案沒有走正常的 gitlab CI/CD 流程,而是完全透過 shell script 來做上版。 會有一個很嚴重的問題,程式碼可以不經過版控系統直接推至遠端 repo。 因為只透過 shell script 檢查版號是否一致,只要更動版號後就算在本地的程式碼也能夠直接推至 im-library repo,而且 im-library repo 也沒有做嚴格的分支保護,此情況下是可能完全找不到問題點的。

    workaround:

    • 專案改走正規 gitlab CI/CD 流程

  1. 聊天室偶發斷線問題

    之前 QA 有測出聊天室會斷線

    發生異常:

    1. 送訊息都沒有回應,重整以後沒有看到之前送出的訊息
    2. 推測有連線成功但送訊息沒有回應,重整後有看到之前送出的訊息

    推測問題原因:

    1. 可能平台用戶 token 已經過期,沒有做重新登入(flutter 有做)
    2. 後端的 push message 有異常。

    之後若再發生可能需與移動端討論當時如何實作這個登入機制,以及去看 sports-chatroom 專案是否有做什麼特殊處理。


  1. svelte context module

    串接平台 的部分有提到,目前與平台溝通都是透過 svelte 提供的 context module 來在平台註冊對應的 callback/setter

    隱憂:

    如果未來需求需要掛載複數個同樣的組件到平台內,因為 context module static state 的特性,所有組件都會共享這個狀態,會造成組件互相影響、狀態管理受到污染。

    workaround:

    1. svelte 有提供類似 react ref 的功能,能夠呼叫組件實例內部暴露的方法,再搭配 react ref 或許能做到從 SvelteAdapter 呼叫綁定的 svelte component 內部的 method/state,就能將狀態切割開來。

    2. 一樣使用 context module 的方式,但是多一層維度去管理各個創建的組件。可以用像是 map 去對每個創建的組件存放屬於它自己的狀態與方法。

  2. svelte in react

    在串接平台專案時有遇到的一些問題:

    1. react 在觸發 re-create component 時 (key bindnew component) 會先產生新的 component 才會清掉舊的,這會導致 svelte 的組件在其生命週期執行順序上會有問題(ex: 聊天室訂閱,先訂閱新的又被清掉訂閱)。

    workaround:

    暫時的解法都是先共用同一個組件,勁量不做 re-create 的動作。

    1. react-redux 在執行 dispatch event 時會影響到 svelte store reactive syntax 的機制,如果同時執行會導致 reactive syntax 失效。

    workaround:

    改成使用 store subscribe 的方式去做狀態響應式處理。


local storage

dev true mock true

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 6

0