Meteor 是一個網絡應用平台。不論是初學者還是專業人士,Meteor 都非常適合。它易於上手,並提供了龐大的庫生態系統,您可以利用這些庫來開發應用。

Meteor 是一個網絡應用平台。

現代網絡應用的編寫可能非常複雜,對於初學者來說尤其如此。

Meteor 是一個適合初學者和專家的工具,它使入門變得容易,並提供了龐大的庫生態系統供您使用。

JavaScript

Meteor 是最早使用 JavaScript 作為前端和後端語言的網絡應用之一。

MySQL 是一款數據庫,它存儲 JSON 對象並使用 JavaScript 作為查詢語言,因此與 JavaScript 必不可少的。

Meteor 還在前端搭配了使用 JavaScript 編寫的 Minimongo 數據庫。

即時通信

Meteor 以其實時功能而聞名,但是什麼是實時通信?假設您想要創建一個聊天應用程序。Meteor 為此提供了完美的功能。

想創建一個內部通信應用程序?也非常完美。專案管理應用程序?基本上,任何應用程式都可以通過用戶的操作或第三方元素(如 API 更改顯示的訊息)更新訊息,並且 Meteor 提供的解決方案相對來說更加簡單。

給人一種快速感

一個名為 延遲補償(Latency Compensation) 的功能使界面具有迅速的感覺,即使它需要與遠程服務器通信。最重要的是,它在 Meteor 中是免費使用的,也就是說,它在 Meteor 中預先完成了,您無需做任何特殊處理就可以使用它。

開源

當然,Meteor 是完全開源的。

易於使用

Meteor 看起來很簡單,因為它確實是簡單的。

複雜的事務通常會產生奇怪的 bug 或困難的問題。而 Meteor 提供了一個乾淨、美觀的 API和功能,供我們在此基礎上進一步開發。

優秀的套件系統

Meteor 最酷的地方在於,它可以驅動前端和後端,並且與數據庫緊密集成,這意味著前端和後端代碼都可以放在一個包中,並在兩邊無縫運行。這就是為什麼我們可以通過一行代碼添加完整的用戶管理功能。

Meteor 如何改善您的生活

Meteor 通過提供客戶端框架和服務器端框架的全棧來為您提供完整的平台。不僅如此,Meteor 甚至為它們之間提供了通信渠道。該通信渠道稱為 DDP,我們稍後會講到它。

您不再需要將不同的框架、語言、工具和代碼庫組合在一起。這對於獨立開發者、小型初創企業甚至不想花費時間和資源使事情變得更加困難的大型組織來說非常重要。

在哪種情況下 Meteor 可能不是最佳選擇

靜態內容網站有更好的平台可供選擇。如果您只需要輸出一些沒有太多交互性的 HTML,請使用靜態網站生成器。

截至目前,Meteor 不支持 SQL 數據庫,在許多情況下這是好事,但在其他情況下可能需要 SQL 數據庫。當然,您可以自己編寫使用 SQL 數據的過程。

7 個 Meteor 原則

Meteor 是基於以下七個原則之上構建的。它們在專案文檔中列出,它們是基本原則,所以我們將在這裡將它們列出。

原則在日常生活中始終很重要。

數據傳輸

Meteor 不會將 HTML 通過網絡傳輸,服務器只會傳送數據,然後客戶端將其呈現。

一個語言

Meteor 允許您在 JavaScript 中編寫客戶端和服務器端的應用程序。

數據庫無處不在

您可以使用相同的方法從客戶端或服務器端訪問數據庫。

延遲補償

在客戶端,Meteor 預取數據並模擬模型,使其看起來像服務器方法調用立即返回。

全棧反應

在 Meteor 中,實時是默認情況。從數據庫到模板的所有層都會在需要時自動更新自身。

擁抱生態系統

Meteor 是開源的,並與現有的開源工具和框架集成。

簡潔等於高效

使事情看起來簡單的最好方法就是讓它真正變得簡單。Meteor 的主要功能提供了乾淨、經典美觀的 API。

安裝過程

在 MacOS 和 Linux 上,安裝 Meteor 就像在操作系統終端中鍵入以下命令一樣簡單:

curl https://install.meteor.com/ | sh

安裝 Meteor

就是這樣!

Windows 上有自己的官方安裝程序,所以請在官方網站上查找相關項目。

初步使用 Meteor

我們來創建第一個 Meteor 應用。

打開操作系統終端,進入您將存放該專案的目錄,然後輸入以下命令:

meteor create hello-world

創建 Meteor 應用

Meteor 會在名為 hello-world 的子文件夾中為您創建一個新的應用程序。

現在進入該目錄,然後輸入以下命令:

meteor

這將啟動 Meteor Web 服務器,您可以通過將瀏覽器指向 http://localhost:3000 來訪問您的第一個 Meteor 應用。

Hello Meteor

是不是很簡單?

代碼導覽

讓我們通過詳細解讀應用程序代碼來了解它的運作方式。

如果現在對一些概念不太清楚,不用擔心,稍後將引入並解釋許多概念。

幾年前,這個 Meteor 示例應用只包含一個 JavaScript 文件,既包含了客戶端代碼,也包含了服務器端代碼,使用 Meteor.isClientMeteor.isServer 來檢查應用程序在客戶端上運行還是服務器端上運行。

這個示例應用程序摒棄了這種方法,現在有一個 server/main.js 文件,和 client/ 文件夾下的其他文件。

client/main.html

如果打開 client/main.html 文件,可以看到應用的源代碼:

<head>
 <title>hello-world</title>
</head>

<body>
 <h1>Welcome to Meteor!</h1>

 {{> hello}}
 {{> info}}
</body>

<template name="hello">
 <button>Click Me</button>
 <p>You've pressed the button {{counter}} times.</p>
</template>

<template name="info">
 <h2>Learn Meteor!</h2>
 <ul>
 ...
 </ul>
</template>

Meteor 會識別 headbody 標籤,並將它們放到頁面內容的正確位置。這意味著通過包括 head 標籤,所有其內容都將添加到“真正”的頁面 head 標籤中。

同樣的事情也適用於 body 標籤,它們是兩個主要標籤。

其他所有內容都必須放在獨立的 template 標籤中。

您看到的特殊的 {{ }} 括號由 Spacebars 定義,它是一種類似 Handlebars 的模板語言,具有一些使其與 Meteor 配合得非常好的獨特功能。

在 hello-world 示例中,

{{> hello}}

包括了 hello 模板,以及

{{counter}}

hello 模板中的代碼會在模板上下文中查找 counter 值。

client/main.js

這是 client/main.js 文件的內容:

import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

import './main.html';

Template.hello.onCreated(function helloOnCreated() {
 // counter starts at 0
 this.counter = new ReactiveVar(0);
});

Template.hello.helpers({
 counter() {
 return Template.instance().counter.get();
 },
});

Template.hello.events({
 'click button'(event, instance) {
 // increment the counter when button is clicked
 instance.counter.set(instance.counter.get() + 1);
 },
});

此代碼設置了一個 reactive variable,一個反應變量。兩個 new ReactiveVar() 分別提供了 setter 和 getter。通過使用 setter,所有使用 get() 檢索值的函數將在其值更改時接收通知。

使用 {{counter}} 片段在 HTML 中顯示反應變量的值,它調用了我們在此處定義的 counter() 模板輔助方法。

它首先將變量初始化為零,並在單擊按鈕時對其值進行遞增。

要處理點擊事件,您可以在 hello 模板的事件處理程序中進行操作。在這種情況下,我們攔截了對 button HTML 元素的點擊事件。當這種情況發生時,我們增加了 Session.counter 的值。

server/main.js 中的 Meteor 服務器代碼中,有一個 Meteor.startup 調用,它在 Meteor 就緒時調用傳入的函數。現在它裡面沒有任何內容,但稍後我們將看到如何使用它。

Meteor CLI

安裝 Meteor 後,您將獲得名為 meteor 的 CLI(命令行實用程序)。

它非常有用,您已經使用它創建了第一個應用程序,而且我們只需了解一小部分它的功能即可開始使用 Meteor。

讓我們介紹您在開始使用 Meteor 過程中將使用到的四個最有用的命令。

meteor

在一個空目錄中輸入以下命令:

meteor

您將會收到錯誤提示,因為該目錄中沒有初始化 Meteor。

如果您在已經創建了 Meteor 專案的文件夾中執行 meteor,Meteor 將啟動並創建服務器,初始化數據庫,您將能夠打開 Meteor 網站。

meteor create

在一個目錄中輸入以下命令:

meteor create my_app_name

Meteor 將在一個名為 my_app_name 的子文件夾中初始化一個新的 Meteor 專案。

meteor add

在已經初始化的 Meteor 專案中,輸入以下命令:

meteor add package_name

Meteor 將查找 package_name 套件並將其安裝到當前專案中。

您可以在 Meteor 應用程序運行時的一個獨立終端窗口中運行此命令,而無需重新啟動 Meteor 服務器,您將無需重新啟動 Meteor 服務器即可獲得套件的功能。

meteor remove

在已經初始化的 Meteor 專案中輸入以下命令:

meteor remove package_name

將從專案中刪除帶有該名稱的套件。

同構

同構 一詞是為表述客戶端代碼和服務器端代碼使用相同的語言而提出的。這意味著任何一段代碼都可以在服務器和客戶端上運行,除非該代碼與具體的上下文相關。

在過去的十年中,網絡應用通常通過清楚區分服務器和客戶端代碼來構建。服務器代碼運行 PHP、Ruby、Python 代碼。瀏覽器只能執行 JavaScript 代碼。

使用 Meteor 近年來迅速崛起的 Node.js 以及基於 Node.js 的工具的支持,現在我們有機會使用相同的語言(JavaScript)來構建整個應用程序。

Meteor 通過在 Node.js 和瀏覽器平台之上構建了一個“超級平台”,讓你可以比以往更快、更好地構建應用程序。

同構 是指能在客戶端和服務器上以少量或不需要進行修改即可運行的 JavaScript 代碼。它是一種可以在瀏覽器和服務器上運行的代碼,可以管控在瀏覽器內部運行的代碼和在服務器內部運行的代碼。

Meteor 是一個同構框架。這很棒,因為我們可以撰寫簡潔的應用程序,它們甚至可以在客戶端和服務器端之間共用一些代碼。

典型的範例是 HTTP 請求。在瀏覽器中,您可以進行 AJAX 請求。在服務器端,可以使用特定於服務器端的代碼。

使用 Meteor,您可以在兩端使用相同的 HTTP.get() 函數,該函數由 http 包提供,與在服務器端或客戶端進行操作無關。這就像安裝 Axios 库 一樣简单。

Meteor.isServer, Meteor.isClient

Meteor 公開了兩個布爾變量,用於確定代碼是在服務器還是在客戶端上運行:

  • Meteor.isServer
  • Meteor.isClient

將它們放在 if 語句中,以僅讓某些代碼在平台的一邊運行。例如:

if (Meteor.isClient) {
 alert('Hello dear user!')
} else if (Meteor.isServer) {
 //running server-side
}

特殊目錄

在代碼中放入大量的 Meteor.isServerMeteor.isClient 檢查並不理想。

首先,代碼很快就會變得複雜,變得不易閱讀。

其次,甚至服務器端代碼也會發送給客戶端。這是不好的,因為最好讓服務器端代碼保持私有,同時還可以減少不必要的代碼,這會降低加載時間。

這就是為什麼 Meteor 有兩個特殊目錄,它們自動為我們處理區別:clientserver

無論您將內容放在 client 目錄中或 server 目錄中,都不會在另一側加載。

保持這種區別的另一個好處是,放在客戶端目錄中的資源在構建過程中根本不會被考慮。

會話變量和模板輔助顯示

這裡是將 Session 變量和模板輔助方法結合使用的簡單示例,以實現在列表中選擇當前選中的評論的簡單案例。

在我們的 template.html 文件中:

<template name="main">
 {{#each comments}}
 {{> comment}}
 {{/each}}
</template>

<template name="comment">
 <div class="{{#if selected}}selected{{/if}}">
 <p>{{this.comment}}</p>
 </div>
</template>

template.js 中:

Session.set('selectedComment', null)

Template.main.helpers({
 comments: function() {
 return Comments.find()
 }
})

Template.comment.helpers({
 selected: function() {
 return Session.equals('selectedComment', this._id)
 }
})

Template.comment.events({
 'click div' : function(e, t) {
 Session.set('selectedComment', this._id)
 }
})

在這種情況下,每次單擊評論時,該評論將成為選中的評論,我們可以展示評論的完整內容,顯示該用戶提交的其他評論,或者進行一些其他炫酷的操作。

反應式編程

首先,要澄清一點:Meteor 的反應式並不是指 React,另一個非常受歡迎的 JavaScript 框架。

什麼是反應式編程?反應式編程是一種編程范型。

反應式編程並不新鮮,也不是 Meteor 的創造之物。但是,Meteor 使我們易於使用反應式編程。

事實上,您很可能已經在使用反應式編程,而不需要明確了解。

什麼是反應式編程

反應式編程允許您編寫自動刷新和重新計算功能和值的代碼,當某些您所依賴的事物發生更改時。

例如,數據庫中的數據發生變化?您需要將其重新顯示在客戶端中。

該變量計算發生變化,因為您添加了一個評論?依賴它的所有內容都需要重新計算。

當具有變化的反應性源被更改時,依賴於這些變化的變量將被失效,並根據新的數據進行重新計算。

反應性來源

Meteor 有一些被視為反應性的東西,它們驅動著整個應用程序。不是所有的東西都是反應性的,僅限於以下列出的項目:

  • 反應變量,使用 new ReactiveVar() 定義
  • 來自數據庫的數據是反應性數據源,因為通過訂閱發布可以得到游標,該游標是反應性的。對集合所做的任何更改都將觸發使用它的任何內容的重新計算。
  • 談到訂閱,當客戶端訂閱可用時,它的 .ready() 方法就會被調用,這是一個反應性數據源。
  • 會話變量是反應性的數據源。當使用 .set() 更改會話變量時,依賴於它的所有內容都將進行重新計算或重新渲染。
  • 用戶方法 Meteor.user()Meteor.userId() 是反應性數據源。
  • Meteor.status() 是客戶端方法,返回當前客戶端和服務器之間的連接狀態,它是一個反應性數據源。
  • Meteor.loggingIn() 返回 true 如果用戶正在進行登錄,它是一個反應性數據源。

反應式計算

從反應性數據源中,每當它們改變時,將觸發反應計算。這是一段代碼,一個函數,當它依賴的反應性數據源變化時,需要重新運行。

模板輔助方法就是反應計算的一個示例,每當與該模板干涉的反應數據源發生變化時,模板就會重新渲染。

定義您自己的反應計算

您可以定義自己的反應計算,並在上游發生更改時做出反應,通過使用 Tracker.autorun()

例如:

Tracker.autorun(function () {
 var currentPage = Session.get('currentPage')
 alert("The current page is " + currentPage)
})

只要调用 Session.set('currentPage', 'whatever'),而無需添加回調或其他觀察者,就可以觸發警告。

Meteor 發布與訂閱

Meteor 的一個關鍵功能由數據層提供。

由於 Meteor 管理著服務器和客戶端,我們可以用以下方式來解釋該概念:

  • 服務器創建發布
  • 客戶端訂閱該發布
  • Meteor 保持所有東西同步

服務器可以精確地確定每個客戶端將看到的內容。每個發佈都可以根據參數和用戶權限進行定制。

讓我們根據標準的 MongoDB 集合來簡單介紹一下發布與訂閱。

服務器發布

下面是服務器代碼創建了一個用於已經批準的評論發佈的示例:

// 服務器端代碼
Meteor.publish('comments', () => {
 return Comments.find({ approved: true })
})

或者,如果我們希望創建一個關於特定文章的評論發佈:

Meteor.publish('comments', (articleId) => {
 return Comments.find({ articleId: articleId })
})

當客戶端訂閱時,publish 函數被調用。

客戶端訂閱

在客戶端,代碼非常簡單。例如,讓我們訂閱所有評論:

Meteor.subscribe('comments')

讓我們改為訂閱當前文章的評論:

const articleId = 23
Meteor.subscribe('comments', articleId)

調用訂閱方法後,Meteor 將以您選擇將其發送到客戶端的數據填充客戶端的 Minimongo(在客戶端運行的 MongoDB 實例)中。通常情況下,客戶端數據庫只會得到一些記錄,只包含初始化和運行所需的最小量的數據。您當然不會複製整個服務器端的 Mongo 集合內容,但您會根據需要請求數據。

自動發布

Meteor 讓我們非常容易地開始進行項目開發,而無需擔心發佈和訂閱。它通過在每個新項目中包含了 autopublish 包來實現這一點。該包做的事情是自動為我們的每個集合創建發佈與訂閱,將所有可用的數據從服務器同步到客戶端。

當您到達所需的數據每個用戶或視圖的可控範圍時,只需移除 autopublish 包,然後手動定義您需要的內容即可。

Minimongo

在 Meteor 中,Minimongo 是您的好幫手。好吧,如果您在使用 Meteor 時覺得自己有很多好幫手,那麼我也有同感。Meteor 中的一切都是為了讓您的生活更輕鬆而提供的。

具體來說,Minimongo 是 MongoDB 的前端實現。您可能會問..為什麼我需要另一個數據庫?

MongoDB: Meteor 數據庫

截至目前為止,Meteor 只支持一種官方數據庫:MongoDB。

您可能會問為什麼。首先,讓我澄清:您實際上可以使用任何您想要的數據庫,但要充分享受到 Meteor 的種種優點,您需要使用 Mongo。當然,目前有一些社區項目正在努力添加對許多其他數據庫的支持。

MongoDB 簡介

MongoDB 是一個基於文檔的數據庫。它具有高性能、高可用性和易於擴展性的特點。它將文檔存儲在數據庫集合中。文檔是由鍵值對(JSON)組成的,並且具有動態模式。這意味著每個文檔無需擁有相同的字段集,這讓您在管理數據方面具有很大的靈活性。

Meteor 和 MongoDB

如前所述,MongoDB 文檔是一個 JSON 對象。Meteor Collections 直接與 MongoDB 集合相關聯,Meteor 內部確保當 Meteor 會跟踪的 MongoDB 集合的數據發生更改時,Meteor Collections 也是最新的。

Minimongo

簡而言之,在 Meteor 中,通常您會創建一個集合,並且該集合將在客戶端和服務器端上都可用。當您進行某種數據庫查詢或數據庫處理時,您不需要“思考”您應該在客戶端數據庫上還是在服務器端數據庫上執行該操作:在某種程度上,它們在大多數情況下兩者都是相同的。它們彼此之間可以透明地溝通。

這意味著當服務器端數據庫(MongoDB)由其他人更改或您在使用的應用程序中發生一些事情時,甚至在您在第二個瀏覽器窗口中添加了一些內容時,您當前會話中感興趣的數據庫中的所有內容都將被服務器 MongoDB 推送到在瀏覽器內運行的 Minimongo 中。

相反的情況也是如此:您將一篇帖子推送到 Posts 集合中?Minimongo 將立即更新,同時 Meteor 也會將更新推送到位於服務器端的 MongoDB 數據庫中。

這使得您的更改、頁面和交互對用戶來說感覺即時可見。

Minimongo 是 MongoDB 的客戶端克隆

Minimongo 嘗試完美模擬 MongoDB 的子集。您可以使用完全相同的 MongoDB API 插入數據、刪除數據、搜索、排序、更新,等等。

這意味著當有必要時,您也可以很容易地將代碼的某些部分從服務器端移植到客戶端,而不需要進行太多修改。

客戶端存儲設施

通過 Minimongo,您可以使用 MongoDB 查詢功能在客戶端瀏覽器中進行強大的客戶端數據存儲。

您當然可以在不需要將集合同步到服务器的情况下,在客户端创建 Minimongo 集合的实例。

此外,您可以观察数据库更改,您的界面可以对这些更改做出反应。

延遲補償

延遲補償是 Meteor 原則的一部分。在原因書中這樣描述:在客戶端,Meteor 在預取數據和模擬模型方面進行了優化,使之看起來就像服務器方法調用立即返回了。

這是什麼意思?

在典型的網絡應用程序中,當您執行某些操作時,操作會傳到服務器進行處理,然後您需要等待服務器回應,然後將更改應用於當前操作的頁面。

更現代的應用程序依靠 AJAX 提供更好的反饋時間,並避免在每次操作時刷新頁面,但仍然有許多應用程序依賴於服務器的回應才能進行任何操作。更好的應用程序引入了某種形式的延遲補償,但這是一個手動的過程。

Meteor 將延遲補償的概念融入到其哲學中並且默認 啟用,無需您進行任何特殊處理就能使用它。

例如,當您將項目添加到集合中時,同時該項目將被發送到服務器,它已經在您的頁面的集合視圖中添加上了。

這使感覺更好,因為應用程序馬上就有了響應(確實如此)。如果有錯誤,您稍後將收到通知,並有機會根據每個情況以最好的方式處理事情。

Meteor 集合

應用程序通常需要顯示某種類型的數據。這可能是消息、評論、文章、書籍、地址、圖片等等方方面