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

- 如何獲取文章標(biāo)題、簡(jiǎn)介、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ā)送一個(gè)消息?
????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 常量讓我們可以在接收消息時(shí)對(duì)消息進(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í),需要將數(shù)據(jù)發(fā)送到服務(wù)端做存儲(chǔ)
//?投稿按鈕點(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
????}
??});
}?
效果圖:
上面就是一個(gè)很輕量的 Chrome 插件的實(shí)現(xiàn)了,基于這樣的一個(gè) Chrome 插件,當(dāng)我們看到喜歡的文章時(shí),就可以一鍵分享給團(tuán)隊(duì)的小伙伴了~
當(dāng)文章多了之后,如果沒有有效的管理,文章會(huì)堆積雜亂,反而讓大家失去了去學(xué)習(xí)的欲望,那么我們?nèi)绾螌?duì)投稿的文章進(jìn)行歸類收集,方便同學(xué)們有查找自己需要的知識(shí)體系呢?
標(biāo)簽設(shè)計(jì)

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

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

//?創(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:?'"政采云前端小報(bào)"?' ,?//?sender?address?
??to:?"[email protected]",?//?list?of?receivers?
??cc:?["[email protected]"],?
??html:?'郵件內(nèi)容'?//?html?body?
};?
//?郵件發(fā)送?
transporter.sendMail(mailOptions);?
定時(shí)發(fā)布掘金
有一天我們的掘金運(yùn)營(yíng)小姐姐和我說,每周五快下班時(shí)都要進(jìn)行文章發(fā)布,太痛苦了,耽誤我下班約會(huì),掘金為啥沒有定時(shí)發(fā)送功能?我說好吧,那咱們自己開發(fā)個(gè)定時(shí)發(fā)布功能吧,想知道如何實(shí)現(xiàn)掘金定時(shí)發(fā)布功能,可在評(píng)論區(qū)留言討論。
整體設(shè)計(jì)

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