在前端技術領域中,咱們能夠切身感覺獲得技術的更新、變革的速度是很是快的,因此工程師們都會須要時常關注和學習一些新技術、新標準。javascript
由於在工做中負責項目的技術棧相比於業界來講,算比較落後了,因此本身動手來開發一個音樂類 web app,能夠嘗試一些新技術棧,或者往一些特定方向深挖學習。css
項目開發時間從年底至今,利用工做之餘的時間斷斷續續地開發,主體功能已經大體完成了,接下來也會陸續添加一些新功能上去,也會持續優化代碼,在此也作一下記錄和總結。前端
在線體驗使用 chrome 移動端調試體驗vue
項目地址java
後端 api 是使用 NeteaseCloudMusicApi,提供了很是多接口,而且支持 CORS 跨域。node
項目分爲兩個部分,分別是前端,好比 javascript、css、img、components 等;還有服務端,負責請求響應和服務端渲染,因此項目總體架構如圖:webpack
項目剛開始使用 vue-cli 初始化,開箱即用的使用體驗爲我省去了很多繁瑣的流程,能夠直接上手進行開發。nginx
用戶登陸是首先須要解決的問題,由於許多接口都依賴用戶登陸態。最終是將 api 服務和項目分紅兩個子域名:git
163api.domain.cn // api 163music.domain.cn // 項目
可是後來發現,請求登陸接口成功後,用戶 cookie 沒法寫入到瀏覽器內,發現原來是 cookie 內的 domain 設置的是 api 子域名,因此致使 163music.domain.cn 下是沒法讀取到 cookie 的,可是通過調試發現,接口在 set cookie 的時候是並無設置 domain,解決方案是在 nginx 內加上 proxy_cookie_path 的配置,爲 cookie 添加 domain 爲 .domain.cn,那麼在其餘子域名下就能正常讀取到 cookie(剛開始設置的是替換 domain,然而不會生效):github
// nginx.conf server { listen 80; server_name 163api.domain.cn; location / { proxy_pass http://127.0.0.1:3000/; proxy_cookie_path ~^(.+)$ "$1; domain=domain.cn"; } }
在項目開始初期,一切都是那麼的和諧,能夠歡騰暢快的開發。開發到中期功能都完成的差很少時候決定添加 ssr 了。vue-cli 3 是能夠經過配置文件 vue.config.js 來實現自定義的 webpack 配置,在加入了 ssr 相關配置以後,就能夠成功構建打包了,但我但願代碼可以實時重載和模塊熱替換,否則開發效率會比較低下。而後,在嘗試了一些改造方案(一番掙扎)以後,仍是以爲不可以很靈活地實現,我決定從新搭建環境 Orz
主要的 webpack 配置是參考 vue-cli,node 代碼主要參考官方 demo,當代碼編寫好後就嘗試運行了,結果固然是...滿屏紅色報錯。
由於官方 demo 使用的 webpack 3,因此有些配置須要更新,還有一些依賴隨版本升級也須要更新調用方法等等。但值得高興的是,錯誤提示都基本是準確的,好比:
// 須要提供 mode 選項 The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
// 配置遷移,須要使用新配置選項 Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
還有可能會缺乏各類 loader,須要安裝各類依賴。確保構建流程正常後,就能夠打開瀏覽器內看效果了,但又會發現這樣的報錯:
window is not defined.
緣由是由於一個輪播插件內包含 window,而在 node 環境內是沒有這個全局變量的,因此致使了這個報錯。亦或者訪問其餘瀏覽器內置對象時,也會出現這樣相似的報錯,因此須要確保代碼和插件均可以在 node 環境下正常運行。由於輪播插件自己是支持 ssr 模式的,因此修改完代碼後便可正常運行。
最後,項目中共有四份 webpack 配置和兩個構建腳本。在開發環境下,搭配 webpack-dev-middleware 和 webpack-hot-middleware 來實現了代碼的熱加載。在生產環境構建時,由於但願能清晰看到錯誤和警告,也想對構建耗時進行統計,因此將構建腳本拎出來。
build ├── build-production.js // 生產環境構建腳本 ├── setup-dev-server.js // 開發環境構建腳本 ├── webpack.base.config.js // 基本配置 ├── webpack.client.config.js // 客戶端配置 ├── webpack.server.config.js // 服務端配置 └── webpack.test.config.js // 測試配置
音樂播放是最主要的核心功能,底層就是使用 audio 標籤,而且監聽了標籤元素的 canplay、timeupdate、ended 事件來分別實現時長計算、更新當前播放進度、下一首播放。
由於播放器是能夠支持「後臺」播放,因此將播放器放到根組件中而且設置隱藏,因此 dom 結構以下:
<div id="app"> <!-- audio --> <player></player> <transition :name="transitionName"> <router-view class="component"></router-view> </transition> <footBox></footBox> </div>
組件數據同步是使用 vuex,好比播放的狀態、歌曲總時長、當前的播放進度等,當歌曲播放完畢時候須要播放下一首,這裏使用的是 eventBus 來作事件觸發,它會比較適合這種相似的場景。
當用戶打開播放頁面時,我但願音樂是可以自動播放的,不管用戶是從其餘入口進來亦或者是直接刷新的時候。自動播放是經過 play() 方法去觸發的,前者沒有問題,可是後者在調用時就會提示錯誤,錯誤意思是須要用戶進行手勢操做以後纔可以播放,而後嘗試了模擬點擊、靜音播放的方案以後發如今 chrome 內依然無效,後來感受 chrome 這樣作是正確的,應該把網站的控制權交給用戶,讓用戶清楚頁面到底發生了什麼,而不是讓用戶在一堆標籤頁裏尋找是哪一個頁面發出了奇怪的聲音。
更新從播放列表進入播放頁後纔會自動播放,感謝小夥伴提供解決方案
單元測試也是早期規劃的功能之一,開始是參考一些開源項目來搭建,最終選型是 karma + mocha + sinon-chai (官方 demo)。搭建的過程就是摸着石頭過河了,其中也經歷了一些報錯,好比:安裝依賴失敗、配置文件出錯、缺乏依賴插件等等,而後接近搭建完成後才發現還有官方文檔。不得不說是, cli 的確幫開發者節省了很是多配置、搭建的工做,搭建完成以後就能夠根據官方文檔來編寫用例了,根據官方文檔內例子已經能夠覆蓋到絕大部分場景,好比模擬瀏覽器渲染、用戶點擊等等。但同時也發現一個問題,若是項目代碼常常發生變動的話,那麼以前的測試用例也可能須要從新編寫了,想知道你們在項目中是怎麼處理或者怎麼看待呢?
以上是在開發過程當中遇到一小部分問題,還有過程中大部分問題描述和解決方案就不在這裏一一展開去講了,你們若是有問題的地方,歡迎你們私信或者郵件與我交流。
use nginx to add Domain to a Set-Cookie
Cookies on localhost with explicit domain