你不再需要動態網頁——編輯-釋出-開發分離
儘管沒有特別的動力去構建一個全新的CMS,但是我還是願意去撰文一篇來書寫如何去做這樣的事——編輯-釋出-開發分離模式是如何工作的。微服務是我們對於複雜應用的一種趨勢,編輯-釋出-開發分離模式則是另外一種趨勢。在上篇文章《Repractise架構篇一: CMS的重構與演進》中,我們說到編輯-釋出-開發分離模式。
系統架構
如先前提到的,Carrot使用了下面的方案來搭建他們的靜態內容的CMS。
在這個方案裡內容是用Contentful來發布他們的內容。而在我司ThoughtWorks的官網裡則採用了Github來管理這些內容。於是如果讓我們寫一個基於Github的CMS,那麼架構變成了這樣:
或許你也用過Hexo / Jekyll / Octopress這樣的靜態部落格,他們的原理都是類似的。我們有一個程式碼庫用於生成靜態頁面,然後這些靜態頁面會被PUSH到Github Pages上。
從我們設計系統的角度來說,我們會在Github上有三個程式碼庫:
- Content。用於存放編輯器生成的JSON檔案,這樣我們就可以GET這些資源,並用Backbone / Angular / React 這些前端框架來搭建SPA。
- Code。開發者在這裡存放他們的程式碼,如主題、靜態檔案生成器、資原始檔等等。
- Builder。在這裡它是執行於Travis CI上的一些指令碼檔案,用於Clone程式碼,並執行Code中的指令碼。
以及一些額外的服務,當且僅當你有一些額外的功能需求的時候。
- Extend Service。當我們需要搜尋服務時,我們就需要這樣的一些服務。如我正考慮使用Python的whoosh來完成這個功能,這時候我計劃用Flask框架,但是隻是計劃中——因為沒有合適的中介軟體。
- Editor。相比於前面的那些知識這一步適合更重要,也就是為什麼生成的格式是JSON而不是Markdown的原理。對於非程式設計師來說,要熟練掌握Markdown不是一件容易的事。於是,一個考慮中的方案就是使用 Electron + Node.js來生成API,最後通過GitHub API V3來實現上傳。
So,這一個過程是如何進行的。
使用者場景
整個過程的Pipeline如下所示:
- 編輯使用他們的編輯器來編輯的內容並點選發布,然後這個內容就可以通過GitHub API上傳到Content這個Repo裡。
- 這時候需要有一個WebHooks監測到了Content程式碼庫的變化,便執行Builder這個程式碼庫的Travis CI。
- 這個Builder指令碼首先,會設定一些基本的git配置。然後clone Content和Code的程式碼,接著執行構建命令,生成新的內容。
- 然後Builder Commit內容,並PUSH內容。
這裡還依賴於WebHook這個東西——還沒想到一個合適的解決方案。下面,我們對裡面的內容進行一些拆解,Content裡面由於是JSON就不多解釋了。
Builder: 構建工具
Github與Travis之間,可以做一個自動部署的工具。相信已經有很多人在Github上玩過這樣的東西——先在Github上生成Token,然後用travis加密:
travis encrypt-file ssh_key --add
加密後的Key就會儲存到.travis.yml
檔案裡,然後就可以在Travis CI上push你的程式碼到Github上了。
接著,你需要建立個deploy指令碼,並且在after_success
執行它:
after_success:
- test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && bash deploy.sh
在這個指令碼里,你所需要做的就是clone content和code中的程式碼,並執行code中的生成指令碼,生成新的內容後,提交程式碼。
#!/bin/bash
set -o errexit -o nounset
rev=$(git rev-parse --short HEAD)
cd stage/
git init
git config user.name "Robot"
git config user.email "robot@phodal.com"
git remote add upstream "https://$GH_TOKEN@github.com/phodal-archive/echeveria-deploy.git"
git fetch upstream
git reset upstream/gh-pages
git clone https://github.com/phodal-archive/echeveria-deploy code
git clone https://github.com/phodal-archive/echeveria-content content
pwd
cp -a content/contents code/content
cd code
npm install
npm install grunt-cli -g
grunt
mv dest/* ../
cd ../
rm -rf code
rm -rf content
touch .
if [ ! -f CNAME ]; then
echo "deploy.baimizhou.net" > CNAME
fi
git add -A .
git commit -m "rebuild pages at ${rev}"
git push -q upstream HEAD:gh-pages
這就是這個builder做的事情——其中最主要的一個任務是grunt
,它所做的就是:
grunt.registerTask('default', ['clean', 'assemble', 'copy']);
Code: 靜態頁面生成
Assemble是一個使用Node.js,Grunt.js,Gulp,Yeoman 等來實現的靜態網頁生成系統。這樣的生成器有很多,Zurb Foundation, Zurb Ink, Less.js / lesscss.org, Topcoat, Web Experience Toolkit等組織都使用這個工具來生成。這個工具似乎上個Release在一年多以前,現在正在開始0.6。雖然,這並不重要,但是還是順便一說。
我們所要做的就是在我們的Gruntfile.js
中寫相應的生成程式碼。
assemble: {
options: {
flatten: true,
partials: ['templates/includes/*.hbs'],
layoutdir: 'templates/layouts',
data: 'content/blogs.json',
layout: 'default.hbs'
},
site: {
files: {'dest/': ['templates/*.hbs']}
},
blogs: {
options: {
flatten: true,
layoutdir: 'templates/layouts',
data: 'content/*.json',
partials: ['templates/includes/*.hbs'],
pages: pages
},
files: [
{ dest: './dest/blog/', src: '!*' }
]
}
}
配置中的site用於生成頁面相關的內容,blogs則可以根據json檔案的檔名生成對就的html檔案儲存到blog目錄中。
生成後的目錄結果如下圖所示:
.
├── about.html
├── blog
│ ├── blog-posts.html
│ └── blogs.html
├── blog.html
├── css
│ ├── images
│ │ └── banner.jpg
│ └── style.css
├── index.html
└── js
├── jquery.min.js
└── script.js
7 directories, 30 files
這裡的靜態檔案內容就是最後我們要釋出的內容。
還需要做的一件事情就是:
javascript
grunt.registerTask('dev', ['default', 'connect:server', 'watch:site']);
用於開發階段這樣的程式碼就夠了,這個和你使用WebPack + React 似乎相差不了多少。
編輯-釋出-開發分離
在這種情形中,編輯能否完成工作就不依賴於網站——脫稿又少了 個藉口。這時候網站出錯的概率太小了——你不需要一個快取伺服器、HTTP伺服器,由於沒有動態生成的內容,你也不需要守護程式。這些內容都是靜態檔案,你可以將他們放在任何可以提供靜態檔案託管的地方——CloudFront、S3等等。或者你再相信自己的伺服器,Nginx可是全球第二好(第一還沒出現)的靜態檔案伺服器。
開發人員只在需要的時候去修改網站的一些內容。
So,你可能會擔心如果這時候修改的東西有問題了怎麼辦。
- 使用這種模式就意味著你需要有測試來覆蓋這些構建工具、生成工具。
- 相比於自己的程式碼,別人的CMS更可靠?
需要注意的是如果你上一次構建成功,你生成的檔案都是正常的,那麼你只需要回滾開發相關的程式碼即可。舊的程式碼仍然可以工作得很好。
其次,由於生成的是靜態檔案,查錯的成本就比較低。
最後,重新放上之前的靜態檔案。
相關文章
- 開發動態編輯的表格
- 動態規劃-編輯距離動態規劃
- Martin Fowler 談“編輯”“釋出”相分離
- Martin Fowler談CMS系統中編輯-釋出模組的分離
- Jsp動態網頁開發JS網頁
- (五) 文章編輯頁開發
- Pisanix v0.2.0 釋出|新增動態讀寫分離支援
- Leetcode 編輯距離(動態規劃)LeetCode動態規劃
- 華為音訊編輯服務帶你一鍵伴奏分離!音訊
- iOS開發模式MVVM 2分離業務邏輯iOS模式MVVM
- 分頁練習-網頁開發常用網頁
- 文章編輯/釋出選擇分類不是很明顯
- 編輯距離及編輯距離演算法演算法
- Whisk for Mac 網頁編輯器Mac網頁
- 網頁編輯器 DIY (轉)網頁
- Firebug 2.0.7 釋出,Firefox 網頁開發外掛Firefox網頁
- Firebug 2.0.9 釋出,Firefox 網頁開發外掛Firefox網頁
- ASP.NET動態網站開發培訓-38.互動論壇製作(六、製作主題釋出頁面)ASP.NET網站
- ACE 1.1.9 釋出,開源雲端程式碼編輯器
- SSM動態展示分頁SSM
- 演算法:編輯距離問題(動態規劃,詳細解答)演算法動態規劃
- Feeder for Macrss文件編輯和釋出Mac
- Java編輯器jEdit 5.0釋出Java
- vue 釋出網頁Vue網頁
- Smultron for Mac 網頁文字編輯工具Mac網頁
- Smultron for Mac(網頁文字編輯器)Mac網頁
- xPath 動態分離XML資料XML
- 網頁版組態軟體之Sovit2D Web組態編輯器網頁Web
- 【DP】編輯距離
- DBPack 讀寫分離功能釋出公告
- ASP.NET動態網站開發培訓-26.線上編輯器FreeTextBox的使用ASP.NET網站
- mybatis動態sql與分頁MyBatisSQL
- django1.10開發部落格(7)——文章的新增、釋出、編輯、刪除Django
- 靜態網頁與動態網頁的區別網頁
- 靜態網頁和動態網頁的區別網頁
- Feeder for Mac rss文件編輯和釋出Mac
- Feeder for Mac(rss文件編輯和釋出)Mac
- 各網頁編輯器對照 (轉)網頁