2018一些重要的地雷跟突破
2018
即將結束
花一點時間整理一下今年一些比較的地雷跟突破
Google Analytics Report API
之前在公司的某個專案有使用到Google Analytics Report API(那時候是使用v3)
那時候看配合後端人員在串這個
光聽完他講解串接的流程就傻眼
因為真的太過複雜
而且還不是程式寫完就好
之後每次只要佈署一個新的客戶
就要到Google API Console做一堆設定
最近自己的專案也開始嘗試串這個API
幸運的是
我最近開始串的時候有出了v4
v4有些流程有簡化(包含Google API Console的設定)
讓我沒有串的那麼痛苦
而且往後的設定也算是輕鬆
Google Photo API
本來串這個API是打算可以在自己系統中使用Google Photo當圖片庫
方便直接設定文章圖片
這是串好的樣子
一開始想的很美好
後來也真的串好了能夠設定文章圖片
結果後來發現圖片過沒多久就失效
最後仔細看完官方文件才發現
Google Photo好像不太想被直接拿來當圖片庫來call
所以他的圖片url只有一小時有效
看到這裡才有點後悔一開始沒仔細看清楚文件
結果花了一個禮拜發現加入系統的圖片url只有一小時有用
但是其實說真的那一個禮拜也不是真的白白浪費
如果真的要可行只要我系統有一個圖片庫系統
新增圖片的方式除了上傳
還能用Google Photo API抓取圖片下載回來再上傳
這種情境下其實一個小時的時效問題就不是問題
當然也學到教訓
之後看文件還要再看仔細一點
未來再找機會把這個功能弄回自己系統中
Webpack跟yargs的矛盾
今年我開發滿多Node.js的App
做了很多Server Side的Micro Service
像是puppeteer-server-side-render、cron-service、line-weather-notify、ciao-deploy
這種Micro Service做多了之後發現很多都需要設定檔
而我們通常都透過CLI的參數來指定設定檔的路徑
或是設定其他CLI的參數來做更多設定
這時候我們就會需要類似yargs這種專門處理CLI參數的Node.js套件
一開始我是希望透過CLI參數指定js或json設定檔
然後透過yargs取得路徑後在Node.js中動態import那支設定檔
但是Webpack最大的問題就是打包後路徑會直接寫死
動態載入設定檔的方法不可行
後來找到終於找到解決方式
想要享受Webpack帶來的便利
就要解決yargs動態載入的問題
yargs在Webpack中不能直接使用
不過沒關係
因為我最主要只是想使用它本身最厲害的處理CLI參數功能
所以只要裝它的核心功能yargs-parser就可以了
另外因為不能動態import js
所以我們要在CLI帶入json設定檔路徑
再利用Node.js的readFileSync去讀那隻json設定檔
大概是這樣
就可以解決上述問題然後繼續使用Webpack開發Node.js
// CLI範例: node app.js --config=/home/$USER/config.json
import yargsParser from 'yargs-parser'
global.args = yargsParser(process.argv.slice(2))
// ...
const config = JSON.parse(readFileSync(argv.config, 'utf8'))
這個問題找了一小段時間才找到核心問題還有解法(這段期間也不知不覺開發了兩三個Service)
當然
如果不是用Webpack開發Node.js的話
就不會遇到上述問題
就單看開發人員對於Webpack的喜好程度來取捨
我個人是覺得開發好打包成一支js真的很好傳輸、發佈
不用每次佈署都要clone專案然後yarn install
所以就偏向使用Webpack開發
Ajax Reuqest因為url多加一個斜線導致被拒絕
這個問題算滿蠢的
簡單來說大概就是原本不知道下面兩種url其實是不一樣的
/api?foo=bar
/api/?foo=bar
結果造成發ajax的時候一直被自己的Server拒絕
看Chrome的Debug Network一直出現ajax request 301 Moved Permanently這個錯誤
最好笑的是這個搞錯的api是拿來上傳圖片的api
而且傳到server存好圖片資料後圖片再傳到S3
所以一開始我一直以為是在S3那邊被擋掉
一直去看S3的上傳檔案的文件
然後看301 error的處理方式
結果都找不到解
更頭痛的是這個問題本機開發都沒有
只有上正式機EC2才出現
所以一開始真的不知道怎麼debug
還好後來檢查前端發的ajax url後有發現
改完之後就搞定
結束了一場鬧劇
寫了一個Chrome Extension給家人方便課程搶票
這個課程是我妹要上畫畫才藝班的課
然後這個課在台中算是滿搶手
每次開放報名都三五分鐘就搶光
我媽說之前他很多次都搶不到
兩年前開始我就開始幫忙搶票
最一開始我是先寫一段js貼在chrome console中執行
算是快速填完表單
最後只要手動人工填完驗證碼就好
那次開始之後我們都是第一個搶到
後來發現需要自動倒數時間+自動填表單比較方便
所以去年開始我是用那時候剛接觸的nightwatch.js來寫自動填單(雖然nightwatch.js是測試工具)
用nightwatch.js自動倒數+填單後就更加方便了
但是唯一麻煩的地方就是我還是要搶課前開啟nightwatch.js來倒數搶票
每次搶課都是早上九點要搶
結果我都要八點我就起床開nightwatch.js來跑
有時候真的不太想那麼早起
所以今年就稍微研究了一下chrome extension
寫了簡單的套件
可以先設定好所有要填的資料
只要按下倒數就可以了
這個因為操作比開nightwatch.js簡單多了
我做好這個chrome extension後
就可以交給我媽自己搶票了
醫療系統的X光片結節標識系統做到跟桌面軟體一樣
這個是公司的一個專案
客戶是打算做一個線上的醫療系統
主要功能就是讓使用者能夠上傳自己的肺部X光照
然後交給醫師透過我們做的系統標識有肺部結節的地方
最初客戶的客戶(也就是醫生)是透過一套叫Osirix的Mac桌面軟體來標識結節
而現階段是要把這套標識的功能搬到Web上
這個對我們來說算是滿大的挑戰
簡單講一下標識界面的主要需求
- 要讓醫生能夠透過滑鼠框出有問題的結節(這個動作叫標識)
- 照片能夠自由放大、縮小、拖曳移動(因為結節有時候很小)
- 一個人的X光照就有上百張,客戶希望能夠透過滑鼠滾輪快速切換X光照而且不能有任何delay(基本上要快到跟動畫一樣)
- 已經標過得標識(上面第一點的動作)要可以點兩下修改(包含移動、縮放)
- 大量的大檔案上傳而且要能續傳
一開始光知道這幾個主要需求就有點頭痛
真的是不太好做
尤其是要可以縮放
這個會影響到畫標識(方框)的相對位置
還有大量圖片快速切換而不能卡的問題(最後解法是先預載用server push載入全部上百張的圖片然後滑鼠滾輪切換z-index來更換圖片)
這中間tune了又tune終於解決了各種極端的需求
算是在工作上真的有遇到大量技術困難點的一次經驗
不過搞定後經驗值算是有提昇
最後交付時客戶的回應也超乎預期
只說了一句:系統真的很好用,跟原本的桌面軟體幾乎一樣
算是目前聽過最好的回應
這段期間也研究了許多套件
然後把這些套件使用到極致
像是jquery-panzoom、jquery-ui的(draggable resizable)、uppy
還有學到平常不會用到的續傳協定tus
算是成功、圓滿而且滿有收穫的一個專案
因為head中錯誤的html格式,造成Facebook crawler把meta移到body中
先說一下結果
這個問題主要是因為我在meta中放入不正確的html
然後Facebook Crawler來爬的時候
vue-meta設定好的tag就被移到body中(不知道為什麼,但是這個狀況只在Facebook Crawler中會發生)
造成Open Graph Tag整個抓不到
事發原因
後來才發現
因為我系統提供後台可以設定Google Tag Manager的功能
正常的GTM代碼是一個script tag包起來的代碼
但是我系統初始化時那個GTM代碼的欄位是一串預設字串Google Tag Manager
然後前端抓到這個字串就直接塞到head中
因為純字串並不是正確的HTML格式
然後就造成上述的結果
Debug過程
雖然是一個小小的錯誤
但是debug還滿久的
因為一開始沒想到是HTML格式問題
還以為是我的SSR Crawler壞掉
還是vue-meta這個套件的問題
找了快兩個禮拜才發現原來是自己系統塞了純字串到head中
這個問題沒遇過還真的不知道會連到影響到meta
Line Notify API發圖片的問題(axios在Node.js不能使用multipart上傳檔案)
在今年的最後一個月
有開發一個用Line做氣象通知的小專案
專門發氣象通知給家人群組用的
其中有一個功能是用puppeteer截空氣盒子的空氣品質截圖
截圖後要用Line Notify API把圖片發出去
一開始我是用axios發Line Notify API
使用的時候發現單純發訊息的時候會成功
但是只要用multipart夾帶圖片時就會被擋掉
而且Line的Server也只回應說圖片不正確
查了一下發現有人跟我遇到一樣的issue
axios其實在Node.js中不支援multipart
雖然issue內有其他人提到說可以裝form data的package來解
但是我裝完form data試了很多次還是不行
後來直接用curl來發Line通知
而且更簡單幾乎一行就解決
搞定後終於可以繼續開發下去