成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

可能是你見過最完善的微前端解決方案

Kahn / 1664人閱讀

摘要:而從技術(shù)實現(xiàn)角度,微前端架構(gòu)解決方案大概分為兩類場景單實例即同一時刻,只有一個子應(yīng)用被展示,子應(yīng)用具備一個完整的應(yīng)用生命周期。為了解決產(chǎn)品研發(fā)之間各種耦合的問題,大部分企業(yè)也都會有自己的解決方案。

原文鏈接:https://zhuanlan.zhihu.com/p/...

Techniques, strategies and recipes for building a modern web app with multiple teams using different JavaScript frameworks.                — Micro Frontends
前言

TL;DR

想跳過技術(shù)細節(jié)直接看怎么實踐的同學(xué)可以拖到文章底部,直接看最后一節(jié)。

目前社區(qū)有很多關(guān)于微前端架構(gòu)的介紹,但大多停留在概念介紹的階段。而本文會就某一個具體的類型場景,著重介紹微前端架構(gòu)可以帶來什么價值以及具體實踐過程中需要關(guān)注的技術(shù)決策,并輔以具體代碼,從而能真正意義上幫助你構(gòu)建一個生產(chǎn)可用的微前端架構(gòu)系統(tǒng)。

而對于微前端的概念感興趣或不熟悉的同學(xué),可以通過搜索引擎來獲取更多信息,如 知乎上的相關(guān)內(nèi)容, 本文不再做過多介紹。

兩個月前 Twitter 曾爆發(fā)過關(guān)于微前端的“熱烈”討論,參與大佬眾多(Dan、Larkin 等),對“事件”本身我們今天不做過多評論(后面可能會寫篇文章來回顧一下),有興趣的同學(xué)可以通過這篇文章了解一二。

微前端的價值

微前端架構(gòu)具備以下幾個核心價值:

技術(shù)棧無關(guān)
主框架不限制接入應(yīng)用的技術(shù)棧,子應(yīng)用具備完全自主權(quán)

獨立開發(fā)、獨立部署
子應(yīng)用倉庫獨立,前后端可獨立開發(fā),部署完成后主框架自動完成同步更新

獨立運行時
每個子應(yīng)用之間狀態(tài)隔離,運行時狀態(tài)不共享

微前端架構(gòu)旨在解決單體應(yīng)用在一個相對長的時間跨度下,由于參與的人員、團隊的增多、變遷,從一個普通應(yīng)用演變成一個巨石應(yīng)用(Frontend Monolith)后,隨之而來的應(yīng)用不可維護的問題。這類問題在企業(yè)級 Web 應(yīng)用中尤其常見。

針對中后臺應(yīng)用的解決方案

中后臺應(yīng)用由于其應(yīng)用生命周期長(動輒 3+ 年)等特點,最后演變成一個巨石應(yīng)用的概率往往高于其他類型的 web 應(yīng)用。而從技術(shù)實現(xiàn)角度,微前端架構(gòu)解決方案大概分為兩類場景:

單實例:即同一時刻,只有一個子應(yīng)用被展示,子應(yīng)用具備一個完整的應(yīng)用生命周期。通常基于 url 的變化來做子應(yīng)用的切換。

多實例:同一時刻可展示多個子應(yīng)用。通常使用 Web Components 方案來做子應(yīng)用封裝,子應(yīng)用更像是一個業(yè)務(wù)組件而不是應(yīng)用。

本文將著重介紹單實例場景下的微前端架構(gòu)實踐方案(基于 single-spa),因為這個場景更貼近大部分中后臺應(yīng)用。

行業(yè)現(xiàn)狀

傳統(tǒng)的云控制臺應(yīng)用,幾乎都會面臨業(yè)務(wù)快速發(fā)展之后,單體應(yīng)用進化成巨石應(yīng)用的問題。為了解決產(chǎn)品研發(fā)之間各種耦合的問題,大部分企業(yè)也都會有自己的解決方案。筆者于17年底,針對國內(nèi)外幾個著名的云產(chǎn)品控制臺,做過這樣一個技術(shù)調(diào)研:

產(chǎn)品 架構(gòu)(截止 2017-12) 實現(xiàn)技術(shù)
google cloud 純 SPA 主 portal angularjs,部分頁面 angular(ng2)。
aws 純 MPA 架構(gòu) 首頁基于 angularjs。各系統(tǒng)獨立域名。
七牛 SPA & MPA 混合架構(gòu) 入口 dashboard 及 個人中心模塊為 spa,使用同一 portal 模塊(AngularJs(1.5.10) + webpack)。其他模塊自治,或使用不同版本 portal,或使用其他技術(shù)棧。
又拍云 純 SPA 架構(gòu) 基于 angularjs 1.6.6 + ui-bootstrap??刂婆_內(nèi)容較簡單。
ucloud 純 SPA 架構(gòu) angularjs 1.3.12

MPA 方案的優(yōu)點在于 部署簡單、各應(yīng)用之間硬隔離,天生具備技術(shù)棧無關(guān)、獨立開發(fā)、獨立部署的特性。缺點則也很明顯,應(yīng)用之間切換會造成瀏覽器重刷,由于產(chǎn)品域名之間相互跳轉(zhuǎn),流程體驗上會存在斷點。

SPA 則天生具備體驗上的優(yōu)勢,應(yīng)用直接無刷新切換,能極大的保證多產(chǎn)品之間流程操作串聯(lián)時的流程性。缺點則在于各應(yīng)用技術(shù)棧之間是強耦合的。

那我們有沒有可能將 MPA 和 SPA 兩者的優(yōu)勢結(jié)合起來,構(gòu)建出一個相對完善的微前端架構(gòu)方案呢?

jsconf china 2016 大會上,ucloud 的同學(xué)分享了他們的基于 angularjs 的方案(單頁應(yīng)用“聯(lián)邦制”實踐),里面提到的 "聯(lián)邦制" 概念很貼切,可以認為是早期的基于耦合技術(shù)棧的微前端架構(gòu)實踐。

微前端架構(gòu)實踐中的問題

可以發(fā)現(xiàn),微前端架構(gòu)的優(yōu)勢,正是 MPA 與 SPA 架構(gòu)優(yōu)勢的合集。即保證應(yīng)用具備獨立開發(fā)權(quán)的同時,又有將它們整合到一起保證產(chǎn)品完整的流程體驗的能力。

這樣一套模式下,應(yīng)用的架構(gòu)就會變成:

Stitching layer 作為主框架的核心成員,充當調(diào)度者的角色,由它來決定在不同的條件下激活不同的子應(yīng)用。因此主框架的定位則僅僅是:導(dǎo)航路由 + 資源加載框架。

而具體要實現(xiàn)這樣一套架構(gòu),我們需要解決以下幾個技術(shù)問題:

路由系統(tǒng)及 Future State

我們在一個實現(xiàn)了微前端內(nèi)核的產(chǎn)品中,正常訪問一個子應(yīng)用的頁面時,可能會有這樣一個鏈路:

由于我們的子應(yīng)用都是 lazy load 的,當瀏覽器重新刷新時,主框架的資源會被重新加載,同時異步 load 子應(yīng)用的靜態(tài)資源,由于此時主應(yīng)用的路由系統(tǒng)已經(jīng)激活,但子應(yīng)用的資源可能還沒有完全加載完畢,從而導(dǎo)致路由注冊表里發(fā)現(xiàn)沒有能匹配子應(yīng)用 /subApp/123/detail 的規(guī)則,這時候就會導(dǎo)致跳 NotFound 頁或者直接路由報錯。

這個問題在所有 lazy load 方式加載子應(yīng)用的方案中都會碰到,早些年前 angularjs 社區(qū)把這個問題統(tǒng)一稱之為 Future State。

解決的思路也很簡單,我們需要設(shè)計這樣一套路由機制:

主框架配置子應(yīng)用的路由為 subApp: { url: "/subApp/**", entry: "./subApp.js" },則當瀏覽器的地址為 /subApp/abc 時,框架需要先加載 entry 資源,待 entry 資源加載完畢,確保子應(yīng)用的路由系統(tǒng)注冊進主框架之后后,再去由子應(yīng)用的路由系統(tǒng)接管 url change 事件。同時在子應(yīng)用路由切出時,主框架需要觸發(fā)相應(yīng)的 destroy 事件,子應(yīng)用在監(jiān)聽到該事件時,調(diào)用自己的卸載方法卸載應(yīng)用,如 React 場景下 destroy = () => ReactDOM.unmountAtNode(container)

要實現(xiàn)這樣一套機制,我們可以自己去劫持 url change 事件從而實現(xiàn)自己的路由系統(tǒng),也可以基于社區(qū)已有的 ui router library,尤其是 react-router 在 v4 之后實現(xiàn)了 Dynamic Routing 能力,我們只需要復(fù)寫一部分路由發(fā)現(xiàn)的邏輯即可。這里我們推薦直接選擇社區(qū)比較完善的相關(guān)實踐 single-spa。

App Entry

解決了路由問題后,主框架與子應(yīng)用集成的方式,也會成為一個需要重點關(guān)注的技術(shù)決策。

構(gòu)建時組合 VS 運行時組合

微前端架構(gòu)模式下,子應(yīng)用打包的方式,基本分為兩種:

方案 特點
構(gòu)建時 子應(yīng)用通過 Package Registry (可以是 npm package,也可以是 git tags 等其他方式) 的方式,與主應(yīng)用一起打包發(fā)布。
運行時 子應(yīng)用自己構(gòu)建打包,主應(yīng)用運行時動態(tài)加載子應(yīng)用資源。

兩者的優(yōu)缺點也很明顯:

方案 優(yōu)點 缺點
構(gòu)建時 主應(yīng)用、子應(yīng)用之間可以做打包優(yōu)化,如依賴共享等 子應(yīng)用與主應(yīng)用之間產(chǎn)品工具鏈耦合。工具鏈也是技術(shù)棧的一部分。
子應(yīng)用每次發(fā)布依賴主應(yīng)用重新打包發(fā)布
運行時 主應(yīng)用與子應(yīng)用之間完全解耦,子應(yīng)用完全技術(shù)棧無關(guān) 會多出一些運行時的復(fù)雜度和 overhead

很顯然,要實現(xiàn)真正的技術(shù)棧無關(guān)跟獨立部署兩個核心目標,大部分場景下我們需要使用運行時加載子應(yīng)用這種方案。

JS Entry vs HTML Entry

在確定了運行時載入的方案后,另一個需要決策的點是,我們需要子應(yīng)用提供什么形式的資源作為渲染入口?

JS Entry 的方式通常是子應(yīng)用將資源打成一個 entry script,比如 single-spa 的 example 中的方式。但這個方案的限制也頗多,如要求子應(yīng)用的所有資源打包到一個 js bundle 里,包括 css、圖片等資源。除了打出來的包可能體積龐大之外的問題之外,資源的并行加載等特性也無法利用上。

HTML Entry 則更加靈活,直接將子應(yīng)用打出來 HTML 作為入口,主框架可以通過 fetch html 的方式獲取子應(yīng)用的靜態(tài)資源,同時將 HTML document 作為子節(jié)點塞到主框架的容器中。這樣不僅可以極大的減少主應(yīng)用的接入成本,子應(yīng)用的開發(fā)方式及打包方式基本上也不需要調(diào)整,而且可以天然的解決子應(yīng)用之間樣式隔離的問題(后面提到)。想象一下這樣一個場景:




  
// 子應(yīng)用入口
ReactDOM.render(, document.getElementById("root"))

如果是 JS Entry 方案,主框架需要在子應(yīng)用加載之前構(gòu)建好相應(yīng)的容器節(jié)點(比如這里的 "#root" 節(jié)點),不然子應(yīng)用加載時會因為找不到 container 報錯。但問題在于,主應(yīng)用并不能保證子應(yīng)用使用的容器節(jié)點為某一特定標記元素。而 HTML Entry 的方案則天然能解決這一問題,保留子應(yīng)用完整的環(huán)境上下文,從而確保子應(yīng)用有良好的開發(fā)體驗。

HTML Entry 方案下,主框架注冊子應(yīng)用的方式則變成:

framework.registerApp("subApp1", { entry: "http://abc.alipay.com/index.html"})

本質(zhì)上這里 HTML 充當?shù)氖菓?yīng)用靜態(tài)資源表的角色,在某些場景下,我們也可以將 HTML Entry 的方案優(yōu)化成 Config Entry,從而減少一次請求,如:

framework.registerApp("subApp1", { html: "", scripts: ["http://abc.alipay.com/index.js"], css: ["http://abc.alipay.com/index.css"]})

總結(jié)一下:

App Entry 優(yōu)點 缺點
HTML Entry 1. 子應(yīng)用開發(fā)、發(fā)布完全獨立
2. 子應(yīng)用具備與獨立應(yīng)用開發(fā)時一致的開發(fā)體驗
1. 多一次請求,子應(yīng)用資源解析消耗轉(zhuǎn)移到運行時
2. 主子應(yīng)用不處于同一個構(gòu)建環(huán)境,無法利用 bundler 的一些構(gòu)建期的優(yōu)化能力,如公共依賴抽取等
JS Entry 主子應(yīng)用使用同一個 bundler,可以方便做構(gòu)建時優(yōu)化 1. 子應(yīng)用的發(fā)布需要主應(yīng)用重新打包
2. 主應(yīng)用需為每個子應(yīng)用預(yù)留一個容器節(jié)點,且該節(jié)點 id 需與子應(yīng)用的容器 id 保持一致
3. 子應(yīng)用各類資源需要一起打成一個 bundle,資源加載效率變低
模塊導(dǎo)入

微前端架構(gòu)下,我們需要獲取到子應(yīng)用暴露出的一些鉤子引用,如 bootstrap、mount、unmout 等(參考 single-spa),從而能對接入應(yīng)用有一個完整的生命周期控制。而由于子應(yīng)用通常又有集成部署、獨立部署兩種模式同時支持的需求,使得我們只能選擇 umd 這種兼容性的模塊格式打包我們的子應(yīng)用。如何在瀏覽器運行時獲取遠程腳本中導(dǎo)出的模塊引用也是一個需要解決的問題。

通常我們第一反應(yīng)的解法,也是最簡單的解法就是與子應(yīng)用與主框架之間約定好一個全局變量,把導(dǎo)出的鉤子引用掛載到這個全局變量上,然后主應(yīng)用從這里面取生命周期函數(shù)。

這個方案很好用,但是最大的問題是,主應(yīng)用與子應(yīng)用之間存在一種強約定的打包協(xié)議。那我們是否能找出一種松耦合的解決方案呢?

很簡單,我們只需要走 umd 包格式中的 global export 方式獲取子應(yīng)用的導(dǎo)出即可,大體的思路是通過給 window 變量打標記,記住每次最后添加的全局變量,這個變量一般就是應(yīng)用 export 后掛載到 global 上的變量。實現(xiàn)方式可以參考 systemjs global import,這里不再贅述。

應(yīng)用隔離

微前端架構(gòu)方案中有兩個非常關(guān)鍵的問題,有沒有解決這兩個問題將直接標志你的方案是否真的生產(chǎn)可用。比較遺憾的是此前社區(qū)在這個問題上的處理都會不約而同選擇”繞道“的方式,比如通過主子應(yīng)用之間的一些默認約定去規(guī)避沖突。而今天我們會嘗試從純技術(shù)角度,更智能的解決應(yīng)用之間可能沖突的問題。

樣式隔離

由于微前端場景下,不同技術(shù)棧的子應(yīng)用會被集成到同一個運行時中,所以我們必須在框架層確保各個子應(yīng)用之間不會出現(xiàn)樣式互相干擾的問題。

Shadow DOM?

針對 "Isolated Styles" 這個問題,如果不考慮瀏覽器兼容性,通常第一個浮現(xiàn)到我們腦海里的方案會是 Web Components?;?Web Components 的 Shadow DOM 能力,我們可以將每個子應(yīng)用包裹到一個 Shadow DOM 中,保證其運行時的樣式的絕對隔離。

但 Shadow DOM 方案在工程實踐中會碰到一個常見問題,比如我們這樣去構(gòu)建了一個在 Shadow DOM 里渲染的子應(yīng)用:

const shadow = document.querySelector("#hostElement").attachShadow({mode: "open"});
shadow.innerHTML = "Here is some new text

由于子應(yīng)用的樣式作用域僅在 shadow 元素下,那么一旦子應(yīng)用中出現(xiàn)運行時越界跑到外面構(gòu)建 DOM 的場景,必定會導(dǎo)致構(gòu)建出來的 DOM 無法應(yīng)用子應(yīng)用的樣式的情況。

比如 sub-app 里調(diào)用了 antd modal 組件,由于 modal 是動態(tài)掛載到 document.body 的,而由于 Shadow DOM 的特性 antd 的樣式只會在 shadow 這個作用域下生效,結(jié)果就是彈出框無法應(yīng)用到 antd 的樣式。解決的辦法是把 antd 樣式上浮一層,丟到主文檔里,但這么做意味著子應(yīng)用的樣式直接泄露到主文檔了。gg...

CSS Module? BEM?

社區(qū)通常的實踐是通過約定 css 前綴的方式來避免樣式?jīng)_突,即各個子應(yīng)用使用特定的前綴來命名 class,或者直接基于 css module 方案寫樣式。對于一個全新的項目,這樣當然是可行,但是通常微前端架構(gòu)更多的目標是解決存量/遺產(chǎn) 應(yīng)用的接入問題。很顯然遺產(chǎn)應(yīng)用通常是很難有動力做大幅改造的。

最主要的是,約定的方式有一個無法解決的問題,假如子應(yīng)用中使用了三方的組件庫,三方庫在寫入了大量的全局樣式的同時又不支持定制化前綴?比如 a 應(yīng)用引入了 antd 2.x,而 b 應(yīng)用引入了 antd 3.x,兩個版本的 antd 都寫入了全局的 .menu class,但又彼此不兼容怎么辦?

Dynamic Stylesheet !

解決方案其實很簡單,我們只需要在應(yīng)用切出/卸載后,同時卸載掉其樣式表即可,原理是瀏覽器會對所有的樣式表的插入、移除做整個 CSSOM 的重構(gòu),從而達到 插入、卸載 樣式的目的。這樣即能保證,在一個時間點里,只有一個應(yīng)用的樣式表是生效的。

上文提到的 HTML Entry 方案則天生具備樣式隔離的特性,因為應(yīng)用卸載后會直接移除去 HTML 結(jié)構(gòu),從而自動移除了其樣式表。

比如 HTML Entry 模式下,子應(yīng)用加載完成的后的 DOM 結(jié)構(gòu)可能長這樣:


  
  
    
// 子應(yīng)用完整的 html 結(jié)構(gòu)
....

當子應(yīng)用被替換或卸載時,subApp 節(jié)點的 innerHTML 也會被復(fù)寫,//alipay.com/subapp.css 也就自然被移除樣式也隨之卸載了。

JS 隔離

解決了樣式隔離的問題后,有一個更關(guān)鍵的問題我們還沒有解決:如何確保各個子應(yīng)用之間的全局變量不會互相干擾,從而保證每個子應(yīng)用之間的軟隔離?

這個問題比樣式隔離的問題更棘手,社區(qū)的普遍玩法是給一些全局副作用加各種前綴從而避免沖突。但其實我們都明白,這種通過團隊間的”口頭“約定的方式往往低效且易碎,所有依賴人為約束的方案都很難避免由于人的疏忽導(dǎo)致的線上 bug。那么我們是否有可能打造出一個好用的且完全無約束的 JS 隔離方案呢?

針對 JS 隔離的問題,我們獨創(chuàng)了一個運行時的 JS 沙箱。簡單畫了個架構(gòu)圖:

即在應(yīng)用的 bootstrap 及 mount 兩個生命周期開始之前分別給全局狀態(tài)打下快照,然后當應(yīng)用切出/卸載時,將狀態(tài)回滾至 bootstrap 開始之前的階段,確保應(yīng)用對全局狀態(tài)的污染全部清零。而當應(yīng)用二次進入時則再恢復(fù)至 mount 前的狀態(tài)的,從而確保應(yīng)用在 remount 時擁有跟第一次 mount 時一致的全局上下文。

當然沙箱里做的事情還遠不止這些,其他的還包括一些對全局事件監(jiān)聽的劫持等,以確保應(yīng)用在切出之后,對全局事件的監(jiān)聽能得到完整的卸載,同時也會在 remount 時重新監(jiān)聽這些全局事件,從而模擬出與應(yīng)用獨立運行時一致的沙箱環(huán)境。

螞蟻的微前端落地實踐

自去年年底伊始,我們便嘗試基于微前端架構(gòu)模式,構(gòu)建出一套全鏈路的面向中后臺場景的產(chǎn)品接入平臺,目的是解決不同產(chǎn)品之間集成困難、流程割裂的問題,希望接入平臺后的應(yīng)用,不論使用哪種技術(shù)棧,在運行時都可以通過自定義配置,實現(xiàn)不同應(yīng)用之間頁面級別的自由組合,從而生成一個千人千面的個性化控制臺。

目前這套平臺已在螞蟻生產(chǎn)環(huán)境運行半年多,同時接入了多個產(chǎn)品線的 40+ 應(yīng)用、4+ 不同類型的技術(shù)棧。過程中針對大量微前端實踐中的問題,我們總結(jié)出了一套完整的解決方案:

在內(nèi)部得到充分的技術(shù)驗證和線上考驗之后,我們決定將這套解決方案開源出來!

qiankun - 一套完整的微前端解決方案

https://github.com/umijs/qiankun

取名 qiankun,意為統(tǒng)一。我們希望通過 qiankun 這種技術(shù)手段,讓你能很方便的將一個巨石應(yīng)用改造成一個基于微前端架構(gòu)的系統(tǒng),并且不再需要去關(guān)注各種過程中的技術(shù)細節(jié),做到真正的開箱即用和生產(chǎn)可用。

對于 umi 用戶我們也提供了配套的 qiankun 插件 @umijs/plugin-qiankun ,以便于 umi 應(yīng)用能幾乎零成本的接入 qiankun。

最后歡迎大家點贊使用提出寶貴的意見。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/109998.html

相關(guān)文章

  • 新手也能實現(xiàn),基于SpirngBoot2.0+ 的 SpringBoot+Mybatis 多數(shù)據(jù)源配

    摘要:下面基于,帶著大家看一下中如何配置多數(shù)據(jù)源。注意版本不一致導(dǎo)致的一些小問題。配置配置兩個數(shù)據(jù)源數(shù)據(jù)庫和數(shù)據(jù)庫注意事項在配置數(shù)據(jù)源的過程中主要是寫成和。五啟動類此注解表示啟動類這樣基于的多數(shù)據(jù)源配置就已經(jīng)完成了,兩個數(shù)據(jù)庫都可以被訪問了。 在上一篇文章《優(yōu)雅整合 SpringBoot+Mybatis ,可能是你見過最詳細的一篇》中,帶著大家整合了 SpringBoot 和 Mybatis...

    shiina 評論0 收藏0
  • 立即收藏!這應(yīng)該是你見過的最全前端下載總結(jié)

    摘要:這應(yīng)該是你見過的最全前端下載總結(jié)自己整理的一些項目中遇到過的關(guān)于上傳和下載的一些,大前端系列也就是純前端端完成的下載,只要獲取到數(shù)據(jù)下載工作全是前端來做,僅供給位看官參考,避免踩坑,即插即用,歡迎和 這應(yīng)該是你見過的最全前端下載總結(jié)自己整理的一些項目中遇到過的關(guān)于上傳和下載的一些Demo,大前端系列(也就是純前端 + node端完成的下載,只要獲取到數(shù)據(jù)下載工作全是前端來做),僅供給位...

    LancerComet 評論0 收藏0
  • 優(yōu)秀文章收藏(慢慢消化)持續(xù)更新~

    摘要:整理收藏一些優(yōu)秀的文章及大佬博客留著慢慢學(xué)習(xí)原文協(xié)作規(guī)范中文技術(shù)文檔協(xié)作規(guī)范阮一峰編程風(fēng)格凹凸實驗室前端代碼規(guī)范風(fēng)格指南這一次,徹底弄懂執(zhí)行機制一次弄懂徹底解決此類面試問題瀏覽器與的事件循環(huán)有何區(qū)別筆試題事件循環(huán)機制異步編程理解的異步 better-learning 整理收藏一些優(yōu)秀的文章及大佬博客留著慢慢學(xué)習(xí) 原文:https://www.ahwgs.cn/youxiuwenzhan...

    JeOam 評論0 收藏0
  • 見過用命令行寫的簡歷嗎?

    摘要:異步任務(wù)的核心是名稱與任務(wù)名一致的函數(shù),該函數(shù)接受兩個參數(shù)一個函數(shù)和命令行的輸入值。 廢話:如果是不能給 hr 發(fā)這樣的簡歷之類大家都懂的話,麻煩您就不要回復(fù)了,謝謝! 國際慣例: https://github.com/dongsuo/vu... 正文: 作為一名程序員,還是有一份有特色的在線簡歷會比較好吧……在線簡歷很容易做得很丑哎……套模板這種事情有點丟人呀……那……干嘛不用程序...

    zhou_you 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<