項目目錄
- root
- apps
- app-1
- app-2
- pkgs
- utils
- hook
- apps
問題描述
使用lerna 管理微前端項目時, 開發的獨立工具包與項目依賴于同一vue版本, 工具包開發的hook工具,在項目中無法觸發視圖更新。
源碼
// pkgs/hook/useToggle.js
export function useToggle(initStatus?:any, reverseValue?:any){
const state = ref(initStatus === undefined ? false : initStatus)
const reverseValueOrigin = computed(() => { return reverseValue === undefined ? !initStatus : reverseValue })
function toggle(value?:any){
if(value !== undefined){
state.value = value === initStatus ? reverseValueOrigin.value : initStatus
}
state.value = state.value === initStatus ? reverseValueOrigin.value : initStatus
}
const setLeft = () => { state.value = initStatus }
const setRight = () => { state.value = reverseValueOrigin.value }
return {
state,
toggle,
setLeft,
setRight
}
// app-1
<template>
{{ state }}
<a-button @click='setLeft'> setLeft </a-button>
<a-button @click='setRight'> setRight </a-button>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useToggle } from '@micro/hooks'
export default defineComponent({
setup(){
const { state, setLeft, setRight } = useToggle('1', 0)
return {
state,
setLeft,
setRight
}
}
});
</script>
問題原因
嘗試將app-1和hooks包的vue版本打印比較后,我們能發現,當前存在兩個不同版本的vue包。 順著app-1的node_modules, 可以發現兩者的依賴問題。
我們知道npm的node_modules依賴查詢規則,遵守就近原則
, 既先查詢當前目錄的node_modules, 未查到時,再查詢父目錄的node_modules,以此類推。
使用lerna 安裝本地包時,本地包是以鏈接的方式將依賴直接指向開發包目錄。而開包包都需要安裝本地依賴,由此本地包查詢到的vue版本始終無法與項目依賴同步。
所以造成了vue視圖無法更新的問題。
解決方案
既然是依賴問題,那我們只要將依賴統一,問題自然就解決了。
這里使用了 workspaces
- 配置 workspaces
// 根目錄lerna.json
{
"npmClient": "yarn",
"useWorkspaces": true,
...
}
// 根目錄
"private": true,
"workspaces": [
"pkgs/*", // 依賴包目錄
"demo/*",
"eslint-config/*"
]
- 重構node_modules
// 清空node_modules
learn clean
// 重新安裝node_moduels
learn bootstrap