日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

我們一起聊聊審核平臺前端新老倉庫遷移

來源: 責編: 時間:2024-07-06 07:42:38 918觀看
導讀背景審核平臺接入50+業(yè)務,提供在線審核及離線質(zhì)檢、新人培訓等核心能力,同時提供數(shù)據(jù)報表、資源追蹤、知識庫等工具。隨著平臺的飛速發(fā)展,越來越多的新業(yè)務正在或即將接入審核平臺,日均頁面瀏覽量為百萬級別。如今審核平

背景

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

審核平臺接入50+業(yè)務,提供在線審核及離線質(zhì)檢、新人培訓等核心能力,同時提供數(shù)據(jù)報表、資源追蹤、知識庫等工具。隨著平臺的飛速發(fā)展,越來越多的新業(yè)務正在或即將接入審核平臺,日均頁面瀏覽量為百萬級別。如今審核平臺已是公司內(nèi)容生產(chǎn)鏈路上的關鍵一環(huán),是保障內(nèi)容安全的重要防線,因此穩(wěn)定性至關重要。LLx28資訊網(wǎng)——每日最新資訊28at.com

過去一年我們曾對前端項目進行框架升級,考慮風險與成本最小化,選擇了漸進式升級,利用微前端實現(xiàn)Vue2和Vue3共存,新接業(yè)務在Vue3倉庫中開發(fā)。經(jīng)過一年的迭代,Vue3項目趨于穩(wěn)定,沉淀了大部分通用能力。為了降低多倉庫維護心智,同時解決核心模塊的技術債務,考慮將剩余活躍代碼進行重構并遷移至新倉庫。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

面向遷移的重構 - 整潔架構在前端的應用

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

案例選擇

LLx28資訊網(wǎng)——每日最新資訊28at.com

參考前端埋點報表,選擇老倉庫中頁面維度訪問量最高的路由,對線上使用情況進行摸排。日常業(yè)務現(xiàn)狀是點直融合,直播業(yè)務配置化接入需求較多,因為業(yè)務形態(tài)的差異,定制需求多,現(xiàn)有配置能力無法滿足,需擴充。開發(fā)現(xiàn)狀是通用配置化代碼改動頻繁,邏輯復雜,開發(fā)門檻較高,影響范圍大,牽一發(fā)而動全身。因此選擇配置化詳情頁作為優(yōu)先重構并遷移的對象。LLx28資訊網(wǎng)——每日最新資訊28at.com

配置化詳情頁采用的是業(yè)務定制化的低代碼方案,包含schema渲染器和任務流兩部分。當前已沉淀近百份json schema,托管在內(nèi)部其他低代碼平臺上。頁面覆蓋40多個業(yè)務,占據(jù)平臺約20%訪問量和35%獨立訪客。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

如果將頁面看做一個黑盒子,依據(jù)唯一標識(路由path和query等)從node服務、平臺服務以及外部業(yè)務方服務獲取數(shù)據(jù),基于頁面內(nèi)部規(guī)則渲染頁面。審核員瀏覽并進行通過、駁回等操作,提交后將對視頻、彈幕等業(yè)務資源產(chǎn)生影響。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

schema渲染器基于json schema和接口數(shù)據(jù),在平臺內(nèi)生成路由信息與頁面內(nèi)容,負責各種模式的頁面分發(fā)、物料分發(fā),并提供敏感詞、快照、洗數(shù)等通用平臺能力。LLx28資訊網(wǎng)——每日最新資訊28at.com

代碼現(xiàn)狀是數(shù)據(jù)獲取、提交操作和頁面復雜邏輯分散在vue文件和store中,業(yè)務邏輯和UI框架耦合嚴重,不利于集成自動化測試和框架升級。待辦、任務、資源等邊界劃分不清晰,平鋪在“巨石store“中,維護成本極高且代碼改動風險大。渲染器和任務流邏輯不夠內(nèi)聚,耦合嚴重,無法做到關注點分離。因此需要尋找一種合適的架構進行重構,減弱業(yè)務邏輯對UI框架的依賴,增強可測試性。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

整潔架構

LLx28資訊網(wǎng)——每日最新資訊28at.com

整潔架構由Robert C. Martin在2012年提出,核心思想是將軟件系統(tǒng)拆分為獨立的層次,以實現(xiàn)高內(nèi)聚、低耦合、可測試和可維護。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

一共分為四個層級,環(huán)與環(huán)之間,存在一個依賴關系原則:源代碼中的依賴關系,必須只指向同心圓的內(nèi)層,即由低層機制指向高級策略。LLx28資訊網(wǎng)——每日最新資訊28at.com

  • 實體層:包含業(yè)務領域的核心概念和業(yè)務邏輯。
  • 用例層:實現(xiàn)特定的業(yè)務用例,將實體層的業(yè)務邏輯與具體的應用場景結合起來。
  • 接口適配器層:負責處理與外部系統(tǒng)的交互比如用戶界面、數(shù)據(jù)庫、web服務等。將外部系統(tǒng)的請求和數(shù)據(jù)格式轉化為用例層和實體層能夠理解和處理的對象。
  • 框架和驅(qū)動層:包含具體的框架和工具,比如web框架、數(shù)據(jù)庫驅(qū)動等。

優(yōu)點是可以在沒有UI、數(shù)據(jù)庫、web服務器或其他外部基礎設施的情況下測試業(yè)務邏輯;降低對UI框架的依賴,比如跨端開發(fā)時,業(yè)務邏輯可以復用,只需要做UI層的適配。相應的,缺點也很明顯,過于復雜,數(shù)據(jù)需要經(jīng)過多層處理。學習成本較高,容易過度設計,增加復雜性,靈活性較低。適用于大型復雜項目,對于需要長期維護和持續(xù)開發(fā)的項目,清晰層次結構和明確依賴關系有助于減少代碼腐化,更容易適應需求變化。針對我們選擇的模塊,審核前端配置化頁面,比較適合。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

重構

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

實體層

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

主要可拆分成待辦、任務、資源等實體。待辦實體,主要提供待辦的基礎信息、獲取配置等屬性和方法。任務實體提供任務的狀態(tài)、任務耗時、調(diào)度配置、任務數(shù)據(jù),計時和拉取任務流程等。資源實體提供資源的詳情數(shù)據(jù)、獲取詳情及數(shù)據(jù)清洗方法等。待辦實體包含了配置詳情頁所需的核心數(shù)據(jù),任務實體高度抽象了核心任務流。在新業(yè)務接入過程中,實體層一般不變動,通過依賴倒置劃分架構邊界。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

// entities/todo.jsexport default class Todo {    todoId    businessId    todoConfig    ...    constructor() {}    async getTodoConfig() {        // 獲取配置    }}// entities/task.jsexport default class Task {  dispatch_conf  listData  timeCount  ...  constructor() {}  async getTaskDetail({ getTask, taskFormat, afterGetTask}) {    // 抽象封裝核心任務流程  }  // 計時邏輯  startTimer() {}  clearTimers() {}}// entities/resource.jsexport default class Resource {    detail    dataReady    constructor() {}    async getResourceDetail({ getResource, resourceFormat, afterGetResource }) {        // 抽象封裝資源模式核心流程    }}

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

用例層

LLx28資訊網(wǎng)——每日最新資訊28at.com

用例層針對洗數(shù)、提交等復雜場景,通過調(diào)用實體層來實現(xiàn)特定的業(yè)務邏輯,是適配器層與實體層的中介。例如封裝了基于配置的洗數(shù)中間件,列表模式的單個和批量提交,卡片模式的單個和批量提交,快照上報、自動化質(zhì)檢的復雜邏輯。用例層包含了系統(tǒng)的復雜業(yè)務邏輯,為單元測試提供了便利,可以獨立于UI和外部系統(tǒng)進行測試。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

// usecase/use-single-submitimport { get } from 'lodash-es' // 三方工具庫import { ANNOTATION_SINGLE_OPER_PASS_NAME } from '@/constants' // 常量import { workbenchApi } from '@/api'import { setLogData } from '@/utils/xx' // 工具函數(shù)export function getSingleSubmitParams({ data, state.xxx }) {  //... 邏輯處理  return params}export function submitAuditSingle({ data, afterTaskSubmit }) {  const params = ...  workbenchApi.submit(params).then((res) => {    if(res.code = xxx){      afterTaskSubmit() // 調(diào)用鉤子函數(shù)    }  })}

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

適配器層

LLx28資訊網(wǎng)——每日最新資訊28at.com

適配器層包含store和UI,調(diào)用用例層的代碼,主要負責將依賴UI、外部服務、設備等的數(shù)據(jù)處理為用例層可以使用的“干凈數(shù)據(jù)”。適配器層一般不包括復雜的業(yè)務邏輯,因此在框架遷移時僅需關注基本的框架差異,適合自動化代碼轉換。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

// store/todoConfigDetailimport { getTodoInfo } from '@/struct/TodoConfigDetailStruct/usecase/use-todo'import { getTaskInfo, getTask, taskDispatchListFormat } from '@/struct/TodoConfigDetailStruct/usecase/use-task'import { getSingleSubmitParams, submitAuditSingle } from '@/struct/TodoConfigDetailStruct/usecase/use-single-submit'const todo = ref({})async function init({ $route }) {  const query = $route.query  const todoId = +query.todo_id  ...  set(todo, getTodoInfo({ todoId, ... }))  await get(todo).getTodoConfig()  ...}function getTaskDetail() {  get(task).getTaskDetail({    getTask: async ({ noSeize, drillTaskIds }) => await getTask({ todo: get(todo), noSeize, drillTaskIds }),    taskFormat: async (data) => await taskDispatchListFormat({ data, schema: get(todo).schema })    afterGetTask: (res) => { ... }  })}async function submit(data) {  if (single) {    const params = getSingleSubmitParams({ data, todo: get(todo) })    submitAuditSingle({ params, afterTaskSubmit: () => { ... } })  } else {    ...  }}
// Audit.vueconst todoConfigDetailStore = useTodoConfigDetailStore()const { todo, task, multipleSelection } = storeToRefs(todoConfigDetailStore)const { getTaskDetail, submit } = todoConfigDetailStore

LLx28資訊網(wǎng)——每日最新資訊28at.com

新業(yè)務接入一般對實體層和用例層無改動,僅需適配器層增加相應的展示物料,盡可能避免“牽一發(fā)動全身”。新架構會有一定的初學成本,但結合審核平臺復雜的項目現(xiàn)狀和持續(xù)接入新業(yè)務的節(jié)奏,長遠來看對于系統(tǒng)穩(wěn)定性、可測試性有一定幫助,同時降低UI框架依賴性。LLx28資訊網(wǎng)——每日最新資訊28at.com

基于新的架構,可分層進行自動化測試和自動代碼轉換。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

完善用例層的單元測試

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

用例層為純函數(shù),不依賴框架、設備、三方服務等。單元測試的技術棧為jest和vue-test-utils,從審核員的基本工作模式入手,針對任務領取、數(shù)據(jù)清洗與展示、稿件處理三個環(huán)節(jié)完善測試用例。因為是新老倉庫遷移,所以可以將線上環(huán)境視為基準進行用例采集。根據(jù)業(yè)務重要性、線上訪問情況,按優(yōu)先級執(zhí)行測試。單測能有效降低回歸成本,在新業(yè)務持續(xù)接入的背景下,保障系統(tǒng)穩(wěn)定性。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

適配器層的自動代碼轉換 - 基于gogocode將vue2升級為vue3 setup語法

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

調(diào)研與分析

LLx28資訊網(wǎng)——每日最新資訊28at.com

在尋求升級方案的過程中,我們對比了兩款工具:Gogocode 和 vue2-to-composition-api。以下是它們的簡要對比:LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

功能LLx28資訊網(wǎng)——每日最新資訊28at.com

GogocodeLLx28資訊網(wǎng)——每日最新資訊28at.com

vue2-to-composition-apiLLx28資訊網(wǎng)——每日最新資訊28at.com

缺點LLx28資訊網(wǎng)——每日最新資訊28at.com

默認不支持轉換成 Vue3 setup 語法LLx28資訊網(wǎng)——每日最新資訊28at.com

不支持 template 轉換LLx28資訊網(wǎng)——每日最新資訊28at.com

轉換規(guī)則覆蓋LLx28資訊網(wǎng)——每日最新資訊28at.com

轉換規(guī)則列表LLx28資訊網(wǎng)——每日最新資訊28at.com

轉換效果LLx28資訊網(wǎng)——每日最新資訊28at.com

特性LLx28資訊網(wǎng)——每日最新資訊28at.com

像 jQuery 一樣修改ASTLLx28資訊網(wǎng)——每日最新資訊28at.com

將 Vue2 代碼轉換為 Vue 3 的 Composition API 格式LLx28資訊網(wǎng)——每日最新資訊28at.com


LLx28資訊網(wǎng)——每日最新資訊28at.com

2. jQuery-like API 簡化了 AST 修改成本LLx28資訊網(wǎng)——每日最新資訊28at.com

2. 支持在線轉換LLx28資訊網(wǎng)——每日最新資訊28at.com

優(yōu)點LLx28資訊網(wǎng)——每日最新資訊28at.com

1. 支持自定義插件LLx28資訊網(wǎng)——每日最新資訊28at.com

1. 支持轉換成 Vue3 setup 語法LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

經(jīng)過調(diào)研,gogocode 是基于 AST 封裝的庫可擴展空間大,但是默認 gogocode-plugin-vue 不支持轉換成 Composition APILLx28資訊網(wǎng)——每日最新資訊28at.com

vue2-to-composition-api 倒是支持 Composition API,但是不支持 template 部分的轉換。LLx28資訊網(wǎng)——每日最新資訊28at.com

考慮到我們的項目中有許多自定義的轉換邏輯,如 UI 庫替換、store 替換等,我們最終決定使用 gogocode 作為主要工具,并結合其他手段來實現(xiàn) vue2 到 vue3 的全面升級。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

實施與探索

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

基礎:升級語法

LLx28資訊網(wǎng)——每日最新資訊28at.com

升級語法是借助 gogocode 的 replace 方法實現(xiàn)的,通過 $$$ 匹配符保留所需要的代碼塊,將 Vue2 的語法快速替換成 Vue3 的語法。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

// 替換datascriptAst.replace("data() {return {$$$};}", `const $data = reactive({$$$})`);
// 替換propsscriptAst.replace("props:{$$$}", "const props = defineProps({$$$})");
// 替換生命周期scriptAst.replace("created(){$$$}", "onBeforeMount(()=>{$$$})")  .replace("mounted(){$$$}", "onMounted(()=>{$$$})")  .replace("async mounted(){$$$}", "onMounted(async ()=>{$$$})")  .replace("beforeUnmount(){$$$}", "onBeforeUnmount(()=>{$$$})")  .replace("unmounted(){$$$}", "onUnmounted(()=>{$$$})")  .replace("beforeDestroy(){$$$}", "onBeforeUnmount(()=>{$$$})")  .replace("destoryed(){$$$}", "onUnmounted(()=>{$$$})");

LLx28資訊網(wǎng)——每日最新資訊28at.com

效果如下,通過 replace 替換的方式適合大部分場景,比如 methods、filters、watch 等LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

進階:處理模板中的變量、函數(shù)中的this變量LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

template綁定的變量可能是data,可能是props,還可能是 methodsLLx28資訊網(wǎng)——每日最新資訊28at.com

想要替換 template 中的變量,需要先收集 data、props、methods 中的 keysLLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

getDataKeys() {  const keys = new Set();  // 只需要第一層的key,所以deep設為1  this.scriptAst.find('data() {$$$}').find('$_$:$_$', { deep: 1 }).each(node => {    if (node.match[0] && node.match[0][0].node.type === 'Identifier') {      keys.add(node.match[0][0].value);    }  });  return Array.from(keys)}getPropsKeys() {  const keys = new Set();  this.scriptAst.find('props: {$$$1}', { deep: 1 }).each((node) => {    if (node.match['$$$1']) {      node.match['$$$1'].forEach((item) => {        if (item.key && item.key.type === 'Identifier') {          keys.add(item.key.name)        }      })    }  });  return Array.from(keys)}// methods 有點小復雜,需要考慮異步函數(shù),普通函數(shù)和鍵值對的寫法getMethodsKeys() {  const methodsAst = this.scriptAst.find('methods:{$$$}');  const methods = methodsAst.find('$_$() {$$$1}');  const asyncmMethods = methodsAst.find('async $_$(){$$$1}');  const mapKeys = methodsAst.find('$_$:$$$1', { deep: 1 });  const methodNames = [];  methods.each(node => {    if (node.match[0] && node.match[0][0]) {      methodNames.push(node.match[0][0].value);    }  });  asyncmMethods.each(node => {    if (node.match[0] && node.match[0][0]) {      methodNames.push(node.match[0][0].value);    }  });  mapKeys.each(node => {    if (node.match[0] && node.match[0][0]) {      methodNames.push(node.match[0][0].value);    }  });  return methodNames;}

LLx28資訊網(wǎng)——每日最新資訊28at.com

收集完成后可以開始遍歷 template 中的 attr,并替換所綁定的變量了。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

handlTemplate() {    // 替換attr, 例如 <div :value="value"></div>    this.ast.find("<template></template>").find(`<$_$ ="$$$0" >$$$1</$_$>`).each((node) => {      node.match['$$$0'].forEach(attr => {        if (attr && attr.value) {          this.dataKeys.some(keyName => {            const reg = new RegExp(`${keyName}//b`, 'g')            const macth = reg.test(attr.value.content);            attr.value.content = attr.value.content.replace(reg, `$data.${keyName}`)            if (macth) {              return true;            }          })          this.methodsKeys.some(keyName => {            const reg = new RegExp(`//b${keyName}//b`, 'g')            const macth = reg.test(attr.value.content);            attr.value.content = attr.value.content.replace(reg, `methods.${keyName}`)            if (macth) {              return true;            }          })          this.propsKeys.some(keyName => {            const reg = new RegExp(`//b${keyName}//b`, 'g')            const macth = reg.test(attr.value.content);            attr.value.content = attr.value.content.replace(reg, `props.${keyName}`)            if (macth) {              return true;            }          })        }      })      // 替換content,例如:<div>{{value}}<div>      node.match['$$$1'].forEach(node => {        if (node.content && node.content.value) {          // 省略:與上面類似        }      })    })  }

LLx28資訊網(wǎng)——每日最新資訊28at.com

說到 this 替換也是一個繁瑣的問題,this.xx, xx 可以是 data,可以是props,可以是 function,還可以是私有屬性等。LLx28資訊網(wǎng)——每日最新資訊28at.com

所以我們需要先把組件中的 data、props、methods、mapGetter 中的 keys 都收集一遍,然后再替換 script 中的 this 變量。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

// 正則替換更方便,所以需要放在最后一步替換handlThis(code) {  code = code.replace(/this/.([_$0-9a-zA-Z]+)/g, (match, $1) => {    // 替換function body 中的 data引用    if (this.dataKeys.includes($1)) {      return `$data.${$1}`;    }    // 替換function body 中的 methods調(diào)用    else if (this.methodsKeys.includes($1)) {      return `methods.${$1}`;    }    // 替換 vm 私有屬性    else if ($1 && $1[0] === '$') {      return `$vm.${$1}`;    } else if (this.computedKeys.includes($1)) {      return $1    } else if (this.propsKeys.includes($1)) {      return `props.${$1}`    }    return `$vm.${$1}`  })  // 替換function body 中的 動態(tài)methods調(diào)用  code = code.replace(/this/[(.+)/]/g, (match, $1) => {    return `methods[${$1}]`;  })  return code}

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

進階:動態(tài)調(diào)用this.xxx該如何解決

LLx28資訊網(wǎng)——每日最新資訊28at.com

async parseOpenDialog(payload) {  const { schema, data } = payload  await this[schema.method](    parseSchema,    data,    dialogParams,    dialogType  )}

按 vue3 新的寫法,一般是展開的LLx28資訊網(wǎng)——每日最新資訊28at.com

const parseOpenDialog = async (payload) => {}

但是按這個習慣來轉換,就無法做到動態(tài)調(diào)用this.xxx,我們可以嘗試把方法都放在methods對象中,有點類似 vue2LLx28資訊網(wǎng)——每日最新資訊28at.com

const methods = {  parseOpenDialog: async (payload) => {  },  xxx: async() => {  }}

在替換 this 時,將 this 替換成 methods 變成 methods[schema.method]()。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

其他技巧

LLx28資訊網(wǎng)——每日最新資訊28at.com

1 . 原來 vue2 中肯很多屬性掛在組件實例上,比如 $route, $router, $emit 甚至自定義的屬性等等。下面是 vue3 中獲取組件實例的方法。LLx28資訊網(wǎng)——每日最新資訊28at.com

import { getCurrentInstance } from 'vue'const { proxy: $vm } = getCurrentInstance()$vm.xxx = '自定義屬性'

2 . 原來使用的 vuex,現(xiàn)在使用的是 pinia。我們需要先收集 ...mapState($_$, [$$$1]),然后使用 storeToRefs 代替LLx28資訊網(wǎng)——每日最新資訊28at.com

// 獲取store 使用storeToRefsif (this.storeType === 'pinia') {  this.scriptAst  .find("computed:{}")  .before(`const {${stateNames.join(',')}} = storeToRefs(${this.getPiniaStoreName(key)})`)  .replace("computed:{$$$}", "$$$")}

最終將上述轉換能力封裝成一個庫,通過 npm 安裝來實現(xiàn)組件批量升級。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

遷移前后的E2E測試 - 視覺輔助UI自動化測試LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

端到端測試是確保新舊系統(tǒng)平穩(wěn)過渡的關鍵步驟。本次遷移依舊遵循漸進式升級的原則,新增v3路由,線上新老路由共存。共分為功能測試、UI測試、性能測試三個部分。功能測試為單元測試的補充,主要驗證新老路由下核心操作路徑及提交參數(shù)的一致性,攔截請求避免對線上造成影響。性能由通用監(jiān)控大盤進行保障。UI對比測試是本次的重點。LLx28資訊網(wǎng)——每日最新資訊28at.com

新老倉庫分別基于Element UI和Element Plus,Element Plus重新設計了組件以適應Vue3,組件尺寸體系調(diào)整為更自然的大中小選項。間距優(yōu)化為更通用的4px體系,主要涉及 padding 和 margin 屬性修改、 font-size 等字體和圖標大小修改等。因此,雖然大部分組件在外觀上保持相似,視覺和布局上可能有一些差異。由于業(yè)務組件具備一定復雜性,手寫測試用例工作量繁瑣,新舊頁面組件可能存在差異無法完全復用,方案也不具備通用性。因此考慮使用計算機視覺技術來識別和驗證用戶界面的元素。LLx28資訊網(wǎng)——每日最新資訊28at.com

基于公司內(nèi)部的自動化測試平臺,測試框架為Playwright,測試語言選擇Python以更好的利用豐富的圖像處理庫。指定CSS選擇器,隨機選擇頁面上的元素進行截圖和對比,設定閾值進行判斷。圖像相似度對比可分為傳統(tǒng)的基于像素差的方法和基于圖像特征的方法。圖像特征有SIFT、ORB等特征提取方法和深度學習方法。分別選擇一種代表性的算法進行對比和測試。LLx28資訊網(wǎng)——每日最新資訊28at.com

  • SSIM(結構相似性指數(shù)),同時考慮圖片亮度、對比度與結構信息。用于檢測兩張相同尺寸的圖像的相似性。對于圖像的亮度和對比度變化具有較好的魯棒性。
  • SIFT(尺度不變特征變換),用于在圖像中檢測和描述局部特征,這些特征對圖像的縮放、旋轉和部分亮度變化具有不變性。能夠檢測和匹配不同尺寸下的特征,對圖像的仿射變換、噪聲和部分遮擋具有較好的魯棒性。
  • LPIPS是一種深度學習特征,用于量化圖像之間的感知相似性,通過比較圖像在深度神經(jīng)網(wǎng)絡中的特征表示來工作,這些特征能夠捕捉到人類視覺所關注的圖像細節(jié)。基于一個大規(guī)模的人類感知相似性判斷數(shù)據(jù)集,包含484K個人類的判斷,涵蓋了多種圖像變換和失真類型。使用深度特征(例如VGG網(wǎng)絡中的特征)來衡量圖像相似性,比傳統(tǒng)的度量方法更有效。

LLx28資訊網(wǎng)——每日最新資訊28at.com

v2LLx28資訊網(wǎng)——每日最新資訊28at.com

v3LLx28資訊網(wǎng)——每日最新資訊28at.com

SSIMLLx28資訊網(wǎng)——每日最新資訊28at.com

SIFTLLx28資訊網(wǎng)——每日最新資訊28at.com

LPIPSLLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

0.656LLx28資訊網(wǎng)——每日最新資訊28at.com

0.855LLx28資訊網(wǎng)——每日最新資訊28at.com

0.909LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

0.916LLx28資訊網(wǎng)——每日最新資訊28at.com

0.874LLx28資訊網(wǎng)——每日最新資訊28at.com

0.961LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

0.658LLx28資訊網(wǎng)——每日最新資訊28at.com

0.857LLx28資訊網(wǎng)——每日最新資訊28at.com

0.881LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

0.877LLx28資訊網(wǎng)——每日最新資訊28at.com

0.855LLx28資訊網(wǎng)——每日最新資訊28at.com

0.926LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

0.551LLx28資訊網(wǎng)——每日最新資訊28at.com

0.836LLx28資訊網(wǎng)——每日最新資訊28at.com

0.947LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

0.929LLx28資訊網(wǎng)——每日最新資訊28at.com

0.884LLx28資訊網(wǎng)——每日最新資訊28at.com

0.942LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

實驗表明,基于深度學習特征的相似度對比結果更接近用戶感知,針對Vue2升級Vue3 UI組件庫導致的間距、字體、尺寸等細微差異判斷更準確。因此采用LPIPS作為對比算法。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

def compare_images(url1, url2):  loss_fn = lpips.LPIPS(net = 'alex')  img1 = cv2.imread(url1)  img2 = cv2.imread(url2)  if img1 is not None and img2 is not None and img1.size > 0 and img2.size > 0:      img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))      cv2.imwrite(url2, img2)      combined_image = cv2.hconcat([img1, img2])      ex_img1 = lpips.im2tensor(lpips.load_image(url1))      ex_img2 = lpips.im2tensor(lpips.load_image(url2))      d = loss_fn.forward(ex_img1, ex_img2)      if d is not None:          cv2.putText(combined_image,'score: %.3f'%(1 - d.mean()), (20, 20), cv2.FONT_ITALIC, 0.4, (255, 0, 255))      return d, combined_image  else:      return None

LLx28資訊網(wǎng)——每日最新資訊28at.com

依據(jù)業(yè)務流程,分別訪問新老路由,對頁面指定元素進行截圖、對比和拼接,輸出測試截圖和完整的測試報告。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

采用視覺輔助UI自動化測試,更接近用戶真實感知,大大降低測試用例復雜度,提升測試效率,無需關注繁雜的DOM元素層級。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

上線

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

以頁面配置的形式按待辦進行灰度,跳轉至新路由。單元測試已集成至項目流水線中,MR和發(fā)布前觸發(fā)。灰度過程中手動執(zhí)行E2E用例,以自定義環(huán)境變量的形式指定頁面路徑、元素選擇器、相似度閾值等。測試通過后修改頁面配置,引流至新路由。通過用戶故障群和頁面反饋入口響應用戶反饋,結合前端埋點報表觀察線上使用情況和確定灰度策略。通過完善單元測試、E2E測試和制定合理的灰度策略,針對特定模板的遷移已順利完成,期間未收到線上故障反饋。LLx28資訊網(wǎng)——每日最新資訊28at.com

后續(xù)遷移策略將以老倉庫中改動較頻繁文件優(yōu)先入手,測試用例先行,借助自動代碼轉換工具快速平穩(wěn)遷移,線上埋點數(shù)據(jù)做輔助。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

收益

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

活躍代碼陸續(xù)遷移,結束多倉庫并行,減少維護心智。之前我們的常態(tài)是新老倉庫并行,開發(fā)一個完整的業(yè)務功能時要在ts和js,選項式API和setup語法之間頻繁切換,心智負擔較重。活躍代碼陸續(xù)遷移至vue3新倉庫,結合新的框架特性和實用工具,能夠更專注于業(yè)務邏輯本身。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

核心模塊重構,“巨石store”輕量化,提高可維護性和可演進性,分層結構保障核心邏輯穩(wěn)定性。原本配置能力擴充時需要在復雜的數(shù)據(jù)流中“走迷宮”,耦合嚴重,通用代碼影響范圍大,常常出現(xiàn)A業(yè)務需求上線導致B業(yè)務不可用的情況。利用整潔架構進行分層設計后,新增一種審核模式僅需在適配器層新增對應物料和action,用例層新增用例。無需修改實體層和其他業(yè)務相關的用例、通用頁面、物料等。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

業(yè)務邏輯的重新梳理,彌補測試用例空缺。領域提取是對業(yè)務邏輯的重新梳理,前端能加深業(yè)務理解。穩(wěn)定性至上的模塊很長時間缺少測試用例,造成對開發(fā)人員的經(jīng)驗、能力依賴極大。完善核心鏈路的測試用例能有效降低回歸成本,保障系統(tǒng)穩(wěn)定性。LLx28資訊網(wǎng)——每日最新資訊28at.com

工具沉淀,組內(nèi)復用。自動代碼轉換工具和基于AI能力的前端E2E測試方案為后續(xù)組內(nèi)其他項目的框架升級和遷移提供了便利。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

總結與展望

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

在2023年開始漸進式升級Vue3后,我們經(jīng)歷了很長一段時間的多倉庫并行。在新業(yè)務不斷接入、開發(fā)新成員加入的背景下,這樣的模式無疑提升了開發(fā)門檻和維護心智。本次活躍代碼的陸續(xù)遷移結束了多倉庫并行的現(xiàn)狀,同時在整個實踐過程中我們?yōu)閷徍似脚_這個大型復雜項目前端引入了整潔架構的思想,為后續(xù)的開發(fā)維護提供了一種新的思路。沉淀了一套自動化vue2代碼轉vue3 setup的工具,可為后臺項目的框架升級提供便利。同時借助AI能力提升前端E2E測試的效率,利用計算機視覺輔助前端UI自動化測試。有幾點心得:LLx28資訊網(wǎng)——每日最新資訊28at.com

完美重構、敏捷重構、系統(tǒng)穩(wěn)定性難以平衡。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

既然下定決心對年久失修的代碼進行重構,我們一定是追求極致優(yōu)化和整潔的。但是需求現(xiàn)狀是不斷有新特性進來,戰(zhàn)線拉的太長必將導致抹平差異的成本增加,因此敏捷性也很重要。同時底線是關注系統(tǒng)的可靠性和穩(wěn)定性。這三者一定程度上存在矛盾,需平衡:LLx28資訊網(wǎng)——每日最新資訊28at.com

  • 任務拆分,基于埋點數(shù)據(jù)選擇最重要或最緊急的鏈路進行重構,而非追求大而全,先落地架構,后擴充功能
  • 測試用例先行,重構必將引入風險,用例先行能最大程度保障核心功能的穩(wěn)定遷移
  • 制定合理的灰度策略,新增路由,以頁面配置形式進行灰度,優(yōu)先uv較低的頁面驗證,并保證及時的反饋渠道
  • 持續(xù)優(yōu)化,重構應成為一種思想,在迭代中持續(xù)優(yōu)化

整潔架構非銀彈,容易過度設計,學習門檻較高。LLx28資訊網(wǎng)——每日最新資訊28at.com

  • 按模塊重構,而非項目
  • 針對新架構,制定長期維護計劃,組織團隊培訓,降低學習成本

LLx28資訊網(wǎng)——每日最新資訊28at.com

多倉庫遷移路線:數(shù)據(jù)為支撐,測試用例先行,借助自動代碼轉換工具和視覺輔助UI自動化測試,制定合理的灰度策略并建立及時的故障反饋和響應渠道。對于大型復雜項目或模塊,先進行面向遷移的重構,也能起到事半功倍的作用。LLx28資訊網(wǎng)——每日最新資訊28at.com

LLx28資訊網(wǎng)——每日最新資訊28at.com

對我們而言,遷移的結束只是起點,基于更整潔的架構和更先進的前端框架,未來仍有很多發(fā)力點:LLx28資訊網(wǎng)——每日最新資訊28at.com

  • 對于遷移過程中沉淀下來的新架構,需不斷優(yōu)化和改進,以適應復雜的業(yè)務場景。
  • 在更多的業(yè)務場景下評估遷移后的性能改進,確保用戶體驗得到提升。
  • 持續(xù)審查并解決在遷移過程中發(fā)現(xiàn)的技術債務。
  • 持續(xù)建設自動代碼轉換工具,賦能團隊內(nèi)其他項目。
  • 視覺輔助UI自動化測試的方案,進一步抽象,給到不熟悉自動化測試的團隊成員“開箱即用”。
  • ...

本文鏈接:http://www.www897cc.com/showinfo-26-99167-0.html我們一起聊聊審核平臺前端新老倉庫遷移

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: AI 引領佛山智造 數(shù)聚禪城開拓創(chuàng)新 2024 華為開發(fā)者大會佛山分會場圓滿落幕

下一篇: Go語言助力安全測試:24小時內(nèi)發(fā)送5億次HTTP/1.1請求

標簽:
  • 熱門焦點
  • 7月安卓手機好評榜:三星S23Ultra好評率第一

    性能榜和性價比榜之后,我們來看最后的安卓手機好評榜,數(shù)據(jù)來源安兔兔評測,收集時間2023年7月1日至7月31日,僅限國內(nèi)市場。第一名:三星Galaxy S23 Ultra好評率:95.71%在即將迎來新
  • 分布式系統(tǒng)中的CAP理論,面試必問,你理解了嘛?

    對于剛剛接觸分布式系統(tǒng)的小伙伴們來說,一提起分布式系統(tǒng),就感覺高大上,深不可測。而且看了很多書和視頻還是一臉懵逼。這篇文章主要使用大白話的方式,帶你理解一下分布式系統(tǒng)
  • 得物效率前端微應用推進過程與思考

    一、背景效率工程隨著業(yè)務的發(fā)展,組織規(guī)模的擴大,越來越多的企業(yè)開始意識到協(xié)作效率對于企業(yè)團隊的重要性,甚至是決定其在某個行業(yè)競爭中突圍的關鍵,是企業(yè)長久生存的根本。得物
  • Flowable工作流引擎的科普與實踐

    一.引言當我們在日常工作和業(yè)務中需要進行各種審批流程時,可能會面臨一系列技術和業(yè)務上的挑戰(zhàn)。手動處理這些審批流程可能會導致開發(fā)成本的增加以及業(yè)務復雜度的上升。在這
  • JavaScript學習 -AES加密算法

    引言在當今數(shù)字化時代,前端應用程序扮演著重要角色,用戶的敏感數(shù)據(jù)經(jīng)常在前端進行加密和解密操作。然而,這樣的操作在網(wǎng)絡傳輸和存儲中可能會受到惡意攻擊的威脅。為了確保數(shù)據(jù)
  • 三萬字盤點 Spring 九大核心基礎功能

    大家好,我是三友~~今天來跟大家聊一聊Spring的9大核心基礎功能。話不多說,先上目錄:圖片友情提示,本文過長,建議收藏,嘿嘿嘿!一、資源管理資源管理是Spring的一個核心的基礎功能,不
  • 微軟邀請 Microsoft 365 商業(yè)用戶,測試視頻編輯器 Clipchamp

    8 月 1 日消息,微軟近日宣布即將面向 Microsoft 365 商業(yè)用戶,開放 Clipchamp 應用,邀請用戶通過該應用來編輯視頻。微軟于 2021 年收購 Clipchamp,隨后開始逐步整合到 Microsof
  • 得物寵物生意「狂飆」,發(fā)力“它經(jīng)濟”

    作者|花花小萌主近日,得物宣布正式上線寵物鑒別,通過得物App內(nèi)的&ldquo;在線鑒別&rdquo;,可找到鑒別寵物的選項。通過上傳自家寵物的部位細節(jié),就能收獲擁有專業(yè)資質(zhì)認證的得物鑒
  • OPPO K11搭載長壽版100W超級閃充:26分鐘充滿100%

    據(jù)此前官方宣布,OPPO將于7月25日也就是今天下午14:30舉辦新品發(fā)布會,屆時全新的OPPO K11將正式與大家見面,將主打旗艦影像,和同檔位競品相比,其最大的賣
Top 主站蜘蛛池模板: 鹿邑县| 镇赉县| 施秉县| 运城市| 安陆市| 饶平县| 惠安县| 济源市| 汉沽区| 庆阳市| 个旧市| 玉山县| 东光县| 石嘴山市| 泉州市| 咸阳市| 沁水县| 鄢陵县| 昌吉市| 界首市| 湖南省| 连州市| 合川市| 绥江县| 富平县| 马关县| 日照市| 肇庆市| 井冈山市| 磴口县| 耿马| 青铜峡市| 蕉岭县| 宁河县| 金堂县| 疏附县| 将乐县| 博野县| 仁化县| 阿拉善左旗| 中方县|