Files
meteor/docs/client/concepts.html
David Glasser 2e9755a75f More improvements to load order doc
Fixes #1839.  See also #1675.
2014-02-20 15:27:44 -08:00

954 lines
41 KiB
HTML

<template name="concepts">
<h1 id="concepts">Concepts</h1>
We've written our fair share of single-page JavaScript applications by hand.
Writing an entire application in one language (JavaScript) with one
data format (JSON) is a real joy. Meteor is everything we wanted
when writing those apps.
{{> whatismeteor }}
{{> structure }}
{{> data }}
{{> reactivity }}
{{> livehtml }}
{{> templates }}
{{> packages_concept }}
{{> namespacing }}
{{> deploying }}
{{> packages_writing }}
</template>
<template name="whatismeteor">
{{#better_markdown}}
<h2 id="whatismeteor">What is Meteor?</h2>
Meteor is two things:
* A _library of packages_: pre-written, self-contained modules that
you might need in your app.<br>
There are about a dozen core Meteor
packages that most any app will use (for example `webapp`, which
handles incoming HTTP connections, and `templating`, which lets you
make HTML templates that automatically update live as data changes).
Then there are optional packages like `email`, which lets your app
send emails, or the Meteor Accounts series (`account-password`,
`accounts-facebook`, `accounts-ui`, and others) which provide a
full-featured user account system that you can drop right into your
app. And beyond these "official" packages, there are hundreds of
community-written packages in [Atmosphere](https://atmosphere.meteor.com/),
one of which might do just what you need.
* A _command-line tool_ called `meteor`.<br>
`meteor` is a build tool analogous to `make`, `rake`, or the non-visual parts of
Visual Studio. It gathers up all of the source files and assets in your
application, carries out any necessary build steps (such as compiling
[CoffeeScript](http://coffeescript.org), minifying CSS, building
[npm](https://npmjs.org/) modules, or generating source maps), fetches the
packages used by your app, and outputs a standalone, ready-to-run application
bundle. In development mode it can do all of this interactively, so that
whenever you change a file you immediately see the changes in your browser. It's
super easy to use out of the box, but it's also extensible: you can add support
for new languages and compilers by adding build plugin packages to your app.
The key idea in the Meteor package system is that _everything should
work identically in the browser and on the server_ (wherever it makes
sense, of course: browsers can't send email and servers can't capture
mouse events). Our whole ecosystem has been built from the ground up
to support this.
{{#note}}
`meteor` cannot yet fetch packages from Atmosphere. If you are using
Atmosphere packages you should take a look at
[Meteorite](http://oortcloud.github.io/meteorite/), a tool that will
help you download and manage your Atmosphere packages.
In Meteor 1.0, the `meteor` build tool will have full support for
Atmosphere.
{{/note}}
{{/better_markdown}}
</template>
<template name="structure">
{{#better_markdown}}
<h2 id="structuringyourapp">Structuring your application</h2>
A Meteor application is a mix of JavaScript that runs inside a client web
browser, JavaScript that runs on the Meteor server inside a
[Node.js](http://nodejs.org/) container, and all the supporting HTML fragments,
CSS rules, and static assets. Meteor automates the packaging and transmission
of these different components. And, it is quite flexible about how you choose
to structure those components in your file tree.
The only server assets are JavaScript and files in the `private` subdirectory.
Meteor gathers all your JavaScript
files, excluding anything under the `client`, `public`, and `private`
subdirectories, and loads them into a Node.js
server instance inside a fiber. In Meteor, your server code runs in
a single thread per request, not in the asynchronous callback style
typical of Node. We find the linear execution model a better fit for
the typical server code in a Meteor application.
Meteor gathers any files under the `private` subdirectory and makes the contents
of these files available to server code via the [`Assets`](#assets) API. The
`private` subdirectory is the place for any files that should be accessible to
server code but not served to the client, like private data files.
There are more assets to consider on the client side. Meteor
gathers all JavaScript files in your tree, with the exception of
the `server`, `public`, and `private` subdirectories, for the
client. It minifies this bundle and serves it to each new client.
You're free to use a single JavaScript file for your entire application, or
create a nested tree of separate files, or anything in between.
Some JavaScript libraries only work when placed in the
`client/compatibility` subdirectory. Files in this directory are
executed without being wrapped in a new variable scope. This means
that each top-level `var` defines a global variable. In addition,
these files are executed before other client-side JavaScript files.
Files outside the `client`, `server` and `tests` subdirectories are loaded on
both the client and the server! That's the place for model definitions and
other functions. Meteor provides the variables [`isClient`](#meteor_isclient) and
[`isServer`](#meteor_isserver) so that your code can alter its behavior depending
on whether it's running on the client or the server. (Files in directories named
`tests` are not loaded anywhere.)
Any sensitive code that you don't want served to the client, such as code
containing passwords or authentication mechanisms, should be
kept in the `server` directory.
CSS files are gathered together as well: the client will get a bundle with all
the CSS in your tree (excluding the `server`,
`public`, and `private` subdirectories).
In development mode, JavaScript and CSS files are sent individually to make
debugging easier.
HTML files in a Meteor application are treated quite a bit differently
from a server-side framework. Meteor scans all the HTML files in your
directory for three top-level elements: `<head>`, `<body>`, and
`<template>`. The head and body sections are separately concatenated
into a single head and body, which are transmitted to the client on
initial page load.
Template sections, on the other hand, are converted into JavaScript
functions, available under the `Template` namespace. It's
a really convenient way to ship HTML templates to the client.
See the [templates](#templates) section for more.
Lastly, the Meteor server will serve any files under the `public`
directory, just like in a Rails or Django project. This is the place
for images, `favicon.ico`, `robots.txt`, and anything else.
It is best to write your application in such a way that it is
insensitive to the order in which files are loaded, for example by
using [Meteor.startup](#meteor_startup), or by moving load order
sensitive code into [packages](#usingpackages), which can explicitly control both
the load order of their contents and their load order with respect to
other packages. However sometimes load order dependencies in your
application are unavoidable. The JavaScript and CSS files in an
application are loaded according to these rules:
* Files in subdirectories are loaded before files in parent directories, so that
files in the deepest subdirectory are loaded first, and files in the root
directory are loaded last.
* Within a directory, files are loaded in alphabetical order by
filename.
* After sorting as described above, all files under directories named `lib` are
moved before everything else (preserving their order).
* Finally, all files that match `main.*` are moved after everything else
(preserving their order).
{{/better_markdown}}
</template>
<template name="data">
{{#better_markdown}}
<h2 id="dataandsecurity">Data and security</h2>
Meteor makes writing distributed client code as simple as talking to a
local database. It's a clean, simple, and secure approach that obviates
the need to implement individual RPC endpoints, manually cache data on
the client to avoid slow roundtrips to the server, and carefully
orchestrate invalidation messages to every client as data changes.
In Meteor, the client and server share the same database API. The same
exact application code &mdash; like validators and computed properties &mdash; can
often run in both places. But while code running on the server has
direct access to the database, code running on the client does *not*.
This distinction is the basis for Meteor's data security model.
{{#note}}
By default, a new Meteor app includes the `autopublish` and `insecure`
packages, which together mimic the effect of each client having full
read/write access to the server's database. These are useful
prototyping tools, but typically not appropriate for production
applications. When you're ready, just remove the packages.
{{/note}}
Every Meteor client includes an in-memory database cache. To manage the
client cache, the server *publishes* sets of JSON documents, and the
client *subscribes* to those sets. As documents in a set change, the
server patches each client's cache.
Today most Meteor apps use MongoDB as their database because it is the
best supported, though support for other databases is coming in the
future. The
[`Meteor.Collection`](http://docs.meteor.com/#meteor_collection) class
is used to declare Mongo collections and to manipulate them. Thanks to
`minimongo`, Meteor's client-side Mongo emulator, `Meteor.Collection`
can be used from both client and server code.
// declare collections
// this code should be included in both the client and the server
Rooms = new Meteor.Collection("rooms");
Messages = new Meteor.Collection("messages");
Parties = new Meteor.Collection("parties");
// server: populate collections with some initial documents
Rooms.insert({name: "Conference Room A"});
var myRooms = Rooms.find({}).fetch();
Messages.insert({text: "Hello world", room: myRooms[0]._id});
Parties.insert({name: "Super Bowl Party"});
Each document set is defined by a publish function on the server. The
publish function runs each time a new client subscribes to a document
set. The data in a document set can come from anywhere, but the common
case is to publish a database query.
// server: publish all room documents
Meteor.publish("all-rooms", function () {
return Rooms.find(); // everything
});
// server: publish all messages for a given room
Meteor.publish("messages", function (roomId) {
check(roomId, String);
return Messages.find({room: roomId});
});
// server: publish the set of parties the logged-in user can see.
Meteor.publish("parties", function () {
return Parties.find({$or: [{"public": true},
{invited: this.userId},
{owner: this.userId}]});
});
Publish functions can provide different results to each client. In the
last example, a logged in user can only see `Party` documents that
are public, that the user owns, or that the user has been invited to.
Once subscribed, the client uses its cache as a fast local database,
dramatically simplifying client code. Reads never require a costly
round trip to the server. And they're limited to the contents of the
cache: a query for every document in a collection on a client will only
return documents the server is publishing to that client.
// client: start a parties subscription
Meteor.subscribe("parties");
// client: return array of Parties this client can read
return Parties.find().fetch(); // synchronous!
Sophisticated clients can turn subscriptions on and off to control how
much data is kept in the cache and manage network traffic. When a
subscription is turned off, all its documents are removed from the cache
unless the same document is also provided by another active
subscription.
When the client *changes* one or more documents, it sends a message to
the server requesting the change. The server checks the proposed change
against a set of allow/deny rules you write as JavaScript functions.
The server only accepts the change if all the rules pass.
// server: don't allow client to insert a party
Parties.allow({
insert: function (userId, party) {
return false;
}
});
// client: this will fail
var party = { ... };
Parties.insert(party);
If the server accepts the change, it applies the change to the database
and automatically propagates the change to other clients subscribed to
the affected documents. If not, the update fails, the server's database
remains untouched, and no other client sees the update.
Meteor has a cute trick, though. When a client issues a write to the
server, it also updates its local cache immediately, without waiting for
the server's response. This means the screen will redraw right away.
If the server accepted the update &mdash; what ought to happen most of the
time in a properly behaving client &mdash; then the client got a jump on the
change and didn't have to wait for the round trip to update its own
screen. If the server rejects the change, Meteor patches up the
client's cache with the server's result.
Putting it all together, these techniques accomplish latency
compensation. Clients hold a fresh copy of the data they need, and
never need to wait for a roundtrip to the server. And when clients
modify data, those modifications can run locally without waiting for the
confirmation from the server, while still giving the server final say
over the requested change.
{{#note}}
The current release of Meteor supports MongoDB, the popular document
database, and the examples in this section use the
[MongoDB API](http://www.mongodb.org/display/DOCS/Manual). Future
releases will include support for other databases.
{{/note}}
<h3 id="dataandsecurity-authentication">Authentication and user accounts</h3>
Meteor includes [Meteor Accounts](#accounts_api), a state-of-the-art
authentication system. It features secure password login using the
[Secure Remote Password
protocol](http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol),
and integration with external services including Facebook, GitHub,
Google, Meetup, Twitter, and Weibo. Meteor Accounts defines a
[`Meteor.users`](#meteor_users) collection where developers can store
application-specific user data.
Meteor also includes pre-built forms for common tasks like login, signup,
password change, and password reset emails. You can add [Accounts
UI](#accountsui) to your app with just one line of code. The `accounts-ui` package even provides a configuration wizard that walks you through the steps to
set up the external login services you're using in your app.
<h3 id="dataandsecurity-validation">Input validation</h3>
Meteor allows your methods and publish functions to take arguments of any
[JSON](http://json.org/) type. (In fact, Meteor's wire protocol supports
[EJSON](#ejson), an extension of JSON which also supports other common types
like dates and binary buffers.) JavaScript's dynamic typing means you don't need
to declare precise types of every variable in your app, but it's usually helpful
to ensure that the arguments that clients are passing to your methods and
publish functions are of the type that you expect.
Meteor provides a [lightweight library](#match) for checking that arguments and
other values are the type you expect them to be. Simply start your functions
with statements like `check(username, String)` or
`check(office, {building: String, room: Number})`. The `check` call will
throw an error if its argument is of an unexpected type.
Meteor also provides an easy way to make sure that all of your methods
and publish functions validate all of their arguments. Just run
<code>meteor add [audit-argument-checks](#auditargumentchecks)</code> and any
method or publish function which skips `check`ing any of its arguments will fail
with an exception.
{{/better_markdown}}
</template>
<template name="reactivity">
{{#better_markdown}}
<h2 id="reactivity">Reactivity</h2>
Meteor embraces the concept of [reactive
programming](http://en.wikipedia.org/wiki/Reactive_programming). This means that
you can write your code in a simple imperative style, and the result will be
automatically recalculated whenever data changes that your code depends on.
Deps.autorun(function () {
Meteor.subscribe("messages", Session.get("currentRoomId"));
});
This example (taken from a chat room client) sets up a data
subscription based on the session variable `currentRoomId`.
If the value of `Session.get("currentRoomId")` changes for any reason, the
function will be automatically re-run, setting up a new subscription that
replaces the old one.
This automatic recomputation is achieved by a cooperation between
`Session` and `Deps.autorun`. `Deps.autorun` performs an arbitrary "reactive
computation" inside of which data dependencies are tracked, and it
will re-run its function argument as necessary. Data providers like
`Session`, on the other hand, make note of the computation they are
called from and what data was requested, and they are prepared to send
an invalidation signal to the computation when the data changes.
This simple pattern (reactive computation + reactive data source) has wide
applicability. Above, the programmer is saved from writing
unsubscribe/resubscribe calls and making sure they are called at the
right time. In general, Meteor can eliminate whole classes of data
propagation code which would otherwise clog up your application with
error-prone logic.
These Meteor functions run your code as a reactive computation:
* [Templates](#templates)
* [`Meteor.render`](#meteor_render) and [`Meteor.renderList`](#meteor_renderlist)
* [`Deps.autorun`](#deps_autorun)
And the reactive data sources that can trigger changes are:
* [`Session`](#session) variables
* Database queries on [Collections](#find)
* [`Meteor.status`](#meteor_status)
* The `ready()` method on a [subscription handle](#meteor_subscribe)
* [`Meteor.user`](#meteor_user)
* [`Meteor.userId`](#meteor_userid)
* [`Meteor.loggingIn`](#meteor_loggingin)
In addition, the following functions which return an object with a
`stop` method, if called from a reactive computation, are stopped when
the computation is rerun or stopped:
* [`Deps.autorun`](#deps_autorun) (nested)
* [`Meteor.subscribe`](#meteor_subscribe)
* [`observe()`](#observe) and [`observeChanges()`](#observe_changes) on cursors
Meteor's
[implementation](https://github.com/meteor/meteor/blob/master/packages/deps/deps.js)
is a package called [`Deps`](#deps) that is fairly short and straightforward.
You can use it yourself to implement new reactive data sources.
{{/better_markdown}}
</template>
<template name="livehtml">
{{#better_markdown}}
<h2 id="livehtml">Live HTML</h2>
HTML templating is central to web applications. With Meteor's live
page update technology, you can render your HTML _reactively_, meaning
that it will update automatically to track changes in the data used to
generate it.
This optional feature works with any HTML templating library, or even
with HTML you generate manually from JavaScript. Here's an example:
var fragment = Meteor.render(
function () {
var name = Session.get("name") || "Anonymous";
return "<div>Hello, " + name + "</div>";
});
document.body.appendChild(fragment);
Session.set("name", "Bob"); // page updates automatically!
[`Meteor.render`](#meteor_render) takes a rendering function, that is, a
function that returns some HTML as a string. It returns an auto-updating
`DocumentFragment`. When there is a change to data used by the rendering
function, it is re-run. The DOM nodes in the `DocumentFragment` then
update themselves in-place, no matter where they were inserted on the
page. It's completely automatic. [`Meteor.render`](#meteor_render) uses
a [reactive computation](#reactivity) to discover what data is used by the
rendering function.
Most of the time, though, you won't call these functions directly
&mdash; you'll just use your favorite templating package, such as
Handlebars or Jade. The `render` and `renderList` functions are intended
for people that are implementing new templating systems.
Meteor normally batches up any needed updates and executes them only
when your code isn't running. That way, you can be sure that the DOM
won't change out from underneath you. Sometimes you want the opposite
behavior. For example, if you've just inserted a record in the
database, you might want to force the DOM to update so you can find
the new elements using a library like jQuery. In that case, call
[`Deps.flush`](#deps_flush) to bring the DOM up to date
immediately.
When live-updating DOM elements are taken off the screen, they are automatically
cleaned up &mdash; their callbacks are torn down, any associated database
queries are stopped, and they stop updating. For this reason, you never have to
worry about the [zombie
templates](http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/)
that plague hand-written update logic. To protect your elements from cleanup,
just make sure that they are on-screen before your code returns to the event loop,
or before any call you make to [`Deps.flush`](#deps_flush).
Another thorny problem in hand-written applications is element
preservation. Suppose the user is typing text into an `<input>`
element, and then the area of the page that includes that element is
redrawn. The user could be in for a bumpy ride, as the focus, the
cursor position, the partially entered text, and the accented
character input state will be lost when the `<input>` is recreated.
This is another problem that Meteor solves for you. You can specify
elements to preserve when templates are re-rendered with the
[`preserve`](#template_preserve) directive on the template. Meteor will
preserve these elements even when their enclosing template is
rerendered, but will still update their children and copy over any
attribute changes.
{{/better_markdown}}
</template>
<template name="templates">
{{#better_markdown}}
<h2 id="templates">Templates</h2>
Meteor makes it easy to use your favorite HTML templating language,
such as Handlebars or Jade, along with Meteor's live page update
technology. Just write your template as you normally would, and Meteor
will take care of making it update in realtime.
To use this feature, create a file in your project with the `.html`
extension. In the file, make a `<template>` tag and give it a
`name` attribute. Put the template contents inside the tag. Meteor
will precompile the template, ship it down to the client, and make it
available as a function on the global `Template` object.
{{#note}}
Today, the only templating system that has been packaged for Meteor is
Handlebars. Let us know what templating systems you'd like to use with
Meteor. Meanwhile, see the [Handlebars
documentation](http://www.handlebarsjs.com/) and [Meteor Handlebars
extensions](https://github.com/meteor/meteor/wiki/Handlebars).
{{/note}}
A template with a `name` of `hello` is rendered by calling the
function `Template.hello`, passing any data for the template:
<!-- in myapp.html -->
<template name="hello">
<div class="greeting">Hello there, {{dstache}}first}} {{dstache}}last}}!</div>
</{{! }}template>
// in the JavaScript console
> Template.hello({first: "Alyssa", last: "Hacker"});
=> "<div class="greeting">Hello there, Alyssa Hacker!</div>"
This returns a string. To use the template along with the [`Live
HTML`](#livehtml) system, and get DOM elements that update
automatically in place, use [`Meteor.render`](#meteor_render):
Meteor.render(function () {
return Template.hello({first: "Alyssa", last: "Hacker"});
})
=> automatically updating DOM elements
The easiest way to get data into templates is by defining helper
functions in JavaScript. Just add the helper functions directly on the
`Template.[template name]` object. For example, in this template:
<template name="players">
{{dstache}}#each topScorers}}
<div>{{dstache}}name}}</div>
{{dstache}}/each}}
</{{! }}template>
instead of passing in `topScorers` as data when we call the
template function, we could define a function on `Template.players`:
Template.players.topScorers = function () {
return Users.find({score: {$gt: 100}}, {sort: {score: -1}});
};
In this case, the data is coming from a database query. When the
database cursor is passed to `#each`, it will wire up all of the
machinery to efficiently add and move DOM nodes as new results enter
the query.
Helpers can take arguments, and they receive the current template context data
in `this`. Note that some block helpers change the current context (notably
`each` and `with`):
// in a JavaScript file
Template.players.leagueIs = function (league) {
return this.league === league;
};
<!-- in a HTML file -->
<template name="players">
{{dstache}}#each topScorers}}
{{dstache}}#if leagueIs "junior"}}
<div>Junior: {{dstache}}name}}</div>
{{dstache}}/if}}
{{dstache}}#if leagueIs "senior"}}
<div>Senior: {{dstache}}name}}</div>
{{dstache}}/if}}
{{dstache}}/each}}
</{{! }}template>
{{#note}}
Handlebars note: `{{dstache}}#if leagueIs "junior"}}` is
allowed because of a Meteor extension that allows nesting a helper
in a block helper. (Both `if` and `leagueIs` are
technically helpers, and stock Handlebars would not invoke
`leagueIs` here.)
{{/note}}
Helpers can also be used to pass in constant data.
// Works fine with {{dstache}}#each sections}}
Template.report.sections = ["Situation", "Complication", "Resolution"];
Finally, you can use an `events` declaration on a template function to set up a
table of event handlers. The format is documented at [Event
Maps](#eventmaps). The `this` argument to the event handler will be
the data context of the element that triggered the event.
<!-- myapp.html -->
<template name="scores">
{{dstache}}#each player}}
{{dstache}}> playerScore}}
{{dstache}}/each}}
</{{! }}template>
<template name="playerScore">
<div>{{dstache}}name}}: {{dstache}}score}}
<span class="givePoints">Give points</span>
</div>
</{{! }}template>
<!-- myapp.js -->
Template.playerScore.events({
'click .givePoints': function () {
Users.update(this._id, {$inc: {score: 2}});
}
});
Putting it all together, here's an example of how you can inject
arbitrary data into your templates, and have them update automatically
whenever that data changes. See [Live HTML](#livehtml) for further
discussion.
<!-- in myapp.html -->
<template name="forecast">
<div>It'll be {{dstache}}prediction}} tonight</div>
</{{! }}template>
<!-- in myapp.js -->
// JavaScript: reactive helper function
Template.forecast.prediction = function () {
return Session.get("weather");
};
<!-- in the console -->
> Session.set("weather", "cloudy");
> document.body.appendChild(Meteor.render(Template.forecast));
In DOM: <div>It'll be cloudy tonight</div>
> Session.set("weather", "cool and dry");
In DOM: <div>It'll be cool and dry tonight</div>
{{/better_markdown}}
</template>
<template name="packages_concept">
{{#better_markdown}}
<h2 id="usingpackages">Using packages</h2>
All of the functionality you've read about so far is implemented as
standard Meteor packages. This is possible thanks to Meteor's
unusually powerful package and build system. The same packages work in
the browser and on the server, and packages can contain plugins that
extend the build process, such as `coffeescript` ([CoffeeScript](http://coffeescript.org)
compilation) or `templating` (compiling HTML templates).
You can see a list of available packages
with [`meteor list`](#meteorlist), add packages to your project
with [`meteor add`](#meteoradd), and remove them
with [`meteor remove`](#meteorremove).
By default all apps include the `standard-app-packages` package. This
automatically pulls in the packages that make up the core Meteor
stack. To keep things simple, these core packages are also hidden in
the output for `meteor list`, but you can read the
[source code of `standard-app-packages`](https://github.com/meteor/meteor/blob/master/packages/standard-app-packages/package.js)
to see what they are (as Meteor is pre-1.0, they may change from release to
release). If you want to build your own custom stack, just remove
`standard-app-packages` from your app and add back in whichever of the standard
packages you want to keep.
In addition to the packages in the official Meteor release being used
by your app, `meteor list` and `meteor add` also search the `packages`
directory at the top of your app. If you've downloaded an unofficial
package from Atmosphere you should unpack it into that directory (the
unofficial [Meteorite](http://oortcloud.github.io/meteorite/) tool
streamlines this process). You can also use the `packages` directory
to break your app into subpackages for your convenience &mdash; if you
are willing to brave the fact that the Meteor package format is not
documented yet and will change significantly before Meteor 1.0. See
[Writing Packages](#writingpackages).
{{/better_markdown}}
</template>
<template name="namespacing">
{{#better_markdown}}
<h2 id="namespacing">Namespacing</h2>
Meteor's namespacing support makes it easy to write large applications
in JavaScript. Each package that you use in your app exists in its own
separate namespace, meaning that it sees only its own global variables
and any variables provided by the packages that it specifically
uses. Here's how it works.
When you declare a top-level variable, you have a choice. You can make
the variable File Scope or Package Scope.
// File Scope. This variable will be visible only inside this
// one file. Other files in this app or package won't see it.
var alicePerson = {name: "alice"};
// Package Scope. This variable is visible to every file inside
// of this package or app. The difference is that 'var' is
// omitted.
bobPerson = {name: "bob"};
Notice that this is just the normal JavaScript syntax for declaring a
variable that is local or global. Meteor scans your source code for
global variable assignments and generates a wrapper that makes sure
that your globals don't escape their appropriate namespace.
In addition to File Scope and Package Scope, there are also
Exports. An export is a variable that a package makes available to you
when you use it. For example, the `email` package exports the `Email`
variable. If your app uses the `email` package (and _only_ if it uses
the `email` package!) then your app can see `Email` and you can call
`Email.send`. Most packages have only one export, but some packages
might have two or three (for example, a package that provides several
classes that work together).
You see only the exports of the packages that you use directly. If you
use package A, and package A uses package B, then you only see package
A's exports. Package B's exports don't "leak" into your namespace just
because you used package A. This keeps each namespace nice and
tidy. Each app or package only sees their own globals plus the APIs of
the packages that they specifically asked for.
When debugging your app, your browser's JavaScript console behaves as
if it were attached to your app's namespace. You see your app's
globals and the exports of the packages that your app uses
directly. You don't see the variables from inside those packages, and
you don't see the exports of your transitive dependencies (packages
that aren't used directly by your app, but that are used by packages
that are used by your app).
If you want to look inside packages from inside your in-browser
debugger, you've got two options:
* Set a breakpoint inside package code. While stopped on that
breakpoint, the console will be in the package's namespace. You'll
see the package's package-scope variables, imports, and also any
file-scope variables for the file you're stopped in.
* If a package `foo` is included in your app, regardless of whether
your app uses it directly, its exports are available in
`Package.foo`. For example, if the `email` package is loaded, then
you can access `Package.email.Email.send` even from namespaces that
don't use the `email` package directly.
When declaring functions, keep in mind that `function x () {}` is just
shorthard for `var x = function () {}` in JavaScript. Consider these
examples:
// This is the same as 'var x = function () ...'. So x() is
// file-scope and can be called only from within this one file.
function x () { ... }
// No 'var', so x() is package-scope and can be called from
// any file inside this app or package.
x = function () { ... }
{{#note}}
Technically speaking, globals in an app (as opposed to in a package)
are actually true globals. They can't be captured in a scope that is
private to the app code, because that would mean that they wouldn't be
visible in the console during debugging! This means that app globals
actually end up being visible in packages. That should never be a
problem for properly written package code (since the app globals will
still be properly shadowed by declarations in the packages). You
certainly shouldn't depend on this quirk, and in the future Meteor may
check for it and throw an error if you do.
{{/note}}
{{/better_markdown}}
</template>
<template name="deploying">
{{#better_markdown}}
<h2 id="deploying">Deploying</h2>
Meteor is a full application server. We include everything you need
to deploy your application on the internet: you just provide the JavaScript,
HTML, and CSS.
<h3 class="nosection">Running on Meteor's infrastructure</h3>
The easiest way to deploy your application is to use `meteor
deploy`. We provide it because it's what, personally, we've always
wanted: an easy way to take an app idea, flesh it out over a weekend,
and put it out there for the world to use, with nothing getting in the
way of creativity.
$ meteor deploy myapp.meteor.com
Your application is now available at myapp.meteor.com. If
this is the first time deploying to this hostname, Meteor creates a
fresh empty database for your application. If you want to deploy an
update, Meteor will preserve the existing data and just refresh the
code.
You can also deploy to your own domain. Just set up the hostname you
want to use as a CNAME to `origin.meteor.com`,
then deploy to that name.
$ meteor deploy www.myapp.com
We provide this as a free service so you can try Meteor. It is also
helpful for quickly putting up internal betas, demos, and so on.
<h3 class="nosection">Running on your own infrastructure</h3>
You can also run your application on your own infrastructure, or any
other hosting provider like Heroku.
To get started, run
$ meteor bundle myapp.tgz
This command will generate a fully-contained Node.js application in the form of
a tarball. To run this application, you need to provide Node.js 0.10 and a
MongoDB server. (The current release of Meteor has been tested with Node
0.10.25; older versions contain a serious bug that can cause production servers
to stall.) You can then run the application by invoking node, specifying the
HTTP port for the application to listen on, and the MongoDB endpoint. If
you don't already have a MongoDB server, we can recommend our friends at
[MongoHQ](http://mongohq.com).
$ PORT=3000 MONGO_URL=mongodb://localhost:27017/myapp node bundle/main.js
Other packages may require other environment variables (for example, the `email`
package requires a `MAIL_URL` environment variable).
{{#warning}}
For now, bundles will only run on the platform that the bundle was
created on. To run on a different platform, you'll need to rebuild
the native packages included in the bundle. To do that, make sure you
have `npm` available, and run the following:
$ cd bundle/programs/server/node_modules
$ rm -r fibers
$ npm install fibers@1.0.1
{{/warning}}
{{/better_markdown}}
</template>
<template name="packages_writing">
{{#better_markdown}}
<h2 id="writingpackages">Writing packages</h2>
The Meteor package format isn't officially documented and will change
before Meteor 1.0. But that hasn't stopped people like you from
creating hundreds of packages by reading the source code of existing
packages and following the model. If you do decide to create your own
packages, you will have to do some detective work, but here are some
quick tips:
* A package is simply a directory with a `package.js` file in it. Look in the
[`packages` directory of the Meteor source
tree](https://github.com/meteor/meteor/tree/master/packages/) for example
`package.js` files. The format and name of the `package.js` file will change
significantly before Meteor 1.0, but the functionality will be basically the
same even though the syntax is different, so it will be easy to port your
code.
* Packages explicitly list all of their source files using `api.add_files`, and
the files are loaded exactly in the order specified. (This is different from
apps, where Meteor scans a directory tree to find the source files.) Don't
forget to include any build plugin packages (such as `coffeescript` or, if
using HTML templates, `templating`) that you require.
* Exporting a symbol from your package (see
[Namespacing](#namespacing)) is accomplished with an `api.export` call
from inside your `on_use` handler.
* An esoteric point about exports: they are not lvalues. You can't set
an exported variable to a new value after exporting it. If you
export `a = {name: 'alice'}` then you can change `a.name` anytime
you want, but if after startup you set `a` to a whole new object
then the packages that import `a` won't see the change. Since your
exports are most always objects or functions, this is hardly ever an
issue.
* Packages can use [npm modules](https://npmjs.org/). Use `Npm.depends` in your
`package.js` to list the npm modules that you need and the specific
versions that you want to use. Then use `Npm.require` inside your
package to pull in the modules when you need them. Meteor strives to
have 100% repeatable builds so that everyone on your team is always
running the same code, and that's why you must explicitly lock your
npm dependencies to specific versions. Behind the scenes, Meteor
will use `npm shrinkwrap` to also lock down the versions of the
transitive dependencies of all of the npm modules that you use.
* Whenever your package changes, Meteor will rebuild it (compiling
non-JavaScript source files, fetching npm dependencies, constructing
namespace wrappers, and so on). The built package will be cached and
rebuilt only when a source file changes (tracked by SHA1) or when
other dependencies such as build plugins change. To force a rebuild
you can use the undocumented command `meteor rebuild-all`, but this
should never be necessary (if it is, please send a
[bug report](https://github.com/meteor/meteor/blob/devel/Contributing.md#filing-bug-reports)!).
* Build plugins are created with `_transitional_registerBuildPlugin`,
an API that is very much in flux. See the `coffeescript` package for
an example. Build plugins are fully-fledged Meteor programs in their
own right and have their own namespace, package dependencies, source
files and npm requirements. The old `register_extension` API is
removed.
* It is possible to create weak dependencies between packages. If
package A has a weak dependency on package B, it means that
including A in an app does not force B to be included too &mdash;
but, if B _is_ included, say by the app developer or by another
package, then B will load before A. You can use this to make
packages that optionally integrate with or enhance other packages if
those packages are present. To create a weak dependency, pass
`{weak: true}` as the third argument to `api.use`. When you weakly
depend on a package you don't see its exports. You can detect if
the possibly-present weakly-depended-on package is there by seeing
if `Package.foo` exists, and get its exports from the same place.
* It is also possible to create unordered dependencies by passing
`{unordered: true}`. An unordered dependency is the exact opposite
of a weak dependency. If A has an unordered dependency on B, then
including A forces B to be included as well, but doesn't require B
to load before A. This is occasionally useful for resolving circular
dependencies.
* The build system also supports package implication. If package A
implies package B, then it means that when someone depends on
package A, it's as if they also depended on package B as well. In
particular, they get B's exports. This is done with `api.imply` and
can be used to create umbrella packages such as
`standard-app-packages` that are a shortcut for pulling in a set of
packages, or it can be helpful in factoring common code out of a set
of packages as with `accounts-base`.
* The build system understands the idea of native code and has a
system of architecture names to ensure that packages that are
specific to one architecture aren't run on the wrong
architecture. For example, if you include an npm module that has a
native extension, your built Meteor package will be specific to your
machine architecture, but if not your built Meteor package will be
portable.
{{/better_markdown}}
</template>