UNPKG

8.78 kBMarkdownView Raw
1#almond
2
3A replacement [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) loader for
4[RequireJS](http://requirejs.org). It provides a minimal AMD API footprint that includes [loader plugin](http://requirejs.org/docs/plugins.html) support. Only useful for built/bundled AMD modules, does not do dynamic loading.
5
6## Why
7
8Some developers like to use the AMD API to code modular JavaScript, but after doing an optimized build,
9they do not want to include a full AMD loader like RequireJS, since they do not need all that functionality.
10Some use cases, like mobile, are very sensitive to file sizes.
11
12By including almond in the built file, there is no need for RequireJS.
13almond is around **1 kilobyte** when minified with Closure Compiler and gzipped.
14
15Since it can support certain types of loader plugin-optimized resources, it is a great
16fit for a library that wants to use [text templates](http://requirejs.org/docs/api.html#text)
17or [CoffeeScript](https://github.com/jrburke/require-cs) as part of
18their project, but get a tiny download in one file after using the
19[RequireJS Optimizer](http://requirejs.org/docs/optimization.html).
20
21If you are building a library, the wrap=true support in the RequireJS optimizer
22will wrap the optimized file in a closure, so the define/require AMD API does not
23escape the file. Users of your optimized file will only see the global API you decide
24to export, not the AMD API. See the usage section below for more details.
25
26So, you get great code cleanliness with AMD and the use of powerful loader plugins
27in a tiny wrapper that makes it easy for others to use your code even if they do not use AMD.
28
29If you want a single file build output but without the module APIs included, you might want to consider [AMDclean](https://github.com/gfranko/amdclean).
30
31## Restrictions
32
33It is best used for libraries or apps that use AMD and:
34
35* optimize all the modules into one file -- no dynamic code loading.
36* all modules have IDs and dependency arrays in their define() calls -- the RequireJS optimizer will take care of this for you.
37* only have **one** requirejs.config() or require.config() call.
38* the requirejs.config/require.config call needs to be included in the build output. This is particularly important for making sure any [map config](http://requirejs.org/docs/api.html#config-map) use still works.
39* do not use the `var require = {};` style of [passing config](http://requirejs.org/docs/api.html#config).
40* do not use [RequireJS multiversion support/contexts](http://requirejs.org/docs/api.html#multiversion).
41* do not use require.toUrl() or require.nameToUrl().
42* do not use [packages/packagePaths config](http://requirejs.org/docs/api.html#packages). If you need to use packages that have a main property, [volo](https://github.com/volojs/volo) can create an adapter module so that it can work without this config. Use the `amdify add` command to add the dependency to your project.
43
44What is supported:
45
46* dependencies with relative IDs.
47* define('id', {}) definitions.
48* define(), require() and requirejs() calls.
49* loader plugins that can inline their resources into optimized files, and
50can access those inlined resources synchronously after the optimization pass.
51The [text](http://requirejs.org/docs/api.html#text) and
52[CoffeeScript](https://github.com/jrburke/require-cs) plugins are two such plugins.
53
54## Download
55
56[Latest release](https://github.com/jrburke/almond/raw/latest/almond.js)
57
58
59## Usage
60
61[Download the RequireJS optimizer](http://requirejs.org/docs/download.html#rjs).
62
63[Download the current release of almond.js](https://github.com/jrburke/almond/raw/latest/almond.js).
64
65Run the optimizer using [Node](http://nodejs.org) (also [works in Java](https://github.com/jrburke/r.js/blob/master/README.md)):
66
67 node r.js -o baseUrl=. name=path/to/almond include=main out=main-built.js wrap=true
68
69This assumes your project's top-level script file is called main.js and the command
70above is run from the directory containing main.js. If you prefer to use a build.js build profile instead of command line arguments, [this RequireJS optimization section](http://requirejs.org/docs/optimization.html#pitfalls) has info on how to do that.
71
72wrap=true will add this wrapper around the main-built.js contents (which will be minified by UglifyJS:
73
74 (function () {
75 //almond will be here
76 //main and its nested dependencies will be here
77 }());
78
79If you do not want that wrapper, leave off the wrap=true argument.
80
81These optimizer arguments can also be used in a build config object, so it can be used
82in [runtime-generated server builds](https://github.com/jrburke/r.js/blob/master/build/tests/http/httpBuild.js).
83
84
85## Triggering module execution <a name="execution"></a>
86
87As of RequireJS 2.0 and almond 0.1, modules are only executed if they are
88called by a top level require call. The data-main attribute on a script tag
89for require.js counts as a top level require call.
90
91However with almond, it does not look for a data-main attribute, and if your
92main JS module does not use a top level require() or requirejs() call to
93trigger module loading/execution, after a build, it may appear that the code
94broke -- no modules execute.
95
96The 2.0 RequireJS optimizer has a build config, option **insertRequire** that you
97can use to specify that a require([]) call is inserted at the end of the built
98file to trigger module loading. Example:
99
100 node r.js -o baseUrl=. name=path/to/almond.js include=main insertRequire=main out=main-built.js wrap=true
101
102or, if using a build config file:
103
104```javascript
105{
106 baseUrl: '.',
107 name: 'path/to/almond',
108 include: ['main'],
109 insertRequire: ['main'],
110 out: 'main-built.js',
111 wrap: true
112}
113```
114
115This will result with `require(["main"]);` at the bottom of main-built.js.
116
117## Exporting a public API
118
119If you are making a library that is made up of AMD modules in source form, but will be built with almond into one file, and you want to export a small public
120API for that library, you can use the `wrap` build config to do so. Build
121config:
122
123```javascript
124{
125 baseUrl: '.',
126 name: 'path/to/almond',
127 include: ['main'],
128 out: 'lib-built.js',
129 wrap: {
130 startFile: 'path/to/start.frag',
131 endFile: 'path/to/end.frag'
132 }
133}
134```
135
136Where start.frag could look like this:
137
138```javascript
139(function (root, factory) {
140 if (typeof define === 'function' && define.amd) {
141 //Allow using this built library as an AMD module
142 //in another project. That other project will only
143 //see this AMD call, not the internal modules in
144 //the closure below.
145 define([], factory);
146 } else {
147 //Browser globals case. Just assign the
148 //result to a property on the global.
149 root.libGlobalName = factory();
150 }
151}(this, function () {
152 //almond, and your modules will be inlined here
153```
154
155and end.frag is like this:
156```javascript
157 //The modules for your project will be inlined above
158 //this snippet. Ask almond to synchronously require the
159 //module value for 'main' here and return it as the
160 //value to use for the public API for the built file.
161 return require('main');
162}));
163```
164
165After the build, then the built file should be structured like so:
166
167* start.frag
168* almond.js
169* modules for your lib, including 'main'
170* end.frag
171
172## Common errors
173
174Explanations of common errors:
175
176### deps is undefined
177
178Where this line is mentioned:
179
180 if (!deps.splice) {
181
182It usually means that there is a define()'d module, but it is missing a name,
183something that looks like this:
184
185 define(function () {});
186 //or
187 define([], function () {});
188
189
190when it should look like:
191
192 define('someName', function () {});
193 //or
194 define('someName', [], function () {});
195
196
197This is usually a sign that the tool you used to combine all the modules
198together did not properly name an anonymous AMD module.
199
200### x missing y
201
202It means that module 'x' asked for module 'y', but module 'y' was not available.
203
204This usually means that 'y' was not included in the built file that includes almond.
205
206almond can only handle modules built in with it, it cannot dynamically load
207modules from the network.
208
209
210### No y
211
212It means that a `require('y')` call was done but y was not available.
213
214This usually means that 'y' was not included in the built file that includes almond.
215
216almond can only handle modules built in with it, it cannot dynamically load
217modules from the network.
218
219## How to get help
220
221* Contact the [requirejs list](https://groups.google.com/group/requirejs).
222* Open issues in the [issue tracker](https://github.com/jrburke/almond/issues).
223
224## Contributing
225
226Almond follows the
227[same contribution model as requirejs](http://requirejs.org/docs/contributing.html)
228and is considered a sub-project of requirejs.
\No newline at end of file