builder.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* jshint node: true */
  6. 'use strict';
  7. var Builder;
  8. /**
  9. * A CKEditor 5 release builder.
  10. *
  11. * @class Builder
  12. */
  13. module.exports = Builder = function( target ) {
  14. /**
  15. * The target directory where to create the build.
  16. *
  17. * **Warning**: if existing, this directory will be deleted before processing.
  18. *
  19. * @type {string}
  20. */
  21. this.target = target || 'build';
  22. /**
  23. * The temporary directory to use for build processing.
  24. *
  25. * **Warning**: if existing, this directory will be deleted before processing.
  26. *
  27. * @type {string}
  28. */
  29. this.tmp = 'tmp';
  30. /**
  31. * The list of tasks to be executed by the `build()` method. Each entry is an Array containing the name of the
  32. * method inside `tasks` to execute and the message to show to the end user when executing it.
  33. *
  34. * @type {Array}
  35. */
  36. this.taskList = [
  37. [ 'cleanup', 'Cleaning the "' + target + '" directory...' ],
  38. [ 'copyToTmp', 'Copying source files for manipulation...' ],
  39. [ 'removeAmdNamespace', 'AMD cleanup...' ],
  40. [ 'optimize', 'Creating the optimized code...' ],
  41. [ 'cleanupTmp', 'Removing the "' + this.tmp + '" directory...' ]
  42. ];
  43. };
  44. Builder.prototype = {
  45. /**
  46. * Builds a CKEditor release based on the current development code.
  47. *
  48. * @param {Function} [callback] Function to be called when build finishes.
  49. */
  50. build: function( callback ) {
  51. var that = this;
  52. var stepCounter = 0;
  53. runNext();
  54. function runNext() {
  55. var next = that.taskList.shift();
  56. if ( next ) {
  57. stepCounter++;
  58. console.log( stepCounter + '. ' + next[ 1 ] );
  59. that.tasks[ next[ 0 ] ].call( that, runNext );
  60. } else {
  61. if ( callback ) {
  62. callback();
  63. }
  64. }
  65. }
  66. },
  67. /**
  68. * Holds individual methods for each task executed by the builder.
  69. *
  70. * All methods here MUST be called in the builder context by using
  71. * `builder.tasks.someMethod.call( builder, callback )`.
  72. */
  73. tasks: {
  74. /**
  75. * Deletes the `target` and `tmp` directories.
  76. *
  77. * @param {Function} callback Function to be called when the task is done.
  78. * @returns {Object} The callback returned valued.
  79. */
  80. cleanup: function( callback ) {
  81. var del = require( 'del' );
  82. del.sync( this.target );
  83. del.sync( this.tmp );
  84. return callback();
  85. },
  86. /**
  87. * Copy the local source code of CKEditor and its dependencies to the `tmp` directory for processing.
  88. *
  89. * @param {Function} callback Function to be called when the task is done.
  90. * @returns {Object} The callback returned valued.
  91. */
  92. copyToTmp: function( callback ) {
  93. var ncp = require( 'ncp' ).ncp;
  94. var path = require( 'path' );
  95. var fs = require( 'fs' );
  96. var tmp = this.tmp;
  97. var deps = require( '../../../package.json' ).dependencies;
  98. var toCopy = Object.keys( deps ).filter( function( name ) {
  99. return name.indexOf( 'ckeditor5-' ) === 0;
  100. } );
  101. if ( !fs.existsSync( tmp ) ) {
  102. fs.mkdirSync( tmp );
  103. }
  104. function copy() {
  105. var module = toCopy.shift();
  106. if ( !module ) {
  107. return callback();
  108. }
  109. var dest = path.join( tmp + '/', module );
  110. if ( !fs.existsSync( dest ) ) {
  111. fs.mkdirSync( dest );
  112. }
  113. // Copy the "src" directory only.
  114. ncp( path.join( 'node_modules', module, 'src' ), path.join( dest, 'src' ), {
  115. dereference: true
  116. }, function( err ) {
  117. if ( err ) {
  118. throw( err );
  119. }
  120. copy();
  121. } );
  122. }
  123. copy();
  124. },
  125. /**
  126. * Removes the `CKEDITOR` namespace from AMD calls in the `tmp` copy of the source code.
  127. *
  128. * @param {Function} callback Function to be called when the task is done.
  129. * @returns {Object} The callback returned valued.
  130. */
  131. removeAmdNamespace: function( callback ) {
  132. var replace = require( 'replace' );
  133. replace( {
  134. regex: /^\s*CKEDITOR\.(define|require)/mg,
  135. replacement: '$1',
  136. paths: [ this.tmp ],
  137. recursive: true,
  138. silent: true
  139. } );
  140. callback();
  141. },
  142. /**
  143. * Creates the optimized release version of `ckeditor.js` in the `target` directory out of the `tmp` copy of the
  144. * source code.
  145. *
  146. * @param {Function} callback Function to be called when the task is done.
  147. * @returns {Object} The callback returned valued.
  148. */
  149. optimize: function( callback ) {
  150. var requirejs = require( 'requirejs' );
  151. var config = {
  152. out: this.target + '/ckeditor.js',
  153. baseUrl: this.tmp + '/ckeditor5-core/src/',
  154. paths: {
  155. 'ckeditor': '../../../ckeditor',
  156. 'ckeditor-dev': '../../../src/ckeditor-dev',
  157. 'ckeditor-core': 'ckeditor'
  158. },
  159. include: [ 'ckeditor' ],
  160. stubModules: [ 'ckeditor-dev' ],
  161. // optimize: 'none',
  162. optimize: 'uglify2',
  163. preserveLicenseComments: false,
  164. wrap: {
  165. startFile: [ 'dev/tasks/build/start.frag', require.resolve( 'almond' ) ],
  166. endFile: 'dev/tasks/build/end.frag'
  167. }
  168. };
  169. requirejs.optimize( config, callback );
  170. },
  171. /**
  172. * Deletes `tmp` directory.
  173. *
  174. * @param {Function} callback Function to be called when the task is done.
  175. * @returns {Object} The callback returned valued.
  176. */
  177. cleanupTmp: function( callback ) {
  178. var del = require( 'del' );
  179. del.sync( this.tmp );
  180. return callback();
  181. }
  182. }
  183. };