You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+21-34Lines changed: 21 additions & 34 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
run.js loads JavaScript modules and JavaScript files. It is optimized for in-browser use, but can be easily adapted to other JavaScript environments.
4
4
5
-
If the loaded file calls run() to define a JavaScript module, then run.js can properly trace the module's dependencies and evaluate modules in the correct order. run() allows for module modifiers and has a plugin system that supports features like i18n string bundles and text file dependencies.
5
+
If the loaded file calls run.def() to define a JavaScript module, then run.js can properly trace the module's dependencies and evaluate modules in the correct order. RunJS allows for module modifiers and has a plugin system that supports features like i18n string bundles and text file dependencies.
6
6
7
7
It uses plain script tags to load modules/files, so it should allow for easy debugging.
8
8
@@ -48,10 +48,9 @@ See the **Configuration Options** section for information on changing the lookup
48
48
49
49
## Defining a Module
50
50
51
-
If the module does not have any dependencies, then just specify the name of the module as the first argument to run() and and the second argument is just an object literal that defines the module's properties. For example:
51
+
If the module does not have any dependencies, then just specify the name of the module as the first argument to run.def() and and the second argument is just an object literal that defines the module's properties. For example:
52
52
53
-
run(
54
-
"my/simpleshirt",
53
+
run.def("my/simpleshirt",
55
54
{
56
55
color: "black",
57
56
size: "unisize"
@@ -62,8 +61,7 @@ This example would be stored in a my/simpleshirt.js file.
62
61
63
62
If the module has dependencies, then specify the dependencies as the second argument (as an array) and then pass a function as the third argument. The function will be called to define the module once all dependencies have loaded. The function should return an object that defines the module:
64
63
65
-
run(
66
-
"my/shirt",
64
+
run.def("my/shirt",
67
65
["my/cart", "my/inventory"],
68
66
function(cart, inventory) {
69
67
//return an object to define the "my/shirt" module.
@@ -94,8 +92,7 @@ The return object from the function call defines the "my/shirt" module. Be defin
94
92
95
93
If the modules do not have to return objects. Any valid return value from a function is allowed. Here is a module that returns a function as its module definition:
96
94
97
-
run(
98
-
"my/title",
95
+
run.def("my/title",
99
96
["my/dependency1", "my/dependency2"],
100
97
function(dep1, dep2) {
101
98
//return a function to define "my/title". It gets or sets
@@ -114,8 +111,7 @@ Only one module should be defined per JavaScript file, given the nature of the m
114
111
115
112
If you define a circular dependency (A needs B and B needs A), then in this case when B's module function is called, it will get an undefined value for A. B can fetch A later after modules have been defined by using the run.get() method (be sure to specify run as a dependency so the right context is used to look up A):
116
113
117
-
run(
118
-
"B",
114
+
run.def("B",
119
115
["run", "A"],
120
116
function(run, a) {
121
117
//"a" in this case will be null if A also asked for B,
@@ -142,8 +138,7 @@ To define a bundle, put it in a directory called "nls" -- the i18n! plugin assum
142
138
143
139
The contents of that file should look like so:
144
140
145
-
run(
146
-
"i18n!my/nls/colors",
141
+
run.def("i18n!my/nls/colors",
147
142
[{
148
143
"root": {
149
144
"red": "red",
@@ -157,8 +152,7 @@ Notice that an object literal with a property of "root" as given as the only dep
157
152
158
153
You can then use the above module in another module, say, in a my/lamps.js file:
159
154
160
-
run(
161
-
"my/lamps",
155
+
run.def("my/lamps",
162
156
["i18n!my/nls/colors"],
163
157
function(colors) {
164
158
return {
@@ -171,8 +165,7 @@ The my/lamps module has one property called "testMessage" that uses colors.red t
171
165
172
166
Later, when you want to add a specific translation to a file, say for the fr-fr locale, change my/nls/colors to look like so:
173
167
174
-
run(
175
-
"i18n!my/nls/colors",
168
+
run.def("i18n!my/nls/colors",
176
169
[{
177
170
"root": {
178
171
"red": "red",
@@ -185,8 +178,7 @@ Later, when you want to add a specific translation to a file, say for the fr-fr
185
178
186
179
Then define a file at my/nls/fr-fr/colors.js that has the following contents:
187
180
188
-
run(
189
-
"i18n!my/nls/fr-fr/colors",
181
+
run.def("i18n!my/nls/fr-fr/colors",
190
182
{
191
183
"red": "rouge",
192
184
"blue": "bleu",
@@ -200,8 +192,7 @@ run.js is also smart enough to pick the right locale bundle, the one that most c
200
192
201
193
run.js also combines bundles together, so for instance, if the french bundle was defined like so (omitting a value for red):
202
194
203
-
run(
204
-
"i18n!my/nls/fr-fr/colors",
195
+
run.def("i18n!my/nls/fr-fr/colors",
205
196
{
206
197
"blue": "bleu",
207
198
"green": "vert"
@@ -223,8 +214,7 @@ run.js has a plugin, run/text.js, that can help with this issue. It will automat
223
214
224
215
You can specify a text file resource as a dependency like so:
//the html variable will be the text of the some/module.html file
230
220
//the css variable will be the text of the som/module.css file.
@@ -236,8 +226,7 @@ Notice the !html and !css suffixes to specify the extension of the file.
236
226
237
227
For HTML/XML/SVG files, there is another option you can pass !strip, which strips XML declarations so that external SVG and XML documents can be added to a document without worry. Also, if the string is an HTML document, only the part inside the body tag is returned. Example:
238
228
239
-
run(
240
-
["text!some/module!html!strip"],
229
+
run(["text!some/module!html!strip"],
241
230
function(html) {
242
231
//the html variable will be the text of the some/module.html file,
243
232
//but only the part inside the body tag.
@@ -376,16 +365,15 @@ The example above in the **Multiversion Support** section shows how code can lat
376
365
377
366
## run.pause()/run.resume() for build layers/bundles
378
367
379
-
If you want to include many modules that use run() in one script, and those modules may depend on each other, then use run.pause() before the set of run() calls to prevent runjs from tracing dependencies on each run() call. When all the run() calls have finished in the file, call run.resume() to have the dependencies properly traced.
368
+
If you want to include many modules that use run.def() in one script, and those modules may depend on each other, then use run.pause() before the set of run calls to prevent runjs from tracing dependencies on each run call. When all the run calls have finished in the file, call run.resume() to have the dependencies properly traced.
380
369
381
370
Only use run.pause() and run.resume() on a file-by-file basis. Do not use run.pause() in one file and run.resume() in another file. Multiple files can call run.pause()/resume() combinations though.
382
371
383
372
Example:
384
373
385
374
run.pause();
386
375
387
-
run(
388
-
"alpha",
376
+
run.def("alpha",
389
377
["beta"],
390
378
function (beta) {
391
379
return {
@@ -395,16 +383,15 @@ Example:
395
383
}
396
384
);
397
385
398
-
run(
399
-
"beta",
386
+
run.def("beta",
400
387
{
401
388
name: "beta"
402
389
}
403
390
);
404
391
405
392
run.resume();
406
393
407
-
If run.pause() and run.resume() were not used, then the run() call to define "alpha" would have tried to load "beta" via another network/file IO call.
394
+
If run.pause() and run.resume() were not used, then the run.def() call to define "alpha" would have tried to load "beta" via another network/file IO call.
408
395
409
396
## Module Modifiers
410
397
@@ -440,7 +427,7 @@ You are not required to register modifiers with runjs. Only do it if you want to
440
427
441
428
### Modifier Definition
442
429
443
-
A modifier definition looks like a normal run() module definition, but:
430
+
A modifier definition looks like a normal run.def() module definition, but:
444
431
445
432
* run.modify() is used.
446
433
* the target module's name is listed first in the run.modify() call.
@@ -462,10 +449,10 @@ For the example given above in Modifier Registration, where "my/target1" is the
462
449
463
450
# History and Influences
464
451
465
-
I work a lot on the Dojo Loader. The normal dojo loader uses synchronous XMLHttpRequest (XHR) calls. However, the XHR loader cannot load Dojo modules from other domains because of the same-origin restrictions. So I created the xdomain loader that required a build step to inject function wrappers similar to what run() uses, but more complex, due to i18n bundle loading and dojo.requireIf behavior. Because of the more complex i18n and requireIf requirements and the existence of many dojo modules already out in the world, I did not feel like the Dojo community would consider writing modules with function wrappers manually.
452
+
I work a lot on the Dojo Loader. The normal dojo loader uses synchronous XMLHttpRequest (XHR) calls. However, the XHR loader cannot load Dojo modules from other domains because of the same-origin restrictions. So I created the xdomain loader that required a build step to inject function wrappers similar to what RunJS uses, but more complex, due to i18n bundle loading and dojo.requireIf behavior. Because of the more complex i18n and requireIf requirements and the existence of many dojo modules already out in the world, I did not feel like the Dojo community would consider writing modules with function wrappers manually.
466
453
467
-
However, the sync XHR loader has other issues, like making debugging harder. Recently, David Mark suggested that Dojo use document.write() to load modules before the page loads to help with that issue, but that means required dependencies would not load until after the current module executes. This can cause errors if the module references a dependency as part of the module's definition. So a function wrapper is needed. The Dojo community seemed more amenable to considering a function wrapper, particularly since we are considering a Dojo 2.0 that can break some APIs. I fleshed out some of the details for run() on the dojo-contributors list, and Mike Wilson originally pushed for a more generic loader that could load plain files as well as allow for different contexts. I hope run.js can be used for Dojo 2.0 modules, but more investigation on i18n and requireIf support is needed.
454
+
However, the sync XHR loader has other issues, like making debugging harder. Recently, David Mark suggested that Dojo use document.write() to load modules before the page loads to help with that issue, but that means required dependencies would not load until after the current module executes. This can cause errors if the module references a dependency as part of the module's definition. So a function wrapper is needed. The Dojo community seemed more amenable to considering a function wrapper, particularly since we are considering a Dojo 2.0 that can break some APIs. I fleshed out some of the details for RunJS on the dojo-contributors list, and Mike Wilson originally pushed for a more generic loader that could load plain files as well as allow for different contexts. I hope run.js can be used for Dojo 2.0 modules, but more investigation on i18n and requireIf support is needed.
468
455
469
-
YUI 3's use() function is also very similar to run(), and use()'s API (but not code) also informed run()'s structure. I believe run() is more generic, since YUI seems to use labels for their modules that do not directly correspond to file paths. It also looks like it cannot load plain JS files, and I liked explicitly passing the dependent modules as arguments to the function definition. YUI.use() might support some of these features underneath, but I just looked at the top-level API doc.
456
+
YUI 3's use() function is also very similar to run, and use()'s API (but not code) also informed run's structure. I believe RunJS is more generic, since YUI seems to use labels for their modules that do not directly correspond to file paths. It also looks like it cannot load plain JS files, and I liked explicitly passing the dependent modules as arguments to the function definition. YUI.use() might support some of these features underneath, but I just looked at the top-level API doc.
470
457
471
458
I originally wanted something that would work with CommonJS modules, but those modules seem to be structured assuming a synchronous module loader, which is possible in server-side JavaScript environments. However, I am mostly concerned with something that works well in the browser, and that means needing a function wrapper so we can use script tags. Using synchronous XHR is not very friendly for new developers or people who want easy of debugging across browsers. It can also be slower than plain script tag loading. Some environments, like Adobe AIR do not allow eval() and most developers are taught that eval() is evil and should be avoided. run.js should be very usable in a server-side environment, and I plan on using it there too.
0 commit comments