不知道大家有沒有發(fā)現(xiàn),長者們的網(wǎng)站都是相似的(比如上面這倆大佬Bjarne Stroustrup,Richard Stallman)扬卷,而粉絲們(比如我)的網(wǎng)站卻各有各的不同
其實在互聯(lián)網(wǎng)早期爆侣,所有網(wǎng)站差不多長這樣,他們都是靜態(tài)的琢锋,因為當(dāng)時壓根就沒有動態(tài)網(wǎng)站
不過我們今天要講的不是像長者們一樣的那種靜態(tài)網(wǎng)站,而是通過靜態(tài)網(wǎng)站生成器(SSG,Static Site Generator)生成的靜態(tài)網(wǎng)站
近年來呆盖,隨著瀏覽器發(fā)展,CDN成為主流,構(gòu)建工具的廣泛應(yīng)用以及入們對高性能的不斷追求,作為傳統(tǒng)動態(tài)網(wǎng)站基礎(chǔ)架構(gòu)的替代方案,現(xiàn)代靜態(tài)網(wǎng)站生成器日漸盛行摘仅。許多導(dǎo)致靜態(tài)網(wǎng)站失敗的限制已不復(fù)存在。現(xiàn)在问畅,每周都會有新的靜態(tài)網(wǎng)站生成器發(fā)布娃属。
下面我將帶大家一起了解靜態(tài)網(wǎng)站生成器的一些知識并利用靜態(tài)生成器搭建一個最基礎(chǔ)的靜態(tài)網(wǎng)站
什么是靜態(tài)網(wǎng)站?
我們在學(xué)習(xí)網(wǎng)站開發(fā)時寫的第一個頁面可能是這樣的:
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
將上面的內(nèi)容保存成index.html,然后扔到Apache服務(wù)器上,就可以通過互聯(lián)網(wǎng)順利訪問了
上面的index.html就叫一個靜態(tài)網(wǎng)頁,由一堆靜態(tài)網(wǎng)頁構(gòu)成的網(wǎng)站就叫靜態(tài)網(wǎng)站
在網(wǎng)站設(shè)計中护姆,純粹HTML(標(biāo)準(zhǔn)通用標(biāo)記語言下的一個應(yīng)用)格式的網(wǎng)頁通常被稱為“靜態(tài)網(wǎng)頁”矾端,靜態(tài)網(wǎng)頁是標(biāo)準(zhǔn)的HTML文件,它的文件擴(kuò)展名是.htm卵皂、.html秩铆,可以包含文本、圖像、聲音殴玛、FLASH動畫捅膘、客戶端腳本和ActiveX控件及JAVA小程序等。靜態(tài)網(wǎng)頁是網(wǎng)站建設(shè)的基礎(chǔ)滚粟,早期的網(wǎng)站一般都是由靜態(tài)網(wǎng)頁制作的寻仗。靜態(tài)網(wǎng)頁是相對于動態(tài)網(wǎng)頁而言,是指沒有后臺數(shù)據(jù)庫凡壤、不含程序和不可交互的網(wǎng)頁愧沟。靜態(tài)網(wǎng)頁相對更新起來比較麻煩,適用于一般更新較少的展示型網(wǎng)站鲤遥。容易誤解的是靜態(tài)頁面都是htm這類頁面沐寺,實際上靜態(tài)也不是完全靜態(tài),他也可以出現(xiàn)各種動態(tài)的效果盖奈,如GIF格式的動畫混坞、FLASH、滾動字幕等钢坦。
什么是動態(tài)網(wǎng)站?
動態(tài)網(wǎng)站并不是指具有動畫功能的網(wǎng)站究孕,而是指網(wǎng)站內(nèi)容可根據(jù)不同情況動態(tài)變更的網(wǎng)站,一般情況下動態(tài)網(wǎng)站通過數(shù)據(jù)庫進(jìn)行架構(gòu)爹凹。 動態(tài)網(wǎng)站除了要設(shè)計網(wǎng)頁外厨诸,還要通過數(shù)據(jù)庫和編程序來使網(wǎng)站具有更多自動的和高級的功能。動態(tài)網(wǎng)站體現(xiàn)在網(wǎng)頁一般是以asp禾酱,jsp微酬,php,aspx等結(jié)束颤陶,而靜態(tài)網(wǎng)頁一般是HTML(標(biāo)準(zhǔn)通用標(biāo)記語言的子集)結(jié)尾颗管,動態(tài)網(wǎng)站服務(wù)器空間配置要比靜態(tài)的網(wǎng)頁要求高,費用也相應(yīng)的高滓走,不過動態(tài)網(wǎng)頁利于網(wǎng)站內(nèi)容的更新垦江,適合企業(yè)建站。動態(tài)是相對于靜態(tài)網(wǎng)站而言搅方。
動態(tài)網(wǎng)站的內(nèi)容都是由服務(wù)器動態(tài)生成的,如WordPress等
靜態(tài)網(wǎng)站的優(yōu)點
-
訪問速度快
即使是最為優(yōu)化的動態(tài)網(wǎng)站比吭,其性能也無法同靜態(tài)網(wǎng)站相比。并且姨涡,對于動態(tài)網(wǎng)站而言衩藤,緩存失效非常難以恢復(fù),尤其是需要充分利用CDN的分布式緩存绣溜。靜態(tài)網(wǎng)站所有內(nèi)容都儲存在html里面慷彤,不需要后臺服務(wù)器對內(nèi)容進(jìn)行渲染,避免了查詢數(shù)據(jù)庫等操作怖喻,而且可以充分利用緩存和CDN -
非常安全
動態(tài)網(wǎng)站容易遭受蠕蟲攻擊底哗。據(jù)保守估計,超過70%的WordPress部署容易因為已知漏洞遭受攻擊(超過23%的Web網(wǎng)站以WordPress為基礎(chǔ)構(gòu)建)锚沸。網(wǎng)站安全兩大威脅SQL注入和XSS(cross-site scritpting)攻擊跋选,靜態(tài)站點都可以很好的避免 -
易于部署
沒有后端要求,想部署在哪兒就部署在哪兒 -
利于版本控制
靜態(tài)網(wǎng)站是由靜態(tài)文件組成哗蜈,所以非常容易使用Git等工具進(jìn)行版本控制
哪些網(wǎng)站可以是靜態(tài)的
-
博客
這也是靜態(tài)網(wǎng)站最主要的使用方式前标,與用戶的交流僅限與評論,而利用Disqus可以滿足該需求 -
文檔
僅次于博客的使用方式距潘,因為文檔需要方便用戶快速查看炼列,并且能夠進(jìn)行版本控制文檔,而文檔一般又不需要經(jīng)常更新,所以靜態(tài)網(wǎng)站非常合適,實際上,很多開源項目的文檔都是利用Jekyll做的 -
網(wǎng)頁海報
這類網(wǎng)站通常非常簡單音比,很適合做成靜態(tài)網(wǎng)站
一般來說內(nèi)容需要經(jīng)常改變的以及需要和用戶進(jìn)行高頻度的交互的網(wǎng)站都不適合做成靜態(tài)網(wǎng)站
什么是靜態(tài)網(wǎng)站生成器
簡單來說,靜態(tài)網(wǎng)站生成器就是一個由輕量的標(biāo)記語言以及模版語言和元數(shù)據(jù)以及CSS預(yù)處理器加上可以編譯成JavaScript的語言構(gòu)成的用來生成靜態(tài)HTML,CSS和JS文件的程序
目前網(wǎng)上有上百種生成器俭尖,不過它們都大同小異:
-
都使用一種或多種模版語言
如Liquid,Handlebars洞翩,Jade等稽犁,這是靜態(tài)網(wǎng)站生成器最關(guān)鍵的部分,它允許你為你的網(wǎng)站構(gòu)建一套主題或者說布局骚亿,在構(gòu)建的時候?qū)討B(tài)的內(nèi)容插入進(jìn)去 -
都使用一種或多種輕量化的標(biāo)記語言
如Markdown已亥,AsciiDoc,reStructuredText等,盡管大多數(shù)SSG都支持直接使用HTML来屠,但是利用標(biāo)記語言可以更快更容易的使用一些流行的文本編輯器進(jìn)行內(nèi)容編輯,比如我一般使用Typora進(jìn)行MarkDown寫作 -
都在命令行下運行
大多數(shù)靜態(tài)網(wǎng)站生成器都主要是一個命令行工具 -
都包含一個本地開發(fā)服務(wù)器
允許你在正式發(fā)布之前在本地開發(fā)和測試虑椎。通常這些工具會檢測你的文件的改變?nèi)缓笤谀憔庉嫷倪^程中就重新編譯 -
都可擴(kuò)展
大多數(shù)靜態(tài)網(wǎng)站生成器都允許你添加插件 -
都支持文件類型(file-based)的數(shù)據(jù)格式
如YAML,TOML俱笛,JSON绣檬,它們允許你結(jié)構(gòu)化任何類型的數(shù)據(jù)而不管他的展示形式,而標(biāo)記語言如Markdown等一般用來保存長期的內(nèi)容
靜態(tài)網(wǎng)站生成器的選擇
那么面對五花八門的靜態(tài)網(wǎng)站生成器我們到底該選哪個好呢?
真理往往掌握在大多數(shù)人手中,在GitHub搜索靜態(tài)網(wǎng)站生成器然后按star排序
決定就是你了,jekyll
jekyll安裝與運行
jekyll是一個專注于創(chuàng)建博客的靜態(tài)網(wǎng)站生成器,他原生支持GitHub Pages嫂粟,也就相當(dāng)于為我們提供了免費的托管服務(wù)
下面我們按照官網(wǎng)的步驟并創(chuàng)建項目(我用的Mac娇未,所以已經(jīng)裝好Ruby和RubyGems了)
gem install jekyll bundler
jekyll new my-awesome-site
cd my-awesome-site
這是創(chuàng)建好的文件目錄結(jié)構(gòu)
其中各文件的用處如下:
- _config.yml: 這是jekyll的配置文件,在里面可以更改你網(wǎng)站的信息,如標(biāo)題等
- _post: 你創(chuàng)建的新博客文件將會存放在這里
- about.md和index.md: 默認(rèn)的關(guān)于頁面和主頁,除了主頁你都可以刪掉星虹,當(dāng)然你也可以添加新頁面進(jìn)來
而其中的Gemfile文件是ruby的包管理工具用的,類似cocoapods的podfile,對Ruby我不太熟悉,但是我們可以打開看看
可以看到除了jekyll我們還安裝了minima,這是jekyll的默認(rèn)主題,要查看它的位置我們可以運行以下命令
bundle show minima
返回目錄如下
/Library/Ruby/Gems/2.0.0/gems/minima-2.1.1
打開該目錄我們可以看到minima主題的內(nèi)容
其中主要文件夾有3個,其他不用管
- _includes: 將會包含到你的模版中的內(nèi)容零抬,比如多個頁面都會用到到版權(quán)聲明
- _sass: 用來編譯生成css文件
- _layout:網(wǎng)頁的布局文件
好了,我們現(xiàn)在開始運行jekyll
jekyll serve
然后在瀏覽器打開localhost:4000
這是jekyll的默認(rèn)UI,當(dāng)然也可以將其更換為自己喜歡的主題
新建文章
要想新建一篇文章只需要把我們寫好的文章Markdown文件添加到_post文件夾就行了
文章文件命名格式為:年-月-日-標(biāo)題.后綴名
如:2017-5-20-hello-world.md
每個文件開頭都必須有如下的YAML格式的說明
---
layout: post
title: "Welcome to Jekyll!"
date: 2017-05-21 09:02:30 -0700
categories: jekyll update
---
YAML儲存的是簡單的鍵值對數(shù)據(jù)宽涌,layout告訴jekyll使用何種模版來渲染該文件平夜,title則是該文章的標(biāo)題,data為文章發(fā)布,文件頭中的日期優(yōu)先級大于文件名的,你也可以移除文件頭中的日期使用文件名中的日期卸亮,category則是你要發(fā)布的文件屬于哪個分類
好了忽妒,現(xiàn)在我們來新建一個名為2017-5-20-hello-world.md的文件
內(nèi)容如下:
---
layout: post
title: "Hello World"
date: 2017-05-21 09:02:30 -0700
categories: jekyll update
---
Hello World!
保存該文件到_post文件夾,然后我們刷新瀏覽器,就可以看到新文章了(并不需要重新運行jekyll,因為jekyll一旦檢測到文檔改變就會重新編譯)
打開Hello World就能看到該文章的詳細(xì)頁面如下
Liquid模版語言
jekyll使用了一種叫Liquid的模版語言,類似于express.js中使用的jade,關(guān)于Liquid的內(nèi)容這里只做簡單介紹
打開minima主題文件夾中_layout文件夾里的home.html
---
layout: default
---
```html
<div class="home">
<h1 class="page-heading">Posts</h1>
{{ content }}
<ul class="post-list">
{% for post in site.posts %}
<li>
{% assign date_format = site.minima.date_format | default: "%b %-d, %Y" %}
<span class="post-meta">{{ post.date | date: date_format }}</span>
<h2>
<a class="post-link" href="{{ post.url | relative_url }}">{{ post.title | escape }}</a>
</h2>
</li>
{% endfor %}
</ul>
<p class="rss-subscribe">subscribe <a href="{{ "/feed.xml" | relative_url }}">via RSS</a></p>
</div>
Liquid使用** "{% %}" 作為循環(huán)段直,條件等邏輯語句的標(biāo)記吃溅,而 "{{ }}" ** 作為變量替換的標(biāo)記,"|"則為管道操作符,用來進(jìn)行格式化操作
Liquid里面的變量來自于jekyll鸯檬,可以參考jekyll變量文檔
主題布局
下面我們看看jekyll的布局文件决侈,我們所發(fā)布的每篇文章文件頭部都需要有對布局的定義,如下面頭文件中的layout所指定的post,而這個post著來自我們的主題minima文件夾里面,打開minima文件夾,在里面的_layout文件夾里我們將會看到一個post.html的文件,這就是我們post布局,文件頭里的布局指定不能帶后綴名,比如post.html就只能指定為layout: post而不是layout: post.html
---
layout: post
title: "Hello World"
date: 2017-05-21 09:02:30 -0700
categories: jekyll update
---
Hello World!
如果你不指定layout將是這樣的結(jié)果
打開minima主題文件夾中_layout文件夾里的post.html
---
layout: default
---
<article class="post" itemscope itemtype="http://schema.org/BlogPosting">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">{{ page.title | escape }}</h1>
<p class="post-meta">
<time datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">
{% assign date_format = site.minima.date_format | default: "%b %-d, %Y" %}
{{ page.date | date: date_format }}
</time>
{% if page.author %}
? <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">{{ page.author }}</span></span>
{% endif %}</p>
</header>
<div class="post-content" itemprop="articleBody">
{{ content }}
</div>
{% if site.disqus.shortname %}
{% include disqus_comments.html %}
{% endif %}
</article>
這就是我們之前發(fā)布的文章布局post的定義文件了,該文件也有個頭信息
---
layout: default
---
可以看到,布局文件也可以有布局,我們打開default.html布局文件看看
default.html:
<!DOCTYPE html>
<html lang="{{ page.lang | default: site.lang | default: "en" }}">
{% include head.html %}
<body>
{% include header.html %}
<main class="page-content" aria-label="Content">
<div class="wrapper">
{{ content }}
</div>
</main>
{% include footer.html %}
</body>
</html>
post.html文件中的所有內(nèi)容都將被插入到下面content的位置
<div class="wrapper">
{{ content }}
</div>
注意default.html里面的include
{% include head.html %}
利用include我們可以直接將其他文件的內(nèi)容引用進(jìn)來
其他頁面
我們的網(wǎng)站當(dāng)然不可能全部由文章構(gòu)成喧务,也會有一些其他頁面,比如關(guān)于頁面等赖歌,這些頁面除了不能放在_post文件夾里面以外,它們和文章頁面沒什么不同
把它們放到j(luò)ekyll根目錄就行了,它們將會被自動解析到liquid標(biāo)簽供你使用
下面我們在根目錄創(chuàng)建一個新文件就叫count.md
---
layout: default
title: Count
---
I have {{site.posts.size}} posts
這里我們用到了jekylly的變量來顯示文章數(shù)量
刷新過后就可以在網(wǎng)頁右上角看到,點擊進(jìn)入Count頁面就能顯示文章數(shù)目
接下來
如果默認(rèn)主題符合你的需求的話其實到此你的博客網(wǎng)站就已經(jīng)構(gòu)建完成了,接下來只需要發(fā)布到你的服務(wù)器就行了,如果沒有服務(wù)器可以利用GitHub Pages進(jìn)行發(fā)布
更多主題可以到GitHub進(jìn)行搜索