Blame view

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