mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
589 lines
25 KiB
HTML
589 lines
25 KiB
HTML
<template name="concepts">
|
|
|
|
<h1 id="concepts">Concepts</h1>
|
|
{{> structure }}
|
|
{{> data_ }}
|
|
{{> reactivity }}
|
|
{{> livehtmltemplates }}
|
|
{{> packages_concept }}
|
|
{{> namespacing }}
|
|
{{> deploying }}
|
|
{{> packages_writing }}
|
|
</template>
|
|
|
|
<template name="structure">
|
|
{{#markdown}}
|
|
|
|
<h2 id="structuringyourapp">Structuring your application</h2>
|
|
|
|
A Meteor application is a mix of client-side JavaScript that runs inside a web
|
|
browser or PhoneGap mobile app, server-side JavaScript that runs on the Meteor
|
|
server inside a [Node.js](http://nodejs.org/) container, and all the supporting
|
|
HTML templates, 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.
|
|
|
|
### Special Directories
|
|
|
|
By default, any JavaScript files in your Meteor folder are bundled and sent to
|
|
the client and the server. However, the names of the files and directories
|
|
inside your project can affect their load order, where they are loaded, and some
|
|
other characteristics. Here is a list of file and directory names that are
|
|
treated specially by Meteor:
|
|
|
|
- **client**
|
|
|
|
Any directory named `client` is not loaded on the server. Similar to
|
|
wrapping your code in `if (Meteor.isClient) { ... }`. All files loaded on
|
|
the client are automatically concatenated and minified when in production
|
|
mode. In development mode, JavaScript and CSS files are not minified, to
|
|
make debugging easier. (CSS files are still combined into a single file
|
|
for consistency between production and development, because changing the
|
|
CSS file's URL affects how URLs in it are processed.)
|
|
|
|
|
|
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.
|
|
|
|
- **server**
|
|
|
|
Any directory named `server` is not loaded on the client. Similar to
|
|
wrapping your code in `if (Meteor.isServer) { ... }`, except the client
|
|
never even receives the code. 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.
|
|
|
|
Meteor gathers all your JavaScript files, excluding anything under the
|
|
`client`, `public`, and `private` subdirectories, and loads them into a
|
|
Node.js server instance. 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.
|
|
|
|
- **public**
|
|
|
|
All files inside a top-level directory called `public` are served as-is to
|
|
the client. When referencing these assets, do not include `public/` in the
|
|
URL, write the URL as if they were all in the top level. For example,
|
|
reference `public/bg.png` as `<img src='/bg.png' />`. This is the best place
|
|
for `favicon.ico`, `robots.txt`, and similar files.
|
|
|
|
- **private**
|
|
|
|
All files inside a top-level directory called `private` are only accessible
|
|
from server code and can be loaded via the [`Assets`](#assets) API. This can
|
|
be used for private data files and any files that are in your project
|
|
directory that you don't want to be accessible from the outside.
|
|
|
|
- **client/compatibility**
|
|
|
|
This folder is for compatibility JavaScript libraries that rely on variables
|
|
declared with var at the top level being exported as globals. Files in this
|
|
directory are executed without being wrapped in a new variable scope. These
|
|
files are executed before other client-side JavaScript files.
|
|
|
|
- **tests**
|
|
|
|
Any directory named `tests` is not loaded anywhere. Use this for any local
|
|
test code.
|
|
|
|
- **node_modules**
|
|
|
|
For compatibility with node.js tools used alongside Meteor, any directory named
|
|
`node_modules` is not loaded anywhere. node.js packages installed into
|
|
`node_modules` directories will not be available to your Meteor code. Use
|
|
`Npm.depends` in your package `package.js` file for that.
|
|
|
|
The following directories are also not loaded as part of your app code:
|
|
|
|
- Files/directories whose names start with a dot, like `.meteor` and `.git`
|
|
- `packages/`: Used for local packages, covered below
|
|
- `programs`: For legacy reasons
|
|
- [`cordova-build-override`](https://github.com/meteor/meteor/wiki/Meteor-Cordova-Phonegap-integration#advanced-build-customization)
|
|
|
|
### Files outside special directories
|
|
|
|
All JavaScript files outside special directories are loaded on both the client
|
|
and the server. That's the place for model definitions and other functions.
|
|
Meteor provides the variables [`Meteor.isClient`](#meteor_isclient) and
|
|
[`Meteor.isServer`](#meteor_isserver) so that your code can alter its behavior
|
|
depending on whether it's running on the client or the server.
|
|
|
|
CSS and HTML files outside special directories are loaded on the client only,
|
|
and cannot be used from server code.
|
|
|
|
### Example File Structure
|
|
|
|
The file structure of your Meteor app is very flexible. Here is an example layout that takes advantage of some of the special folders mentioned above.
|
|
|
|
```bash
|
|
lib/ # common code like collections and utilities
|
|
lib/methods.js # Meteor.methods definitions
|
|
lib/constants.js # constants used in the rest of the code
|
|
|
|
client/compatibility # legacy libraries that expect to be global
|
|
client/lib/ # code for the client to be loaded first
|
|
client/lib/helpers.js # useful helpers for your client code
|
|
client/body.html # content that goes in the <body> of your HTML
|
|
client/head.html # content for <head> of your HTML: <meta> tags, etc
|
|
client/style.css # some CSS code
|
|
client/<feature>.html # HTML templates related to a certain feature
|
|
client/<feature>.js # JavaScript code related to a certain feature
|
|
|
|
server/lib/permissions.js # sensitive permissions code used by your server
|
|
server/publications.js # Meteor.publish definitions
|
|
|
|
public/favicon.ico # app icon
|
|
|
|
settings.json # configuration data to be passed to meteor --settings
|
|
mobile-config.js # define icons and metadata for Android/iOS
|
|
```
|
|
|
|
You can also model your directory structure after the example apps. Run `meteor
|
|
create --example todos` and explore the directories to see where all the files
|
|
in a real app could go.
|
|
|
|
### File Load Order
|
|
|
|
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.
|
|
|
|
There are several load ordering rules. They are *applied sequentially* to all
|
|
applicable files in the application, in the priority given below:
|
|
|
|
1. HTML template files are *always* loaded before everything else
|
|
2. Files beginning with `main.` are loaded last
|
|
3. Files inside *any* `lib/` directory are loaded next
|
|
4. Files with deeper paths are loaded next
|
|
5. Files are then loaded in alphabetical order of the entire path
|
|
|
|
```js
|
|
nav.html
|
|
main.html
|
|
client/lib/methods.js
|
|
client/lib/styles.js
|
|
lib/feature/styles.js
|
|
lib/collections.js
|
|
client/feature-y.js
|
|
feature-x.js
|
|
client/main.js
|
|
```
|
|
|
|
For example, the files above are arranged in the correct load order.
|
|
`main.html` is loaded second because HTML templates are always loaded first,
|
|
even if it begins with `main.`, since rule 1 has priority over rule 2.
|
|
However, it will be loaded after `nav.html` because rule 2 has priority over
|
|
rule 5.
|
|
|
|
`client/lib/styles.js` and `lib/feature/styles.js` have identical load order
|
|
up to rule 4; however, since `client` comes before `lib` alphabetically,
|
|
it will be loaded first.
|
|
|
|
### Organizing Your Project
|
|
|
|
There are three main ways to organize your files into features or components.
|
|
Let's say we have two types of objects in our project: **apples** and
|
|
**oranges**.
|
|
|
|
#### Method 1: Root-Level Folders
|
|
|
|
Since the special `client`, `server`, and `lib` directories work if they are
|
|
anywhere in the path, you can use top-level folders to organize code into
|
|
modules:
|
|
|
|
```bash
|
|
apples/lib/ # code for apple-related features
|
|
apples/client/
|
|
apples/server/
|
|
|
|
oranges/lib/ # code for orange-related features
|
|
oranges/client/
|
|
oranges/server/
|
|
```
|
|
|
|
#### Method 2: Folders inside client/ and server/
|
|
|
|
```bash
|
|
lib/apples/ # common code for apples
|
|
lib/oranges/ # and oranges
|
|
|
|
client/apples/ # client code for apples
|
|
client/oranges/ # and oranges
|
|
|
|
server/apples/ # server code for apples
|
|
server/oranges/ # and oranges
|
|
```
|
|
|
|
#### Method 3: Packages
|
|
|
|
This is the ultimate in code separation, modularity, and reusability. If you put
|
|
the code for each feature in a separate package, the code for one feature won't
|
|
be able to access the code for the other feature except through exports, making
|
|
every dependency explicit. This also allows for the easiest independent testing
|
|
of features. You can also publish the packages and use them in multiple apps
|
|
with `meteor add`.
|
|
|
|
```bash
|
|
packages/apples/package.js # files, dependencies, exports for apple feature
|
|
packages/apples/<anything>.js # file loading is controlled by package.js
|
|
|
|
packages/oranges/package.js # files, dependencies, exports for orange feature
|
|
packages/oranges/<anything>.js # file loading is controlled by package.js
|
|
```
|
|
|
|
{{/markdown}}
|
|
</template>
|
|
|
|
<template name="data_">
|
|
{{#markdown}}
|
|
|
|
<a id="dataandsecurity-validation"></a>
|
|
<h2 id="dataandsecurity">Data and security</h2>
|
|
|
|
To read about best practices for managing data and security in Meteor, consult the Meteor Guide:
|
|
|
|
- [Security](http://guide.meteor.com/security.html)
|
|
- [Database collections](http://guide.meteor.com/collections.html)
|
|
- [Data loading](http://guide.meteor.com/data-loading.html)
|
|
- [Methods and saving data](http://guide.meteor.com/methods.html)
|
|
|
|
<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
|
|
[bcrypt](http://en.wikipedia.org/wiki/Bcrypt) algorithm,
|
|
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.
|
|
|
|
[Read about how to manage user accounts in your Meteor app in the Meteor Guide.](http://guide.meteor.com/accounts.html)
|
|
|
|
{{/markdown}}
|
|
</template>
|
|
|
|
<template name="reactivity">
|
|
{{#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.
|
|
|
|
Tracker.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 `Tracker.autorun`. `Tracker.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](#livehtmltemplates)
|
|
* [`Tracker.autorun`](#tracker_autorun)
|
|
* [`Template.autorun`](#template_autorun)
|
|
* [`Blaze.render`](#blaze_render) and [`Blaze.renderWithData`](#blaze_renderwithdata)
|
|
|
|
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:
|
|
|
|
* [`Tracker.autorun`](#tracker_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/tracker/tracker.js)
|
|
is a package called [`Tracker`](#tracker) that is fairly short and straightforward.
|
|
You can use it yourself to implement new reactive data sources.
|
|
|
|
{{/markdown}}
|
|
</template>
|
|
|
|
<template name="livehtmltemplates">
|
|
{{#markdown}}
|
|
|
|
<h2 id="livehtmltemplates">Live HTML templates</h2>
|
|
|
|
HTML templating is central to web applications. With Blaze, 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.
|
|
|
|
[Read about how to use Blaze in the Meteor Guide.](http://guide.meteor.com/blaze.html)
|
|
|
|
{{/markdown}}
|
|
</template>
|
|
|
|
<template name="packages_concept">
|
|
{{#markdown}}
|
|
|
|
<h2 id="usingpackages">Using packages</h2>
|
|
|
|
All of the functionality you've read about so far is implemented in standard
|
|
Meteor packages. This is possible thanks to Meteor's unusually powerful
|
|
isomorphic package and build system. Isomorphic means the same packages work in
|
|
the web browser, in mobile apps, and on the server. Packages can also contain
|
|
plugins that extend the build process, such as `coffeescript`
|
|
([CoffeeScript](http://coffeescript.org) compilation) or `templating` (compiling
|
|
HTML templates).
|
|
|
|
Anyone can publish a Meteor package, and thousands of community-written packages
|
|
have been published to date. The easiest way to browse these packages is
|
|
<a href="http://www.atmospherejs.com">Atmosphere</a>, by Percolate Studio.
|
|
You can also use the [`meteor search`](#meteorsearch) and
|
|
[`meteor show`](#meteorshow) commands.
|
|
|
|
You can add packages to your project with [`meteor add`](#meteoradd) and remove
|
|
them with [`meteor remove`](#meteorremove).
|
|
Additionally, [`meteor list`](#meteorlist) will tell you what
|
|
packages your project is using, and [`meteor update`](#meteorupdate)
|
|
will update them to the newest versions when possible.
|
|
|
|
By default all apps include the `meteor-base` package. This pulls in the
|
|
packages that make up the core of the Meteor stack. Most apps will have this
|
|
package.
|
|
|
|
All new apps also start with a set of packages that allow a friendly development
|
|
experience. For more information about these packages, check out the comments in
|
|
the [packages file](https://github.com/meteor/meteor/blob/master/tools/skel/.meteor/packages).
|
|
|
|
Meteor uses a single-loading packaging system, meaning that it loads just one
|
|
version of every package. Before adding or upgrading to a particular version of
|
|
a package, Meteor uses a constraint solver to check if doing so will cause
|
|
other packages to break. By default, Meteor will choose conservatively. When
|
|
adding transitive dependencies (packages that other packages, but not the
|
|
application itself) depend on, Meteor will try to choose the earlier version.
|
|
|
|
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. You can also use the `packages` directory to break your app
|
|
into subpackages for your convenience, or to test packages that you might want
|
|
to publish. See [Writing Packages](#writingpackages). If you wish to add
|
|
packages outside of your app's folder structure, set the environment variable
|
|
`PACKAGE_DIRS` to a colon-delimited list of paths.
|
|
|
|
{{/markdown}}
|
|
</template>
|
|
|
|
|
|
<template name="namespacing">
|
|
{{#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
|
|
shorthand for `var x = function x () {}` in JavaScript. Consider these
|
|
examples:
|
|
|
|
// This is the same as 'var x = function x () ...'. 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}}
|
|
|
|
{{/markdown}}
|
|
</template>
|
|
|
|
|
|
<template name="deploying">
|
|
{{#markdown}}
|
|
|
|
<h2 id="deploying">Deploying</h2>
|
|
|
|
To learn how to deploy Meteor apps, read the
|
|
[deployment article in the Meteor Guide](http://guide.meteor.com/deployment.html).
|
|
|
|
{{/markdown}}
|
|
</template>
|
|
|
|
|
|
<template name="packages_writing">
|
|
{{#markdown}}
|
|
|
|
<h2 id="writingpackages">Writing packages</h2>
|
|
|
|
Writing Meteor packages is easy. To initialize a meteor package, run
|
|
`meteor create --package username:packagename`, where `username` is your Meteor
|
|
Developer username. This will create a package from scratch and prefill the
|
|
directory with a package.js control file and some javascript. By default, Meteor
|
|
will take the package name from the name of the directory that contains the
|
|
package.js file. Don't forget to run `meteor add [packagename]`, even if the
|
|
package is internal to the app, in order to use it.
|
|
|
|
Meteor promises repeatable builds for both packages and applications. This means
|
|
that, if you built your package on a machine, then checked the code into a
|
|
repository and checked it out elsewhere, you should get the same result. In your
|
|
package directory, you will find an automatically generated `.versions`
|
|
file. This file specifies the versions of all packages used to build your
|
|
package and is part of the source. Check it into version control to ensure
|
|
repeatable builds across machines.
|
|
|
|
{{#note}}
|
|
|
|
Sometimes, packages do not just stand on their own, but function in the context
|
|
of an app (specifically, packages in the packages directory of an app). In that
|
|
case, the app's context will take precedence. Rather than using the
|
|
`.versions` file as a guide, we will build the package with the same
|
|
dependencies as used by the app (we think that, in practice, it would be
|
|
confusing to find your local packages built with different versions of
|
|
things).
|
|
|
|
{{/note}}
|
|
|
|
Meteor uses extended semver versioning for its packages: that means that the version
|
|
number has three parts separated by dots: major version, minor version and patch version
|
|
(for example: 1.2.3) with an optional pre-release version. You can read more about it on
|
|
[semver.org](http://www.semver.org).
|
|
Additionally, because some meteor packages wrap external libraries,
|
|
Meteor supports the convention of using `_` to denote a wrap number.
|
|
|
|
You can read more about [`package.js`](#packagejs) files in the API
|
|
section.
|
|
|
|
A word on testing: since testing is an important part of the development process,
|
|
there are two common ways to test a package:
|
|
|
|
* Integration tests (putting a package directly into an application, and writing
|
|
tests against the application) is the most common way to test a package. After
|
|
creating your package, add it to your app's /packages directory and run `meteor add`.
|
|
This will add your package to your app as a local package. You can then
|
|
test and run your app as usual. Meteor will detect and respond to changes to
|
|
your local package, just as it does to your app files.
|
|
|
|
* Unit tests are run with the command [`meteor test-packages package-name`](#meteortestpackages).
|
|
As described in the [`package.js`](#packagejs)
|
|
section, you can use the `package.js` file to specify where your unit tests are
|
|
located. If you have a repository that contains only the package source, you can
|
|
test your package by specifying the path to the package directory (which must
|
|
contain a slash), such as `meteor test-packages ./`.
|
|
|
|
To publish a package, run [`meteor publish`](#meteorpublish) from the package
|
|
directory. There are some extra restrictions on published packages: they must
|
|
contain a version (Meteor packages are versioned using
|
|
strict <a href="http://www.semver.org">semver</a> versioning) and their names
|
|
must be prefixed with the username of the author and a colon, like so:
|
|
`iron:router`. This namespacing allows for more descriptive and on-topic package
|
|
names.
|
|
|
|
{{/markdown}}
|
|
</template>
|