build.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /**
  2. * Module dependencies.
  3. */
  4. var fs = require('fs')
  5. , package = JSON.parse(fs.readFileSync(__dirname+ '/../package.json'))
  6. , uglify = require('uglify-js');
  7. /**
  8. * License headers.
  9. *
  10. * @api private
  11. */
  12. var template = '/*! peerjs.%ext% build:' + package.version + ', %type%. Copyright(c) 2013 Michelle Bu <michelle@michellebu.com> */'
  13. , prefix = '\n(function(exports){\n'
  14. , development = template.replace('%type%', 'development').replace('%ext%', 'js')
  15. , production = template.replace('%type%', 'production').replace('%ext%', 'min.js')
  16. , suffix = '\n})(this);\n';
  17. /**
  18. * If statements, these allows you to create serveride & client side compatible
  19. * code using specially designed `if` statements that remove serverside
  20. * designed code from the source files
  21. *
  22. * @api private
  23. */
  24. var starttagIF = '// if node'
  25. , endtagIF = '// end node';
  26. /**
  27. * The modules that are required to create a base build of BinaryJS client.
  28. *
  29. * @const
  30. * @type {Array}
  31. * @api private
  32. */
  33. var base = [
  34. '../deps/js-binarypack/lib/bufferbuilder.js'
  35. , '../deps/js-binarypack/lib/binarypack.js'
  36. , '../deps/EventEmitter/EventEmitter.js'
  37. , '../deps/reliable/lib/reliable.js'
  38. , 'adapter.js'
  39. , 'util.js'
  40. , 'peer.js'
  41. , 'dataconnection.js'
  42. , 'mediaconnection.js'
  43. , 'negotiator.js'
  44. , 'socket.js'
  45. ];
  46. /**
  47. * @param {Array} transports The transports that needs to be bundled.
  48. * @param {Object} [options] Options to configure the building process.
  49. * @param {Function} callback Last argument should always be the callback
  50. * @callback {String|Boolean} err An optional argument, if it exists than an error
  51. * occurred during the build process.
  52. * @callback {String} result The result of the build process.
  53. * @api public
  54. */
  55. var builder = module.exports = function () {
  56. var options, callback, error = null
  57. , args = Array.prototype.slice.call(arguments, 0)
  58. , settings = {
  59. minify: true
  60. , node: false
  61. , custom: []
  62. };
  63. // Fancy pancy argument support this makes any pattern possible mainly
  64. // because we require only one of each type
  65. args.forEach(function (arg) {
  66. var type = Object.prototype.toString.call(arg)
  67. .replace(/\[object\s(\w+)\]/gi , '$1' ).toLowerCase();
  68. switch (type) {
  69. case 'object':
  70. return options = arg;
  71. case 'function':
  72. return callback = arg;
  73. }
  74. });
  75. // Add defaults
  76. options = options || {};
  77. // Merge the data
  78. for(var option in options) {
  79. settings[option] = options[option];
  80. }
  81. var files = [];
  82. base.forEach(function (file) {
  83. files.push(__dirname + '/../lib/' + file);
  84. });
  85. var results = {};
  86. files.forEach(function (file) {
  87. fs.readFile(file, function (err, content) {
  88. if (err) error = err;
  89. results[file] = content;
  90. // check if we are done yet, or not.. Just by checking the size of the result
  91. // object.
  92. if (Object.keys(results).length !== files.length) return;
  93. // concatinate the file contents in order
  94. var code = development
  95. , ignore = 0;
  96. code += prefix;
  97. files.forEach(function (file) {
  98. code += results[file];
  99. });
  100. // check if we need to add custom code
  101. if (settings.custom.length) {
  102. settings.custom.forEach(function (content) {
  103. code += content;
  104. });
  105. }
  106. if (!settings.node) {
  107. code = code.split('\n').filter(function (line) {
  108. // check if there are tags in here
  109. var start = line.indexOf(starttagIF) >= 0
  110. , end = line.indexOf(endtagIF) >= 0
  111. , ret = ignore;
  112. // ignore the current line
  113. if (start) {
  114. ignore++;
  115. ret = ignore;
  116. }
  117. // stop ignoring the next line
  118. if (end) {
  119. ignore--;
  120. }
  121. return ret == 0;
  122. }).join('\n');
  123. }
  124. code += suffix;
  125. // check if we need to process it any further
  126. if (settings.minify) {
  127. var ast = uglify.parser.parse(code);
  128. ast = uglify.uglify.ast_mangle(ast);
  129. ast = uglify.uglify.ast_squeeze(ast);
  130. code = production + uglify.uglify.gen_code(ast, { ascii_only: true });
  131. }
  132. callback(error, code);
  133. })
  134. })
  135. };
  136. /**
  137. * @type {String}
  138. * @api public
  139. */
  140. builder.version = package.version;
  141. /**
  142. * Command line support, this allows us to generate builds without having
  143. * to load it as module.
  144. */
  145. if (!module.parent){
  146. // the first 2 are `node` and the path to this file, we don't need them
  147. var args = process.argv.slice(2);
  148. // build a development build
  149. builder(args.length ? args : false, { minify:false }, function (err, content) {
  150. if (err) return console.error(err);
  151. console.log(__dirname);
  152. fs.write(
  153. fs.openSync(__dirname + '/../dist/peer.js', 'w')
  154. , content
  155. , 0
  156. , 'utf8'
  157. );
  158. console.log('Successfully generated the development build: peer.js');
  159. });
  160. // and build a production build
  161. builder(args.length ? args : false, function (err, content) {
  162. if (err) return console.error(err);
  163. fs.write(
  164. fs.openSync(__dirname + '/../dist/peer.min.js', 'w')
  165. , content
  166. , 0
  167. , 'utf8'
  168. );
  169. console.log('Successfully generated the production build: peer.min.js');
  170. });
  171. }