背景:公司有项目A、B、C,A、B、C中均有相同的功能模块,为了方便相同部分代码的后续开发与维护工作,故将相同部分提出来变成base项目,A、B、C项目继承base,无须再写公共部分功能,只需开发各自的功能即可。
同时对于base项目的代码开发与维护工作,团队相应成员都有权限进行操作。
对于公共项目的管理,目前市面上有模块联邦、npm包、monorepo、qiankun、subtree、submodule等集中管理方式。
又因为领导对base项目的要求,仅是代码块即可,不需要变成一个独立运行的项目;可以进行版本控制。
故选择subtree方式进行代码管理。
git subtree add --prefix=src/components http://gitlab.local/basei.git master
说明:--prefix=src/components //在父项目存放的位置
http://gitlab.local/basei.git //子项目存放的远端地址
master //base项目的分支名称
git add .
git commit -m '提交子项目修改项'
// 退回到项目的根路径提交到远端
git subtree pull --prefix=src/components http://gitlab.local/basei.git master // 拉取远端最新代码
git subtree push --prefix=src/components http://gitlab.local/basei.git master // 提交本地base代码至远端
// 将子项目地址作为一个remote,名称为【base】在父项目执行:
git remote add -f base http://gitlab.local/basei.git
git subtree add --prefix=trunk/front-end/src/base base master // 全路径
* 以上操作会将整个子项目的提交历史合并到父存储库中
* 更新
` git subtree pull --prefix=trunk/front-end/src/base base master `
* 提交--会在远端生成一个叫hotfix/components_xxx的分支
` git subtree push --prefix=trunk/front-end/src/base base master `
* 删除当前remote
` git remote remove base `
base中的store
// state.ts
import { MessageInfo } from '../types/message.interface'
export interface State {
webSocketMessage: MessageInfo
}
export const state: State = {
webSocketMessage: {
type: "",
body: null,
regionId: 0
}
}
// mutation.ts
export default {
setWebSocketMessage(state: State, value: MessageInfo) {
state.webSocketMessage = Object.assign({}, value);
}
}
// action.ts
export default {
handleWebSocketMessage({ commit }, webSocketMessage) {
commit("setWebSocketMessage", webSocketMessage)
}
}
// index.ts -------------------主要是这里
import { State, state } from './state'
// 接口继承
export interface BaseState extends State {}
const baseState:BaseState = { ...state }
const baseMutations = { ...mutations }
const baseActions = { ...actions }
export const BaseStore = {
baseState,
baseMutations,
baseActions
}
项目A中的store继承BaseStore
// index.ts
import Vue from "vue";
import Vuex from "vuex";
import { state, State } from './state'
import actions from './action'
import mutations from './mutation'
import { BaseStore, BaseState } from '@/base/store/index'
Vue.use(Vuex);
interface CombiantState extends BaseState, State {}
const CombinatState: CombiantState = {...state, ...BaseStore.baseState}
const CombinatMutations = Object.assign({}, mutations, BaseStore.baseMutations)
const CombinatAction = Object.assign({}, actions, BaseStore.baseActions)
export default new Vuex.Store({
state: CombinatState,
mutations: CombinatMutations,
actions: CombinatAction
});