實時開發框架Meteor API解讀系列Core

寫在前面的話

  1. 本篇博客主要講述如果Docs API目錄下的Core部分。
  2. 此部分比較簡單 ,如有可能請儘量閱讀官方文檔
  3. 本人英語水平有限,肯定存在翻譯錯誤的地方。如有發現,望指出
  4. 轉載請註明出處。非常感謝關注我的Meteor系列博客
  5. 本篇博客涉及到的幾個主要API是:Meteor.isClient,Meteor.isServer,Meteor.startup,Meteor.absoluteUrl,Meteor.settings,Meteor.release
  6. 本篇博客的Meteor版本是0.6.6.4,這此表明版本號是爲了避免由於版本更新帶來的 本篇博客的錯誤性描述。如有可能我會盡量會過頭來更新它。
  7. 因爲客戶端和服務端都是加載的js文件,那麼這些API的使用環境到底是客戶端還是服務端呢?根據官方的例子。我們把僅能在客戶端(也就是瀏覽器端)能使用的API 描述成Client。僅能在服務器端調用的API描述成Server,既可以在客戶端使用,又可以在服務端使用的API描述成Anywhere。

Meteor.isClient,Metoer.isServer –Anywhere

Meteor.client是一個boolean值。作用是判斷當前上下文所處的環境是客戶端和服務端。如果想知道詳細,那麼就需要先簡單的瞭解下Meteor的工程目錄結構。(可能我會專門用一篇博客來描述它) 
通過

 meteor create API-002-Core

生成的應用目錄中,通常包括如下幾個部分:(#表示註釋)

.meteor/ 
# .meteor文件夾,經meteor編譯後的工程文件將生成在這個文件下的某個子目錄中,如果在類Unix系統下,如ubuntu 它可能是隱藏的。這個文件夾通常還放有屬於當前應用的數據庫文件。當然前提是沒有修改默認的數據庫鏈接,還有諸如 包管理配置之類的文件等等。這裏不做詳細說明,畢竟和本篇博客暫時無關

API-002-Core.css 
#css文件 這個文件裏面是空白的。只是做個樣例而已。

API-002-Core.html
#如果你在創建應用後直接運行meteor,那麼它就是顯示的內容。

API-002-Core.js
#這個就是實際上的邏輯代碼了。 不去暫時不去分析其內容。

現在說明一下Meteor的工作目錄是這樣劃分的,但是在說明之前 做個約定,以免後面造成混淆或錯誤。 
我們通過 meteor create API-002-Core創建meteor工程後,那麼就會有一個API-002-Core的文件夾。從現在起我把這個文件夾的直接子目錄,稱之爲應用根目錄,或者簡稱爲更目錄,用符號/來表示。 
那麼以上面的文件爲例,他們的文件位置就是 /.meteor/,/API-002-Core.css /等。如果我在API-002-Core文件夾下創建了一個hello的文件夾。那麼該文件用/hello/表示.約定就這些了。

在meteor工程目錄中有幾個目錄是特殊的。它會通過文件夾的名稱區別作用,默認創建應有後這些文件夾是不存在的,需要自己創建。具體如下:

/client/

該文件夾下的所有文件都會在瀏覽器訪問應用時加載。換就話說即使客戶端加載。它是自動加載的,無法進行控制。至於具體的加載順序我會在另外一篇博文中講述。

/server/

這個文件夾下的所有文件都會在meteor啓動時在服務端加載。加載順序另外一篇博文中進行描述。也就是V8虛擬機來加載,類似於一般的node.js文件,它是屬於後臺的。

/public/

這個文件裏面的所有文件只能在瀏覽器端進行使用,通過文件夾的名稱也能夠看出來。區別於/client/,這裏面的文件不會自動加載。裏面主要存放的就是一些資源文件,如圖片,css,js插件如jquery之類的等。這些文件需要手動的寫引用,來使瀏覽器進行加載。如寫在

<script src=".."></script>
<style href="..."></style>

這裏又有一點需要注意,在標籤中引用文件時以“/public/“`爲相對根目錄引用就可以。舉例說明。如果存在這樣的css文件 
/public/a.css或者/public/css/b.css 
那麼他們在引用上這樣寫即可,不需要帶上public路徑:

<style href="a.css"></style>
<style href="css/b.css"></style>

/private/

這個文件夾是一個資源文件。用在服務端。一般存放一些配置文件。如json格式的配置文件等。區別於/server/ 這裏面的文件不會自動加載。更不會執行。哪怕裏面存放了一個js文件,js文件裏面聲明瞭全局變量。而不會執行。因爲V8引擎根本就沒有加載它。這個文件夾下的文件僅是看作二進制的文件而已。你可以讀寫它。

/packages/

這個文件夾下主要放的是第三方擴展模塊。如router之類的擴展。這個裏面的文件加載的位置(server或着client)主要看模塊內部的定義。這裏不做討論。它配合/.meteor/packages文件使用。

本篇博客內,把瀏覽器 稱爲Client 服務器稱爲Server

以上這五種文件夾(嚴格來說是6個,還包括一個.meteor文件夾)是meteor工程裏面比較特殊的幾個。你可以根據實際情況來創建它們。他們的基本介紹就介紹到這裏。

除這6個文件夾(包括其子目錄)以外的其他所有文件及其他文件夾下的文件都將同時在client和server端進行加載。當然裏面有個特例就是.html和.css兩種文件,他們僅會放在Client端。

其實還有個文件夾,但是我沒有測試(官方也沒有說明,估計就不是特殊的了。),只是我在實際開發工程中發現的。不知道是不是特殊的或者跟裏面的文件的後綴有關。 那就是```/log/```文件,因爲應用中需要輸出日子信息,所以我把所有的.log文件輸出到這個文件夾後不會導致應用重啓。可能和不是```.js```的文件後綴有關。這是個人經驗,僅供參考。

回到主題。

在一開始meteor那自動創建的xxx.js,xxx.css,xxx,html三個文件(這三個文件沒有在上面提到的6種特殊文件夾裏)。根據上面說到的原則,那麼xxx.csss,xxx.html 將加載在Client端,xxx.js將同時加載到Client和Server.

關於驗證上面的結論,可以在啓動一次應用後(如果沒有啓動過應用會找不到),去文件夾```/.meteor/local/build/programs/```下面的```client``````server```
文件下具體尋找一下。

那麼因爲有這種同時加載js文件到Client和Server的規則。那麼如同判斷當前的運行時環境到底是Client還是Server呢?答案就是這小節的標題了。我們通過 
變量Meteor.isClient或者Meteor.isServer來判斷了。

看到自動生成的js文件內容:

if (Meteor.isClient) {
    Template.hello.greeting = function () {
        return "Welcome to API-002-Core.";
    };

    Template.hello.events({
    'click input' : function () {
         // template data, if any, is available in 'this'
        if (typeof console !== 'undefined')
            console.log("You pressed the button");
    }
    });
}

if (Meteor.isServer) {
    Meteor.startup(function () {
        // code to run on server at startup
    });
}

現在看兩個if部分。那麼現在應該很容易理解了。如果這js文件在Client端執行。那麼if(Meteor.isServer)裏面的語句就不會執行了,反之,如果js文件是在Server端進行加載實行,那麼if(Meteor.isClient)裏面的就不會執行了。 
所以最後總結:

Meteor.isServer,Meteor.isClient它的主要作用是判斷當前的執行環境是Client還是Server
通常只使用在那些 同時被ClientServer加載的js文件中。因爲上文提到過,Meteorjs加載的位置通過文件夾(/server/,/client/)給區分開了,所以在/server/和/client/中我們已經明確的知道了這些文件運行時的環境(瀏覽器或是服務器),就用不上這兩個布爾值了。

Meteor.startup — Anywhere

這個API使用起來也比價簡單。它一般使用在Server端。 它介紹一個參數,參數類型是Funtion。 
如同上面代碼:

Meteor.startup(function () {
        // code to run on server at startup
    });

根據function的名字也容易想到它的意思。那就是在啓動後來執行這個函數。這裏的啓動後指的是服務器進程完全啓動後。 它一般用來進行初始化之類的操作。比如說,如果有你的數據庫是空的,那麼你希望在第一次啓動時添加一些數據進去,那麼就需要用到它了。

其實我不太想講 這個函數在Client端的使用。因爲可以有很多種方法來代替它。 
在Client端的它的執行時間是在整個頁面加載完全後來執行。具體的順序看官方解釋。我不太會翻譯這個,也沒想到解釋好這個(因爲我從來沒在Client端使用過這個,有其他API也可以實現這個)

startup callbacks from packages will be called first, followed by templates from your .html files, followed by your application code.

Meteor.settings —Anywhere

這個API是一個json格式的object,它的作用一般是在啓動時想給Meteor應用傳遞一些參數。使得在代碼裏可以獲取這些參數或者值。 來看一個例子。

想要後去傳遞的參數,那麼第一部就得清楚知道怎麼設置這些參數。

首先我們新建一個文件 test.ini 內容是:(這個文件後綴任意,但得保證它是個文本文檔,裏面的內容是一個正確的json格式)

{
    "a":1,
    "b":2
}
這個test.ini 文件隨便放在哪裏。當然既然相當於一個外部配置文件,我們最好還是放在工程的根目錄下如:
/test.ini
windows下或者你可以放在c:\\test.ini
linux下你可以放在 /home/user/test.ini #注意這裏的/不是代表應用根目錄。代表磁盤根目錄。使用windows的可以忽略這種設置。使用linux的自然明白。

好,上面就是配置我們希望傳遞給metoer的一些信息。

那麼啓動meteor時後用如下命令啓動 就把配置傳給Meteor.settings了。

meteor run --settings test.ini #這個是對應放在應用根目錄下的test.ini
如果你寫的是絕對路徑應該就是:
meteor run --settings c:\\test.ini #windows
或者
meteor run --settings /home/user/test.ini #linux

當然現在還不使用這個命令。因爲代碼還沒有完成。如果已經啓動了,請關閉應用。 
現在我們來在代碼裏使用Meteor.settings. 
先把自動創建的那三個文件(.js,.css,.html)刪除。新建以下幾個文件夾

/client/
/server/

這樣做主要是省得每次寫代碼都得判斷執行環境。然後在文件夾下分別新建兩個這樣的文件

client.js,server.js
使得目錄是個這樣的情況
/client/client.js
/server/server.js

先看server.js

Meteor.startup(function(){
   console.log(Meteor.settings);
});

很簡單的一個代碼。保存。 
現在啓動

meteor run --settings test.ini 

啓動後就能看到打印信息了。至於如何使用–setting 或者用在什麼地方就不是本篇討論的問題了,當然其實也沒什麼可值得討論的。 
還有一點提一下,就是如果在配置文件裏面有個字段是public。如:

{
    "a":1,
    "b":2,
    "public":"任意" 
}

那麼這個Meteor.settings也會存在與Client。否則就只是在Server端存在。這裏不做測試了。如果有興趣可以在client.js裏面寫上測試的代碼。

這個API其實也很容易。我寫得有點羅嗦了。

Meteor.release —Anywhere

這個API更簡單。就是獲取當前的Meteor系統版本號。Client和Server都可以得到。

Meteor.absoluteUrl([path], [options]) —Anywhere

這是也是個非常簡單的東西。你僅僅只需要把它看成一個保存全局變量的東西就可以了。 
這個東西不知道我能不能表達的清楚。

Server端

如果在調用它,如:

Meteor.absoluteUrl()

那麼它將返回一個字符串。默認情況下是:

console.log(Meteor.absoluteUrl());
輸出:
http://localhost:3000/

它裏面的一個參數是一個相對路徑。然會返回這個相對路徑的在url中的絕對路徑:

console.log(Meteor.absoluteUrl(“hello”));
輸出:http://localhost:3000/hello
console.log(Meteor.absoluteUrl(“hello/a.html”));
輸出:http://localhost:3000/hello/a.html

你可以在代碼裏設置它的值,當然可以在啓動時環境變量裏面設置它的值。代碼裏面設置:

console.log(Meteor.absoluteUrl()); #輸出:http://localhost:3000
Meteor.absoluteUrl.defaultOptions.rootUrl = "http://mydomain.com";//重新設置它的值
console.log( Meteor.absoluteUrl()); #輸出: http://mydomain.com
console.log( Meteor.absoluteUrl("hello")); #輸出: http://mydomain.com/hello
在這次設置後它再次在服務端調用那麼就是設置後的值了。所以說可以看成一個保存全局變量的東西

在環境變量裏面設置:(因爲官方文檔裏面提到了這個我才說i一下,其實可以跳過不看) 
Windows 
打開環境變量設置(如果說你不知道window環境變量在哪裏,就可以跳過這部分。) 
添加一個key/value

ROOT_URL=http://mydomain.com

和上面代碼設置是一個效果。不過首次打印輸出就不是默認的http://localhost:3000而是http://mydomain.com

Linux 
同樣可以把ROOT_URL=http://mydomain.com設置到環境變量中。 
當然這裏我們通過導入臨時環境變量來測試

export ROOT_URL=http://mydomain.com
meteor

結果和window下設置環境變量一樣 .首次打印輸出就不是默認的http://localhost:3000而是http://mydomain.com 
下面是服務端server.js的測試代碼:

Meteor.startup(function(){
   console.log(Meteor.absoluteUrl());
   Meteor.absoluteUrl.defaultOptions.rootUrl = "http://mydomain.com";
   console.log( Meteor.absoluteUrl());
   console.log( Meteor.absoluteUrl("hello"));
});

Client

在client端(你可以打開localhost:3000,然後在console控制檯來輸出查看)也可以使用

console.log(Meteor.absoluteUrl());
Meteor.absoluteUrl.defaultOptions.rootUrl = "http://mydomain.com";
console.log(Meteor.absoluteUrl());

這裏有兩點提示

1.Server通過的Meteor.absoluteUrl.defaultOptions.rootUrl這種方法設置的rooturl不會影響到客戶端瀏覽器Meteor.absoluteUrl()的值。也就是當前是在什麼域名上跑的那麼Meteor.absoluteUrl()返回的就是這個域名,但是通過環境變量設置的url會影響到客戶端瀏覽器Meteor.absoluteUrl()的值。

2.因爲在每個瀏覽器控制檯上都可以使用apiMeteor.absoluteUrl.defaultOptions.rootUrl = "http://mydomain.com";所以Meteor.absoluteUrl()的改變後的值只會影響當前這個瀏覽器的這個頁面。不會影響到其他客戶端的Meteor.absoluteUrl()的值。舉個例子:
如果你在chrome上打開了```http://localhost:3000```,然後在控制檯重新設置了rooturl的值。那麼在chrome rooturl的值就變了。
如果這時你在另一個瀏覽器如Firefox上也打開了```http://localhost:3000```Firefox上的Meteor.absoluteUrl()的返回值是不受Chrome上修改影響的。
不會影響到。(但是是不是通過環境變量)

不知道我是否說清楚了這個意思。也就這樣吧。自己可以寫代碼嘗試兩次就明白了。

以上。完結於 2014-01-18 23:23 
轉載請註明。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章