]> git.r.bdr.sh - rbdr/dotfiles/blob
037a6e817e32865d596530eaa61234ab66eb11ea
[rbdr/dotfiles] /
1 # amdefine
2
3 A module that can be used to implement AMD's define() in Node. This allows you
4 to code to the AMD API and have the module work in node programs without
5 requiring those other programs to use AMD.
6
7 ## Usage
8
9 **1)** Update your package.json to indicate amdefine as a dependency:
10
11 ```javascript
12 "dependencies": {
13 "amdefine": ">=0.1.0"
14 }
15 ```
16
17 Then run `npm install` to get amdefine into your project.
18
19 **2)** At the top of each module that uses define(), place this code:
20
21 ```javascript
22 if (typeof define !== 'function') { var define = require('amdefine')(module) }
23 ```
24
25 **Only use these snippets** when loading amdefine. If you preserve the basic structure,
26 with the braces, it will be stripped out when using the [RequireJS optimizer](#optimizer).
27
28 You can add spaces, line breaks and even require amdefine with a local path, but
29 keep the rest of the structure to get the stripping behavior.
30
31 As you may know, because `if` statements in JavaScript don't have their own scope, the var
32 declaration in the above snippet is made whether the `if` expression is truthy or not. If
33 RequireJS is loaded then the declaration is superfluous because `define` is already already
34 declared in the same scope in RequireJS. Fortunately JavaScript handles multiple `var`
35 declarations of the same variable in the same scope gracefully.
36
37 If you want to deliver amdefine.js with your code rather than specifying it as a dependency
38 with npm, then just download the latest release and refer to it using a relative path:
39
40 [Latest Version](https://github.com/jrburke/amdefine/raw/latest/amdefine.js)
41
42 ### amdefine/intercept
43
44 Consider this very experimental.
45
46 Instead of pasting the piece of text for the amdefine setup of a `define`
47 variable in each module you create or consume, you can use `amdefine/intercept`
48 instead. It will automatically insert the above snippet in each .js file loaded
49 by Node.
50
51 **Warning**: you should only use this if you are creating an application that
52 is consuming AMD style defined()'d modules that are distributed via npm and want
53 to run that code in Node.
54
55 For library code where you are not sure if it will be used by others in Node or
56 in the browser, then explicitly depending on amdefine and placing the code
57 snippet above is suggested path, instead of using `amdefine/intercept`. The
58 intercept module affects all .js files loaded in the Node app, and it is
59 inconsiderate to modify global state like that unless you are also controlling
60 the top level app.
61
62 #### Why distribute AMD-style modules via npm?
63
64 npm has a lot of weaknesses for front-end use (installed layout is not great,
65 should have better support for the `baseUrl + moduleID + '.js' style of loading,
66 single file JS installs), but some people want a JS package manager and are
67 willing to live with those constraints. If that is you, but still want to author
68 in AMD style modules to get dynamic require([]), better direct source usage and
69 powerful loader plugin support in the browser, then this tool can help.
70
71 #### amdefine/intercept usage
72
73 Just require it in your top level app module (for example index.js, server.js):
74
75 ```javascript
76 require('amdefine/intercept');
77 ```
78
79 The module does not return a value, so no need to assign the result to a local
80 variable.
81
82 Then just require() code as you normally would with Node's require(). Any .js
83 loaded after the intercept require will have the amdefine check injected in
84 the .js source as it is loaded. It does not modify the source on disk, just
85 prepends some content to the text of the module as it is loaded by Node.
86
87 #### How amdefine/intercept works
88
89 It overrides the `Module._extensions['.js']` in Node to automatically prepend
90 the amdefine snippet above. So, it will affect any .js file loaded by your
91 app.
92
93 ## define() usage
94
95 It is best if you use the anonymous forms of define() in your module:
96
97 ```javascript
98 define(function (require) {
99 var dependency = require('dependency');
100 });
101 ```
102
103 or
104
105 ```javascript
106 define(['dependency'], function (dependency) {
107
108 });
109 ```
110
111 ## RequireJS optimizer integration. <a name="optimizer"></name>
112
113 Version 1.0.3 of the [RequireJS optimizer](http://requirejs.org/docs/optimization.html)
114 will have support for stripping the `if (typeof define !== 'function')` check
115 mentioned above, so you can include this snippet for code that runs in the
116 browser, but avoid taking the cost of the if() statement once the code is
117 optimized for deployment.
118
119 ## Node 0.4 Support
120
121 If you want to support Node 0.4, then add `require` as the second parameter to amdefine:
122
123 ```javascript
124 //Only if you want Node 0.4. If using 0.5 or later, use the above snippet.
125 if (typeof define !== 'function') { var define = require('amdefine')(module, require) }
126 ```
127
128 ## Limitations
129
130 ### Synchronous vs Asynchronous
131
132 amdefine creates a define() function that is callable by your code. It will
133 execute and trace dependencies and call the factory function *synchronously*,
134 to keep the behavior in line with Node's synchronous dependency tracing.
135
136 The exception: calling AMD's callback-style require() from inside a factory
137 function. The require callback is called on process.nextTick():
138
139 ```javascript
140 define(function (require) {
141 require(['a'], function(a) {
142 //'a' is loaded synchronously, but
143 //this callback is called on process.nextTick().
144 });
145 });
146 ```
147
148 ### Loader Plugins
149
150 Loader plugins are supported as long as they call their load() callbacks
151 synchronously. So ones that do network requests will not work. However plugins
152 like [text](http://requirejs.org/docs/api.html#text) can load text files locally.
153
154 The plugin API's `load.fromText()` is **not supported** in amdefine, so this means
155 transpiler plugins like the [CoffeeScript loader plugin](https://github.com/jrburke/require-cs)
156 will not work. This may be fixable, but it is a bit complex, and I do not have
157 enough node-fu to figure it out yet. See the source for amdefine.js if you want
158 to get an idea of the issues involved.
159
160 ## Tests
161
162 To run the tests, cd to **tests** and run:
163
164 ```
165 node all.js
166 node all-intercept.js
167 ```
168
169 ## License
170
171 New BSD and MIT. Check the LICENSE file for all the details.