<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          花椒低代碼可視化編輯平臺(tái)的設(shè)計(jì)與實(shí)踐

          共 7210字,需瀏覽 15分鐘

           ·

          2021-07-15 02:45

          一. 項(xiàng)目由來(lái)

          19年夏天的一次小組頭腦風(fēng)暴會(huì)議上,成員們?cè)谟懻撓掳肽陝?chuàng)新項(xiàng)目時(shí)提出了這樣一個(gè)想法,大致思路是左側(cè)預(yù)覽,右側(cè)填充數(shù)據(jù),數(shù)據(jù)保存后觸發(fā)頁(yè)面更新,為此我們還做了一個(gè)類(lèi)似的DEMO進(jìn)行演示。因?yàn)楫?dāng)時(shí)我們已經(jīng)有Blade模板平臺(tái)可以使用,所以該項(xiàng)目的優(yōu)先級(jí)被排在了后面,慘遭擱置。

          2020年以來(lái)因?yàn)橐咔榈脑颍覀児鞠嚓P(guān)的營(yíng)銷(xiāo)業(yè)務(wù)越來(lái)越多,活動(dòng)形式大同小異,多是單期,而B(niǎo)lade平臺(tái)只能做到整頁(yè)定制,無(wú)法復(fù)用,就導(dǎo)致?tīng)I(yíng)銷(xiāo)活動(dòng)占用了更多的開(kāi)發(fā)資源,擠壓了其他項(xiàng)目,所以我們就又想起了上面那個(gè)想法。我們需要一個(gè)能更精細(xì)化定制,可自由組合,實(shí)時(shí)預(yù)覽,方便使用的模板平臺(tái)去解決這個(gè)問(wèn)題。

          二. 明確需求

          2.1 定制的顆粒度

          該模板平臺(tái)的主要使用對(duì)象是運(yùn)營(yíng)人員,開(kāi)發(fā)人員負(fù)責(zé)開(kāi)發(fā)組件,所以顆粒度不能太細(xì),否則運(yùn)營(yíng)人員的學(xué)習(xí)成本和開(kāi)發(fā)人員的開(kāi)發(fā)成本都會(huì)非常高昂。每個(gè)組件最好只能配置少量參數(shù),邏輯全部由開(kāi)發(fā)人員在組件內(nèi)部實(shí)現(xiàn);

          2.2 組件的UI

          由于該模板平臺(tái)生成的頁(yè)面是 to C 的,所以必須是強(qiáng)UI表現(xiàn),需由開(kāi)發(fā)人員自己編寫(xiě),像生成企業(yè)OA、后臺(tái)那種的定制UI組件或者不支持自定義組件的就得PASS掉;

          2.3 自由組合

          對(duì)于這個(gè)需求,一般的可視化搭建框架都能實(shí)現(xiàn)。由于我們的業(yè)務(wù)都是面向移動(dòng)端用戶(hù),不像PC那樣需要嵌套,所以采用非嵌套組件層級(jí)規(guī)則,每個(gè)組件占寬100%,可調(diào)整先后順序即可;

          2.4 實(shí)時(shí)預(yù)覽

          因?yàn)橹暗腂lade模板平臺(tái),只有發(fā)布到測(cè)試/正式環(huán)境才能查看實(shí)際配置后的效果,遇到不確定的配置項(xiàng)可能得重發(fā)好幾次才能符合最終需求。該需求一般的框架都能滿(mǎn)足,所以開(kāi)發(fā)排期排到最后。

          三. 技術(shù)調(diào)研

          本著不重復(fù)造輪子的想法,先調(diào)研一下有沒(méi)有現(xiàn)成的解決方案。

          1. amis

          amis 是百度開(kāi)源的一個(gè)低代碼前端框架,它使用 JSON 配置來(lái)生成頁(yè)面,功能很強(qiáng)大,能實(shí)現(xiàn)很多復(fù)雜的功能,但是有點(diǎn)不適合我們的業(yè)務(wù)。amis的目標(biāo)是 toB 用戶(hù),組件很簡(jiǎn)潔(就是丑),不適合toC,并且配置項(xiàng)太多,學(xué)習(xí)成本很高。而我們新的模板發(fā)布平臺(tái)打算是提供給運(yùn)營(yíng)人員使用,考慮到運(yùn)營(yíng)人員的技術(shù)水平約等于無(wú),所以只能PASS,如果后續(xù)有后臺(tái)的需求,我們會(huì)考慮用這個(gè)。

          2. 魯班H5

          魯班H5是基于Vue2.0開(kāi)發(fā),通過(guò)拖拽的形式,生成頁(yè)面的工具。它支持自定義組件、腳本系統(tǒng)、拖拽等功能,能滿(mǎn)足我們的業(yè)務(wù)需求,但是對(duì)于一些復(fù)雜組件要實(shí)現(xiàn)自己的編輯器,這點(diǎn)讓我們很猶豫。試想一下自己做完一個(gè)很復(fù)雜的組件,還要去做一個(gè)相應(yīng)的好用的組件屬性編輯器,還要考慮各種校驗(yàn)等等一系列問(wèn)題,令人望而卻步。

          3. pipeline-page

          pipeline-page 是 github 上開(kāi)源的一套頁(yè)面可視化搭建框架。它將整個(gè)系統(tǒng)分為了三部分:編輯器,實(shí)際頁(yè)面,后臺(tái)。編輯器通過(guò)iframe與實(shí)際頁(yè)面關(guān)聯(lián),編輯器編輯屬性之后發(fā)給后臺(tái),后臺(tái)構(gòu)建頁(yè)面,刷新之后即可實(shí)時(shí)預(yù)覽,通過(guò)這種方式

          1.實(shí)現(xiàn)了編輯器和組件庫(kù)前端框架的分離;2.實(shí)現(xiàn)了編輯器和組件庫(kù)各組件的分離;3.避免了預(yù)覽頁(yè)面的邏輯和樣式污染編輯器環(huán)境。

          這樣的方案理論上無(wú)論采用什么技術(shù)棧,升級(jí)組件庫(kù)前端框架,都可以做到成本最小化。編輯器頁(yè)面只提供數(shù)據(jù),后臺(tái)負(fù)責(zé)存儲(chǔ)組件信息、組件屬性值和頁(yè)面的數(shù)據(jù),渲染頁(yè)面只需要根據(jù)獲取的頁(yè)面和組件數(shù)據(jù)進(jìn)行展示,三者解耦。另外pipeline-page 采用了 JSON Schema 的方案來(lái)實(shí)現(xiàn)組件屬性表單的生成,并且?guī)в行r?yàn),不用再考慮去寫(xiě)編輯器了,完美解決了 魯班H5 的痛點(diǎn)。

          看到 pipeline-page 之后就沒(méi)有再去調(diào)研其他的可視化搭建框架了,這套方案的架構(gòu)十分適合我們的業(yè)務(wù),但是它的實(shí)現(xiàn)不太符合我們現(xiàn)有的業(yè)務(wù),于是我們決定按照 pipeline-page 的思想,根據(jù)花椒前端的實(shí)際情況自己實(shí)現(xiàn)一套。

          四. 技術(shù)架構(gòu)

          花椒低代碼可視化編輯平臺(tái)也是分為三個(gè)部分: 前端,服務(wù)端,組件庫(kù)+預(yù)覽頁(yè)。

          4.1 前端部分

          前端采用的是D2Admin的模板搭建了一個(gè)簡(jiǎn)易的管理系統(tǒng),根據(jù)花椒自己的實(shí)際業(yè)務(wù)增加了團(tuán)隊(duì)管理,站點(diǎn)管理(預(yù)埋,還未實(shí)現(xiàn)),頁(yè)面管理,組件分類(lèi)等功能。在編輯頁(yè)面我們?cè)谧髠?cè)按照不同分類(lèi)展示組件,點(diǎn)擊可彈出浮層介紹組件詳情,方便運(yùn)營(yíng)同學(xué)了解使用方法,點(diǎn)擊添加即可在中間預(yù)覽區(qū)看到組件;右側(cè)為屬性編輯區(qū),組件的邏輯和樣式由組件內(nèi)部封裝,前端部分通過(guò)組件信息中的 JSON Schema 去渲染表單,運(yùn)營(yíng)人員根據(jù)開(kāi)發(fā)人員提供的簡(jiǎn)單的預(yù)設(shè)屬性來(lái)填入信息即可。使用組件搭建出一套活動(dòng)頁(yè)面,例子: https://web.huajiao.com/jimu/3/index.html


          編輯頁(yè)


          前端部分與 pipeline-page 不同的是我們?cè)诰庉嫿M件屬性時(shí),不僅將組件及頁(yè)面信息發(fā)送給后臺(tái)服務(wù)端,而且同時(shí)將這些信息通過(guò) window.postMessage 的方式傳輸給iframe中的預(yù)覽頁(yè);預(yù)覽頁(yè)本身集合了所有業(yè)務(wù)組件,收到信息后通過(guò) 動(dòng)態(tài)組件 的方式實(shí)時(shí)渲染,方便了使用人員及時(shí)看到配置后的效果,不需要后臺(tái)構(gòu)建,比 pipeline-page 的預(yù)覽更加快速及時(shí)。所以在頁(yè)面未發(fā)布之前,不會(huì)生成真正的頁(yè)面,它只是存在服務(wù)器端中的一段數(shù)據(jù)。

          其中 page 字段是對(duì)頁(yè)面本身的一些描述信息,componentList存儲(chǔ)的是頁(yè)面使用的組件中的數(shù)據(jù),預(yù)覽頁(yè)使用 cname 指定渲染的組件,style 字段為組件容器的樣式(用于調(diào)整組件的顯示區(qū)間等不影響組件功能的樣式),props 就是組件根據(jù)業(yè)務(wù)需求需要填入的屬性值(VUE Compoent中的props字段需要傳入的值)。

          4.2 服務(wù)端部分

          服務(wù)器負(fù)責(zé)存儲(chǔ)前端提交的組件數(shù)據(jù)、頁(yè)面數(shù)據(jù)以及組件信息,在收到用戶(hù)發(fā)起的發(fā)布請(qǐng)求后,通過(guò)調(diào)用gitlab的API來(lái)觸發(fā)pipeline構(gòu)建和發(fā)布頁(yè)面。

          技術(shù)架構(gòu):

          1.node框架基于可維護(hù)可擴(kuò)展的考慮,采用的是nestjs框架。2.使用管道、DTO驗(yàn)證參數(shù),摒棄if-else,使參數(shù)驗(yàn)證更加優(yōu)雅。3.用戶(hù)注冊(cè)登錄是基于passport-jwt實(shí)現(xiàn),再配合nest的路由守衛(wèi)方便進(jìn)行用戶(hù)信息的驗(yàn)證。4.使用typeorm連接數(shù)據(jù)庫(kù),可以讓前端專(zhuān)注于業(yè)務(wù)邏輯,不用過(guò)度擔(dān)心數(shù)據(jù)存儲(chǔ)。

          服務(wù)器在以上技術(shù)的基礎(chǔ)上,實(shí)現(xiàn)了和各個(gè)平臺(tái)的聯(lián)動(dòng)。詳情如下

          4.3 預(yù)覽+編譯部分

          我們的實(shí)現(xiàn)方案和 pipeline-page 最大的不同就是在 預(yù)覽+編譯部分,我們覺(jué)得 pipeline-page 方案關(guān)于組件這部分太過(guò)割裂,使用起來(lái)不順暢,用戶(hù)還需要打包并將資源轉(zhuǎn)移到 pipeline-resources 中,所以我們依托花椒的GITLAB CI/CD 實(shí)現(xiàn)了一套"預(yù)覽+編譯"功能。

          組件庫(kù)目錄結(jié)構(gòu):

          組件庫(kù)和平時(shí)開(kāi)發(fā)的單頁(yè)項(xiàng)目沒(méi)有任何區(qū)別,開(kāi)發(fā)人員切新分支后在 components/xxx 分類(lèi)目錄下添加組件,組件可以引用公共資源。

          分類(lèi)的目錄結(jié)構(gòu)

          class.config.json 標(biāo)識(shí)子分類(lèi)信息

          autoplay-video/index.vue 為模板文件

          這個(gè)和平常開(kāi)發(fā)一個(gè)業(yè)務(wù)組件是沒(méi)有任何區(qū)別的,props 中標(biāo)明了組件所需數(shù)據(jù),每個(gè)屬性上面必須寫(xiě)好注釋?zhuān)驗(yàn)槲覀儗?xiě)了一個(gè)腳本工具,執(zhí)行 yarn generate:schema 命令即可將 props 通過(guò)腳本自動(dòng)轉(zhuǎn)化為渲染表單的JSON Schema => autoplay-video/index.schema.json, 當(dāng)然這個(gè)文件開(kāi)發(fā)人員也可以選擇不自動(dòng)生成,自己手寫(xiě)也可以;

          然后開(kāi)發(fā)人員在 constants/devConfig.js 中編輯 componentList 即可實(shí)現(xiàn)本地調(diào)試;

          開(kāi)發(fā)測(cè)試完畢之后合并到master分支,此時(shí)通過(guò)CI執(zhí)行添加組件腳本 node scripts/updateComponent.js,將組件信息提交給服務(wù)端,對(duì)開(kāi)發(fā)流程無(wú)侵入,和平時(shí)開(kāi)發(fā)無(wú)區(qū)別。

          components_update:    image: registry.huajiao.com/gitlab-ci/dplt-core:0.1.5    stage: components_update    script:        - node scripts/updateComponent.js    only:        changes:            - src/js/components/**/*        refs:            - master    except:        - triggers

          添加組件之后需要將新的組件集合到預(yù)覽頁(yè)中,同樣是通過(guò)CI文件執(zhí)行新的腳本構(gòu)建和發(fā)布新的預(yù)覽頁(yè)。

          build_preview:    stage: build    script:        - PREVIEW_MODE=true yarn build    artifacts:        name: "$CI_COMMIT_SHA" # 每次提交一個(gè)功件        paths:            - dist        when: on_success    only:        refs:            - master    except:        - triggers
          deploy_preview: image: registry.huajiao.com/gitlab-ci/dplt-core:0.1.5 stage: deploy dependencies: - build_preview script: - PREVIEW_MODE=true node scripts/deploy.js only: refs: - master except: - triggers

          待發(fā)布完畢之后,在編輯器頁(yè)面調(diào)用新組件的時(shí)候就可以顯示出來(lái)了。

          if(PREVIEW_MODE === 'true') {        window.addEventListener("message", (event) => {            console.log('onMessage', event.data);            if(                typeof event.data === 'string'                && event.data !== ''            ) {                const message = JSON.parse(event.data);                if(message.identifier === 'jimu_preview') {                    if(message.type === 'updateView') {                        safeStart(); // 這里是清理組件重新初始化VUE                        loadConfig(message.data); // 這里是加載上面的預(yù)覽信息                    }                }            }        }, false);    }

          發(fā)布生成真正的文件同樣是依托 gitlab CI 功能,代碼如下

          build_template:    stage: build    script:        - yarn build:trigger    artifacts:        name: "$CI_COMMIT_SHA" # 每次提交一個(gè)功件        paths:            - dist        when: on_success    only:        - triggers
          deploy_template: image: registry.huajiao.com/gitlab-ci/dplt-core:0.1.5 stage: deploy dependencies: - build_template script: - node scripts/deploy.js only: - triggers

          當(dāng)用戶(hù)點(diǎn)擊發(fā)布時(shí),服務(wù)端調(diào)用 https://git.huajiao.com/api/v4/projects/772/trigger/pipeline 接口,將構(gòu)建頁(yè)面所需信息傳輸過(guò)去,CI接收到信息后將其進(jìn)行格式化并組裝成自己所需信息,然后構(gòu)建頁(yè)面并發(fā)布到測(cè)試環(huán)境/正式環(huán)境。

          if(process.env.DEPLOY_CONFIG) {    // 從環(huán)境變量取傳入配置    const DEPLOY_CONFIG = JSON.parse(process.env.DEPLOY_CONFIG);    config = {        componentList: DEPLOY_CONFIG.components.map(item => {            return {                id: item.cname,                style: JSON.parse(item.style),                props: JSON.parse(item.props)            }        }),        page: {            id: DEPLOY_CONFIG.pageId,            name: DEPLOY_CONFIG.pageName,            ...JSON.parse(DEPLOY_CONFIG.props),        }    };}

          前端可以通過(guò)服務(wù)端轉(zhuǎn)接的 gitlab 接口輪詢(xún) pipeline 狀態(tài),給用戶(hù)顯示發(fā)布進(jìn)度信息。

          {    "id": 161337,    "sha": "50e37a230e1f221ae1fdd9b28cf27d3c7eb1f9bb",    "ref": "master",    "status": "pending", // 這里的狀態(tài)    "web_url": "https://git.huajiao.com/frontend/cli/jimu/pipelines/161337",    "before_sha": "0000000000000000000000000000000000000000",    "tag": false,    "yaml_errors": null,    "user": {        "id": 18,        "name": "yyy",        "username": "zzzxxx-hj",        "state": "active",        "avatar_url": "https://secure.gravatar.com/avatar/39fe51fea0fca93e688cbae09d68b30f?s=80&d=identicon",        "web_url": "https://git.huajiao.com/zzzxxx-hj"    },    "created_at": "2021-07-01T09:29:00.210Z",    "updated_at": "2021-07-01T09:29:00.332Z",    "started_at": null,    "finished_at": null,    "committed_at": null,    "duration": null,    "coverage": null}

          五. END

          至此花椒的這套可視化搭建框架大致講解完畢,功能雖然還比較簡(jiǎn)陋,但它能切實(shí)解決目前我們前端組所遇到的難題,并且由于是我們自己組內(nèi)開(kāi)發(fā),可以自由拓展符合公司業(yè)務(wù)的功能;這套框架的編輯器和組件庫(kù)之間只通過(guò)iframe相關(guān)聯(lián),以前業(yè)務(wù)中積累的組件可以快速添加到該組件庫(kù)中,進(jìn)而豐富組件庫(kù),滿(mǎn)足業(yè)務(wù)方需求。
          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩午夜影院 | 91麻豆亚洲国产成人久久精品 | 亚洲图片乱伦小说 | 麻豆蜜桃69无码专区 | 欧美1234区黄片 |