你再也不須要動態網頁——編輯-發佈-開發分離

​儘管沒有特別的動力去構建一個全新的CMS,可是我仍是願意去撰文一篇來書寫如何去作這樣的事——編輯-發佈-開發分離模式是如何工做的。微服務是咱們對於複雜應用的一種趨勢,編輯-發佈-開發分離模式則是另一種趨勢。在上篇文章《Repractise架構篇一: CMS的重構與演進》中,咱們說到編輯-發佈-開發分離模式。javascript

系統架構

如先前提到的,Carrot使用了下面的方案來搭建他們的靜態內容的CMS。css

Carrot

在這個方案裏內容是用Contentful來發布他們的內容。而在我司ThoughtWorks的官網裏則採用了Github來管理這些內容。因而若是讓咱們寫一個基於Github的CMS,那麼架構變成了這樣:html

Github 編輯-發佈-開發

或許你也用過Hexo / Jekyll / Octopress這樣的靜態博客,他們的原理都是相似的。咱們有一個代碼庫用於生成靜態頁面,而後這些靜態頁面會被PUSH到Github Pages上。前端

從咱們設計系統的角度來講,咱們會在Github上有三個代碼庫:java

  1. Content。用於存放編輯器生成的JSON文件,這樣咱們就能夠GET這些資源,並用Backbone / Angular / React 這些前端框架來搭建SPA。jquery

  2. Code。開發者在這裏存放他們的代碼,如主題、靜態文件生成器、資源文件等等。git

  3. Builder。在這裏它是運行於Travis CI上的一些腳本文件,用於Clone代碼,並執行Code中的腳本。程序員

以及一些額外的服務,當且僅當你有一些額外的功能需求的時候。github

  1. Extend Service。當咱們須要搜索服務時,咱們就須要這樣的一些服務。如我正考慮使用Python的whoosh來完成這個功能,這時候我計劃用Flask框架,可是隻是計劃中——由於沒有合適的中間件。npm

  2. Editor。相比於前面的那些知識這一步適合更重要,也就是爲何生成的格式是JSON而不是Markdown的原理。對於非程序員來講,要熟練掌握Markdown不是一件容易的事。因而,一個考慮中的方案就是使用 Electron + Node.js來生成API,最後經過GitHub API V3來實現上傳。

So,這一個過程是如何進行的。

用戶場景

整個過程的Pipeline以下所示:

  1. 編輯使用他們的編輯器來編輯的內容並點擊發布,而後這個內容就能夠經過GitHub API上傳到Content這個Repo裏。

  2. 這時候須要有一個WebHooks監測到了Content代碼庫的變化,便運行Builder這個代碼庫的Travis CI。

  3. 這個Builder腳本首先,會設置一些基本的git配置。而後clone Content和Code的代碼,接着運行構建命令,生成新的內容。

  4. 而後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

這裏的靜態文件內容就是最後咱們要發佈的內容。

還須要作的一件事情就是:

grunt.registerTask('dev', ['default', 'connect:server', 'watch:site']);

用於開發階段這樣的代碼就夠了,這個和你使用WebPack + React 彷佛相差不了多少。

編輯-發佈-開發分離

在這種情形中,編輯可否完成工做就不依賴於網站——脫稿又少了 個藉口。這時候網站出錯的機率過小了——你不須要一個緩存服務器、HTTP服務器,因爲沒有動態生成的內容,你也不須要守護進程。這些內容都是靜態文件,你能夠將他們放在任何能夠提供靜態文件託管的地方——CloudFront、S3等等。或者你再相信本身的服務器,Nginx但是全球第二好(第一還沒出現)的靜態文件服務器。

開發人員只在須要的時候去修改網站的一些內容。

So,你可能會擔憂若是這時候修改的東西有問題了怎麼辦。

  1. 使用這種模式就意味着你須要有測試來覆蓋這些構建工具、生成工具。

  2. 相比於本身的代碼,別人的CMS更可靠?

須要注意的是若是你上一次構建成功,你生成的文件都是正常的,那麼你只須要回滾開發相關的代碼便可。舊的代碼仍然能夠工做得很好。

其次,因爲生成的是靜態文件,查錯的成本就比較低。

最後,從新放上以前的靜態文件。

相關文章
相關標籤/搜索