实时开发框架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 
转载请注明。

实时开发框架Meteor API解读系列<二>Core

上一篇:PhotoShop通过锐化实现高质量的图像小技巧


下一篇:苹果 macOS Monterey Beta 5 已部分支持通用控制,不过需手动开启