手把手教你打造屬于自己團(tuán)隊的前端小報系統(tǒng)
???這是第?62?篇不摻水的原創(chuàng),想要了解更多,請戳上方藍(lán)色字體:政采云前端團(tuán)隊?關(guān)注我們吧~
本文首發(fā)于政采云前端團(tuán)隊博客:手把手教你打造屬于自己團(tuán)隊的前端小報系統(tǒng)
https://www.zoo.team/article/building-a-tabloid-system
前言
經(jīng)常關(guān)注我們政采云前端團(tuán)隊的同學(xué), 對下面這張圖應(yīng)該不陌生~
每周五下午我們會定時推送一期前端小報,里面匯集了一些精選的前端文章~
下面這張圖就是 政采云前端小報 (https://weekly.zoo.team/ )的官方站點(diǎn)的截圖,這個站點(diǎn)里面有我們歷史每期的匯總~
至今前端小報已經(jīng) 93 期,匯聚了 1000+ 文章,覆蓋了 50+ 大小分類,可謂是一個非常好的知識庫了~
前端小報的由來
持續(xù)學(xué)習(xí)是每個工程師必備的素養(yǎng),一個成長性的團(tuán)隊也同樣需要這樣一個持續(xù)學(xué)習(xí)的氛圍。那么如何通過技術(shù)的手段來幫助團(tuán)隊培養(yǎng)持續(xù)學(xué)習(xí)的氛圍呢?
政采云前端小報因此應(yīng)運(yùn)而生,它主要包含投稿、匯總沉淀、定時投遞三大核心模塊,這樣的一個系統(tǒng)可以讓大家輕松的將自己喜歡的文章分享到團(tuán)隊內(nèi)部,并且將文章進(jìn)行分類沉淀,營造團(tuán)隊的知識庫,方便大家查閱,同時小報系統(tǒng)也會在每周五進(jìn)行定時推送,方便大家了解最新的技術(shù)動向,前端小報系統(tǒng)是一個幫助我們營造團(tuán)隊內(nèi)部分享和學(xué)習(xí)氛圍的得力幫手~
那么這樣的一個小報系統(tǒng)是如何實現(xiàn)的呢?
如何設(shè)計一個小報系統(tǒng)
投稿
相信大家看到好的文章的時候,總會有忍不住想分享給別人的沖動,一個簡單易用的投遞功能可以很方便的滿足大家的分享欲望,將好的文章輸入到團(tuán)隊,幫助其他同學(xué)~
一個簡單容易的投稿功能,我們需要解決兩件事情:
1、如何能在看到好文章時,滿足分享的沖動
2、如何對投稿的文章進(jìn)行歸類收集,方便沉淀與查找
如果是一個單獨(dú)的錄入系統(tǒng),手動錄入,這種方式操作繁瑣,很容易打消大家的熱情,平時在瀏覽器看文章的時候,我們經(jīng)常將好的文章加入書簽收藏,一鍵操作,方便快捷。那么如何能像瀏覽器書簽收藏文章一樣方便的去投稿呢?
很容易想到通過瀏覽器的擴(kuò)展能力去做這個事情,Chrome 插件就提供了這樣的能力
什么是 Chrome 插件
官方解釋 (https://developer.chrome.com/extensions):谷歌插件是一種小型的用于定制瀏覽器體驗的程序。它可以使用戶根據(jù)個人需要或偏好來定制 ?Chrome 的功能和行為,它們基于 Web 技術(shù)(HTML,JavaScript 和 CSS)構(gòu)建。
說人話:開發(fā)一個 Web 項目,能夠嵌入到 Chrome 瀏覽器中,同時能夠通過一些特定的 Api 獲取到一些能力,從而訂制自己的插件功能
如何開發(fā)一個一鍵投稿的 Chrome 插件
首先創(chuàng)建一個項目,開發(fā)一個投稿功能頁面 。
此項目和普通 Vue 項目唯一的區(qū)別是根目錄多了一個manifest.json 文件。
創(chuàng)建
manifest.json:Chrome 通過識別項目根目錄是否有manifest.json文件來識別是否為 Chrome ?插件。
{???
??//?核心代碼?
??"name":?"Zoo!",?//?擴(kuò)展名?
??"browser_action":?{??
????"default_popup":?"./popup.html"??//?點(diǎn)擊瀏覽器右上方插件小圖標(biāo)彈出的內(nèi)容?html?
??},?
??"content_scripts":?[??//?能夠在??Web?頁面內(nèi)運(yùn)行的?javascript?腳本?
????{?
??????"matches":?[
????????//?滿足什么協(xié)議下進(jìn)行調(diào)用?
????????"http://*/*",??
????????"https://*/*"?
??????],?
??????"js":?[?
????????"./contentScripts/zdata.js"?//?插入到網(wǎng)頁的?JS?文件路徑?
??????],?
????????"run_at":?"document_start"?//?在document?加載時執(zhí)行?
????}?
??]?
}?
這樣插件被打開時會默認(rèn)加載 popup.html 頁面的內(nèi)容,效果如圖:

- 如何獲取文章標(biāo)題、簡介、URL
let?host?=?this;
//?獲取當(dāng)前窗口?id?
chrome.tabs.query({
??active:?true,
??currentWindow:?true
},?function?(tabs)?{
??let?tabId?=?tabs.length???tabs[0].id?:?null;
??//?向當(dāng)前頁面注入?JavaScript?腳本?
??chrome.tabs.executeScript(tabId?||?null,?{
????file:?'./contentScripts/recommend.js'
??},?function?()?{
????//?向目標(biāo)網(wǎng)頁進(jìn)行通信,向?recommend.js?發(fā)送一個消息?
????chrome.tabs.sendMessage(tabId,?{
??????message:?'GET_TOPIC_INFO',
????},?function?(response)?{
??????//?獲取到返回的文章?title?、url、description?
??????host.article.title?=?response.title;
??????host.article.link?=?response.link;
??????host.article.description?=?response.description;
????});
??});
});???
recommend.js ?監(jiān)聽消息 ,通過 addListener 我們可以監(jiān)聽來自 ?sendMessage ?發(fā)出的消息,在 sendMessage 中定義 message 常量讓我們可以在接收消息時對消息進(jìn)行區(qū)分。
let?doc?=?document;
chrome.runtime.onMessage.addListener(function?(request,?sender,?sendResponse)?{
??if?(request.message?===?'GET_TOPIC_INFO')?{
????//?獲取?title?
????let?title?=?document.getElementsByTagName('title')[0].textContent;
????let?descriptionEl?=?doc.querySelectorAll('meta[name=description]')[0];
????//?獲取?描述?
????let?description?=?descriptionEl???descriptionEl.getAttribute('content')?:?title;
????//?發(fā)送數(shù)據(jù)?
????sendResponse({
??????title:?title.trim(),
??????link:?location.href,
??????description:?description.trim()
????});
??}?else?if?(request.message?===?'SIGN_RELOAD')?{
????console.log('request,?sender',?request,?sender);
??}
});?
- 點(diǎn)擊投稿時,需要將數(shù)據(jù)發(fā)送到服務(wù)端做存儲
//?投稿按鈕點(diǎn)擊事件?
handleRecommendArticle:?function?()?{
??let?request;
??request?=?ajax({
????method:?'post',
????url:?'https://XXX/api/post',?//?后端接口?
????data:?{
??????'title':?this.article.title,
??????'desc':?this.article.description,
??????'category':?this.article.category[1]?||?'默認(rèn)分類',
??????'link':?this.article.link,
??????'referrer':?this.article.reporter
????}
??});
}?
效果圖:
上面就是一個很輕量的 Chrome 插件的實現(xiàn)了,基于這樣的一個 Chrome 插件,當(dāng)我們看到喜歡的文章時,就可以一鍵分享給團(tuán)隊的小伙伴了~
當(dāng)文章多了之后,如果沒有有效的管理,文章會堆積雜亂,反而讓大家失去了去學(xué)習(xí)的欲望,那么我們?nèi)绾螌ν陡宓奈恼逻M(jìn)行歸類收集,方便同學(xué)們有查找自己需要的知識體系呢?
標(biāo)簽設(shè)計

- 標(biāo)簽分類
在標(biāo)簽分類上當(dāng)時花了一些時間去設(shè)計,難點(diǎn)主要是什么樣的分類維度能夠讓投稿人快速找到對應(yīng)的分類,讓查看人能夠快速根據(jù)分類找到自己想要的文章, 以及如何能夠快速找到往期文章等 。
這就要求我們的分類需通俗易懂,且能夠涵蓋業(yè)務(wù)大部分文章的類型,最后我們是從基礎(chǔ)、語言、架構(gòu)、選型、工具、總結(jié)等多維度進(jìn)行分類。
為了能夠快速進(jìn)行文章查找,這里將分類查看功能也集成在 Chrome 插件中
安裝插件
插件制作完成之后,其他同學(xué)就可以將你的插件安裝包安裝到瀏覽器中。因為墻的原因,這里沒有選擇將插件上傳到 Chrome 應(yīng)用商店,我們是直接安裝到本地, 下圖為打包后的項目目錄結(jié)構(gòu):
安裝步驟:瀏覽器選擇設(shè)置 —> 擴(kuò)展程序 —> 加載已解壓的擴(kuò)展程序 —> 選擇文件目錄即可。同時,開發(fā)者模式記得打開。
關(guān)于 Chrome 擴(kuò)展 插件的官方 詳細(xì)文檔請移步鏈接(https://developer.chrome.com/extensions) 查看
匯總沉淀
很普通一個前端項目,這里不再過多陳述,主要是能夠看到每一期文章和按照分類進(jìn)行快速查找,并統(tǒng)一收錄文章入口。其中,前端頁面采用 SSR 服務(wù)端渲染實現(xiàn)。

定時投遞
到這里小報系統(tǒng)的前臺展示頁面已經(jīng)完成,那么如何將每一期的優(yōu)質(zhì)文章更及時且方便的讓同學(xué)能夠閱讀到呢,讓大家及時的去了解新技術(shù),擴(kuò)充視野。后來我們想可以通過主動觸達(dá),定時提醒等方式將期刊主動發(fā)送給團(tuán)隊同學(xué)。因此在上述基礎(chǔ)上單獨(dú)設(shè)計 了一個推送服務(wù),定時將每一周的小報推送到釘釘群和前端郵件組。
通過釘釘群機(jī)器人,每周五將期刊發(fā)送到前端群里。詳情見官方開發(fā)手冊 (https://ding-doc.dingtalk.com/doc#/serverapi2/ye8tup/7ae8ebf3)

const?pushToRobot?=?async?({?data,?title,?nums?})?=>?{
??//?組裝發(fā)送數(shù)據(jù)格式?
??const?links?=?wrapperFeedcard({?data,?nums?});
??//?發(fā)送數(shù)據(jù)到指定群?
??return?axios("https://oapi.dingtalk.com/robot/send?",?{
????method:?"post",
????params:?{
??????access_token:?"XXXX"?//前端群?
????},
????data:?{
??????feedCard:?{
????????links
??????},
??????msgtype:?"feedCard"
????}
??})
};?
通過郵件發(fā)送, 每周定時發(fā)送郵件到團(tuán)隊郵件組。

//?創(chuàng)建郵件鏈接?
const?nodemailer?=?require("nodemailer");?
let?transporter?=?nodemailer.createTransport({?
??service:?"qiye.aliyun",?
??port:?25,?//?SMTP?端口?
??host:?"smtp.mxhichina.com",?
??secureConnection:?true,?//?使用了?SSL?
??auth:?{?
????user:?"[email protected]",?
????pass:?"xxx"?
??}?
});?
//?組裝發(fā)送內(nèi)容?
let?mailOptions?=?{?
??from:?'"政采云前端小報"?' ,?//?sender?address?
??to:?"[email protected]",?//?list?of?receivers?
??cc:?["[email protected]"],?
??html:?'郵件內(nèi)容'?//?html?body?
};?
//?郵件發(fā)送?
transporter.sendMail(mailOptions);?
定時發(fā)布掘金
有一天我們的掘金運(yùn)營小姐姐和我說,每周五快下班時都要進(jìn)行文章發(fā)布,太痛苦了,耽誤我下班約會,掘金為啥沒有定時發(fā)送功能?我說好吧,那咱們自己開發(fā)個定時發(fā)布功能吧,想知道如何實現(xiàn)掘金定時發(fā)布功能,可在評論區(qū)留言討論。
整體設(shè)計

總結(jié)
前端小報系統(tǒng)雖然是個小系統(tǒng) ,但是不論從功能設(shè)計,還是系統(tǒng)設(shè)計方面都奔著一個目標(biāo),努力推動團(tuán)隊的學(xué)習(xí)氛圍,讓團(tuán)隊同學(xué)持續(xù)的成長。希望通過本文分享能夠給大家一些啟發(fā),如何從一個目標(biāo)出發(fā)去拆解落地,去思考如何讓工具的去更好的服務(wù)于人。
推薦閱讀
我的公眾號能帶來什么價值?(文末有送書規(guī)則,一定要看)
每個前端工程師都應(yīng)該了解的圖片知識(長文建議收藏)
為什么現(xiàn)在面試總是面試造火箭?
