8
0

tasks.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. 'use strict';
  6. const fs = require( 'fs' );
  7. const path = require( 'path' );
  8. const gulp = require( 'gulp' );
  9. const gulpCssnano = require( 'gulp-cssnano' );
  10. const gulpUglify = require( 'gulp-uglify' );
  11. const gutil = require( 'gulp-util' );
  12. const runSequence = require( 'run-sequence' );
  13. const utils = require( './utils' );
  14. const rollup = require( 'rollup' ).rollup;
  15. const rollupBabel = require( 'rollup-plugin-babel' );
  16. const mkdirp = require( 'mkdirp' );
  17. const { tools } = require( 'ckeditor5-dev-utils' );
  18. module.exports = ( config ) => {
  19. const args = utils.parseArguments();
  20. const sourceBuildDir = path.join( config.ROOT_DIR, config.BUILD_DIR, 'esnext' );
  21. const bundleDir = path.join( config.ROOT_DIR, config.BUNDLE_DIR );
  22. const bundleTmpDir = path.join( bundleDir, 'tmp' );
  23. const temporaryEntryFilePath = path.join( bundleTmpDir, 'entryfile.js' );
  24. const tasks = {
  25. /**
  26. * Removes all files from bundle directory.
  27. */
  28. clean() {
  29. return tools.clean( bundleDir, '*.*' );
  30. },
  31. /**
  32. * Combines whole editor files into two files `ckeditor.js` and `ckeditor.css`.
  33. *
  34. * For JS bundle is required to pass configuration file `gulp bundle --config path/to/file.js` where
  35. * we need to specify which editor and features we want to include in our bundle.
  36. *
  37. * // example-config-file.js:
  38. *
  39. * module.exports = {
  40. * // Name of CKEditor instance exposed as global variable by a bundle.
  41. * moduleName: 'MyCKEditor',
  42. *
  43. * // Path to specified editor module.
  44. * // It could be a path relative to `build/esnext/ckeditor5` directory e.g. `editor-classic/classic`
  45. * // or path relative to directory where build task will be executed `./full/path/to/custom/editor`.
  46. * //
  47. * // Note: file extension is appended automatically.
  48. * editor: 'editor-classic/classic',
  49. *
  50. * // List of features.
  51. * //
  52. * // Note: file extension is appended automatically.
  53. * features: [
  54. * // It could be a plugin name only if plugin is a default CKEditor plugin.
  55. * 'delete',
  56. *
  57. * // It could be a path relative to `build/esnext/ckeditor5` directory.
  58. * `typing/typing`,
  59. *
  60. * // Or it could be a path relative to directory where build task will be executed.
  61. * './path/to/some/custom/feature',
  62. * ]
  63. * };
  64. *
  65. * ** Note: ** Entry file is a physically existing file because rollup requires it.
  66. *
  67. * @param {String} configFilePath Path to the bundle configuration file.
  68. * @returns {Promise} Promise that resolve bundling for CSS and JS.
  69. */
  70. generate( configFilePath ) {
  71. // When config file is not specified.
  72. if ( !configFilePath ) {
  73. // Then log error.
  74. gutil.log( gutil.colors.red( `Bundle Error: Path to the config file is required. 'gulp bundle --config path/to/file.js'` ) );
  75. // And stop task as failed.
  76. return Promise.reject();
  77. }
  78. // Get configuration from the configuration file.
  79. const config = require( path.resolve( '.', configFilePath ) );
  80. // Create a temporary entry file with proper directory structure if not exist.
  81. // Entry file can not be a stream because rollup requires physically existing file.
  82. mkdirp.sync( bundleTmpDir );
  83. fs.writeFileSync( temporaryEntryFilePath, utils.renderEntryFileContent( bundleTmpDir, config ) );
  84. // Bundling JS by Rollup.
  85. function bundleJS() {
  86. const outputFile = path.join( bundleDir, 'ckeditor.js' );
  87. return rollup( {
  88. entry: temporaryEntryFilePath,
  89. plugins: [
  90. rollupBabel( {
  91. presets: [ 'es2015-rollup' ]
  92. } )
  93. ]
  94. } )
  95. .then( ( bundle ) => {
  96. return bundle.write( {
  97. dest: outputFile,
  98. format: 'iife',
  99. moduleName: config.moduleName
  100. } );
  101. } )
  102. .then( () => {
  103. // If everything went well then remove tmp directory.
  104. tools.clean( bundleTmpDir, path.join( '' ) );
  105. } )
  106. .catch( ( err ) => {
  107. // If something went wrong then log error.
  108. gutil.log( gutil.colors.red( err.stack ) );
  109. // And remove tmp directory.
  110. tools.clean( bundleTmpDir, path.join( '' ) );
  111. throw new Error( 'Build error.' );
  112. } );
  113. }
  114. // CSS is already bundled by a build task, so we need only to copy it.
  115. function bundleCss() {
  116. const cssSource = path.join( sourceBuildDir, 'theme', 'ckeditor.css' );
  117. return utils.copyFile( cssSource, bundleDir );
  118. }
  119. // Lets wait for both - JS and CSS.
  120. return Promise.all( [ bundleJS(), bundleCss() ] );
  121. },
  122. minify: {
  123. /**
  124. * JS minification by UglifyJS.
  125. */
  126. js() {
  127. let stream = gulp.src( path.join( bundleDir, 'ckeditor.js' ) )
  128. .pipe( gulpUglify() );
  129. return utils.saveFileFromStreamAsMinified( stream, bundleDir );
  130. },
  131. /**
  132. * CSS minification by cssnano.
  133. */
  134. css() {
  135. let stream = gulp.src( path.join( bundleDir, 'ckeditor.css' ) )
  136. .pipe( gulpCssnano() );
  137. return utils.saveFileFromStreamAsMinified( stream, bundleDir );
  138. }
  139. },
  140. register() {
  141. gulp.task( 'bundle:clean', tasks.clean );
  142. gulp.task( 'bundle:generate',
  143. [
  144. 'bundle:clean',
  145. 'build:js:esnext',
  146. 'build:themes:esnext'
  147. ],
  148. () => tasks.generate( args.config )
  149. );
  150. gulp.task( 'bundle:minify:js', tasks.minify.js );
  151. gulp.task( 'bundle:minify:css', tasks.minify.css );
  152. gulp.task( 'bundle', ( callback ) => {
  153. runSequence( 'bundle:generate', [ 'bundle:minify:js', 'bundle:minify:css' ], () => {
  154. const files = [ 'ckeditor.js', 'ckeditor.css', 'ckeditor.min.js', 'ckeditor.min.css' ];
  155. const filesStats = utils.getFilesSizeStats( files, bundleDir );
  156. // Show bundle summary on console.
  157. utils.showFilesSummary( 'Bundle summary', filesStats );
  158. // Finish the task.
  159. callback();
  160. } );
  161. } );
  162. }
  163. };
  164. return tasks;
  165. };