ServerJS/Modules/GlobalFileLoading

From MozillaWiki
Jump to: navigation, search

The following is a simple system based on loading files by filename. This is quite Ruby-like.


 //
 // Evaluate the content of the fully specified file 
 // in the global scope. 
 // 
 load('/usr/local/lib/js/File.js')  
 
 // 
 // If no file extension is included '.js' is assumed 
 // 
 load('/usr/local/lib/js/File')  
 
 // 
 // Searching through the library path.  
 // Suppose the path is 
 // /home/peter/js:/usr/local/lib/js:/usr/lib/js 
 //  
 load('File')  
 
 // 
 // Use 'load' above only if this file has never been 
 // loaded before. 
 // 
 load.once('File')  
 
 //  
 // Load a file relative to the current file's path. 
 // '__DIR__' is a macro expanded to the file's absolute path 
 // before the code is evaluated. It may be that __DIR__ is 
 // expanded to be something like 
 // 
 //    /home/peter/src/foo-project  
 // 
 // This allows for one file to load many others distributed 
 // in the same package. 
 // 
 //    web-framework.js 
 //    web-framework/ 
 //      routing.js 
 //      templates.js 
 //      orm.js 
 // 
 // This does not cross over to the browser as the browser does 
 // not have macros. 
 //
 load(__DIR__+'subdir/foo'); 

Remark: the __DIR__ macro is not necessary: the JS intepreter can as well do a chdir() to the directory of a script being loaded, effectively setting a new base path for consecutive relative includes.

Remark: I think chdir() is not a good option here because if one module does chdir to include other modules which also do chdir(), then chdir() is required before every individual "load". Otherwise the current directory is basically unknown to any particular script. -- Peter Michaux

sample code

// ==================================================================
// source code ------------------------------------------------------
 
//
// base.js
//
var LIB = {};

//
// math.js
//
require('base');
LIB.add = function() {
  var sum = arguments[0];
  for (var i=1; i<arguments.length; i++) {
    sum += arguments[i];
  }
  return sum;
};

//
// increment.js
//
require('base');
require('math');
LIB.increment = function(val) {
  return LIB.add(val, 1);
};

//
// program.js
//
require('increment');
var a = 1;
LIB.inc(a); // 2

// ==================================================================
// browser code in development

//
// *Can* manually include all dependencies like the following.
// Other more complex techniques for manual dependency resolution
// can be used.
//
<script type="text/javascript">require=function(){}</script>
<script src="/js/src/base.js" type="text/javascript"></script>
<script src="/js/src/math.js" type="text/javascript"></script>
<script src="/js/src/increment.js" type="text/javascript"></script>
<script src="/js/src/program.js" type="text/javascript"></script>

// ===================================================================
// browser code in production

//
// Can just concatenate the source files and perhaps minify them.
// Other more complex techniques can be used.
//
<script type="text/javascript">require=function(){}</script>
<script src="/js/lib.js" type="text/javascript"></script>
<script src="/js/program.js" type="text/javascript"></script>