8
0
Quellcode durchsuchen

Enhanced building tasks and utilities.

Aleksander Nowodzinski vor 9 Jahren
Ursprung
Commit
d27cbbbed0
4 geänderte Dateien mit 127 neuen und 63 gelöschten Zeilen
  1. 1 11
      dev/tasks/build/icons-template.js
  2. 38 24
      dev/tasks/build/tasks.js
  3. 49 27
      dev/tasks/build/utils.js
  4. 39 1
      dev/tests/build/utils.js

+ 1 - 11
dev/tasks/build/icons-template.js

@@ -5,14 +5,4 @@
 
 'use strict';
 
-export const sprite = `{{#shapes}}
-{{{svg}}}{{/shapes}}`;
-// var tmp = document.createElement( 'div' );
-
-// 	tmp.innerHTML =
-// 		'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="ck-sprite">' +
-// 			sprite +
-// 		'</svg>';
-
-// 	document.body.appendChild( tmp.firstChild );
-// } );
+export default `{{#shapes}}{{{svg}}}{{/shapes}}`;

+ 38 - 24
dev/tasks/build/tasks.js

@@ -8,10 +8,11 @@
 const path = require( 'path' );
 const gulp = require( 'gulp' );
 const merge = require( 'merge-stream' );
-const gulpMirror = require( 'gulp-mirror' );
+const mirror = require( 'gulp-mirror' );
 const gulpWatch = require( 'gulp-watch' );
 const gulpPlumber = require( 'gulp-plumber' );
 const gutil = require( 'gulp-util' );
+const filter = require( 'gulp-filter' );
 const utils = require( './utils' );
 const runSequence = require( 'run-sequence' );
 
@@ -19,6 +20,7 @@ module.exports = ( config ) => {
 	const buildDir = path.join( config.ROOT_DIR, config.BUILD_DIR );
 	const themesGlob = path.join( 'theme', '**', '*.scss' );
 	const iconsGlob = path.join( 'theme', 'icons', '*.svg' );
+	const parsedArguments = utils.parseArguments();
 
 	const tasks = {
 		clean: {
@@ -32,8 +34,11 @@ module.exports = ( config ) => {
 			/**
 			 * Removes all but "themes" folder from "./build/{format}" directory.
 			 */
-			js() {
-				return utils.clean( buildDir, path.join( `@(${ utils.parseArguments().formats.join( '|' ) })`, '!(theme)' ) );
+			js( options ) {
+				// TODO: ES6 default function parameters
+				options = options || utils.parseArguments();
+
+				return utils.clean( buildDir, path.join( `@(${ options.formats.join( '|' ) })`, '!(theme)' ) );
 			},
 
 			/**
@@ -203,7 +208,7 @@ module.exports = ( config ) => {
 				function createConversionStream() {
 					const formatPipes = options.formats.reduce( conversionStreamGenerator, [] );
 
-					return gulpMirror.apply( null, formatPipes )
+					return mirror.apply( null, formatPipes )
 						.on( 'error', onError );
 				}
 
@@ -242,8 +247,8 @@ module.exports = ( config ) => {
 			},
 
 			/**
-			 * The task capable of watching, processing and writing CSS files into
-			 * the `build/{format}/theme` directory.
+			 * The task capable of watching, processing and writing CSS files into `build/[formats]/theme`
+			 * directories.
 			 *
 			 * @param {Object} options
 			 * @param {String} options.formats
@@ -270,24 +275,24 @@ module.exports = ( config ) => {
 				}
 
 				function build() {
-					const dests = utils.getThemeDestsForFormats( buildDir, options.formats );
+					const formatStreams = utils.getThemeFormatDestStreams( buildDir, options.formats );
 
 					return tasks.src.sass()
 						.pipe( gulpPlumber() )
 						.pipe( utils.filterThemeEntryPoints() )
-						.pipe( utils.compileThemes( 'ckeditor.css' ) )
-						.pipe( gulpMirror( dests ) )
 						.pipe(
-							utils.noop( ( file ) => {
-								gutil.log( `Output file saved to '${ gutil.colors.cyan( file.path ) }'.` );
+							utils.noop( file => {
+								gutil.log( `Found theme entry point '${ gutil.colors.cyan( file.path ) }'.` );
 							} )
 						)
+						.pipe( utils.compileThemes( 'ckeditor.css' ) )
+						.pipe( mirror( formatStreams ) )
 						.on( 'error', console.log );
 				}
 			},
 
 			/**
-			 * The task capable of converting SVG files into `build/{format}/theme/icons.js`
+			 * The task capable of converting *.svg icon files into `./build/[formats]/theme/icons.js`
 			 * sprite.
 			 *
 			 * @param {Object} options
@@ -295,16 +300,18 @@ module.exports = ( config ) => {
 			 * @returns {Stream}
 			 */
 			icons( options ) {
-				const dests = utils.getThemeDestsForFormats( buildDir, options.formats );
+				const formatStreams = utils.getThemeFormatDestStreams( buildDir, options.formats, format => {
+					if ( format !== 'esnext' ) {
+						return utils.transpile( format, utils.getBabelOptionsForSource( format ) );
+					} else {
+						return utils.noop();
+					}
+				} );
 
 				return tasks.src.icons()
 					.pipe( utils.compileIconSprite() )
-					.pipe( gulpMirror( dests ) )
-					.pipe(
-						utils.noop( ( file ) => {
-							gutil.log( `Output file saved to '${ gutil.colors.cyan( file.path ) }'.` );
-						} )
-					);
+					.pipe( filter( '*.js' ) )
+					.pipe( mirror( formatStreams ) );
 			}
 		}
 	};
@@ -315,25 +322,32 @@ module.exports = ( config ) => {
 
 	gulp.task( 'build:clean:all', tasks.clean.all );
 	gulp.task( 'build:clean:themes', tasks.clean.themes );
-	gulp.task( 'build:clean:js', tasks.clean.js );
+	gulp.task( 'build:clean:js', () => {
+		return tasks.clean.js( parsedArguments );
+	} );
 
 	gulp.task( 'build:themes', ( callback ) => {
 		runSequence( 'build:clean:themes', 'build:icons', 'build:sass', callback );
 	} );
 
 	gulp.task( 'build:sass', () => {
-		return tasks.build.sass( utils.parseArguments() );
+		return tasks.build.sass( parsedArguments );
 	} );
 
 	gulp.task( 'build:icons', () => {
-		return tasks.build.icons( utils.parseArguments() );
+		return tasks.build.icons( parsedArguments );
 	} );
 
 	gulp.task( 'build:js', [ 'build:clean:js' ], () => {
-		return tasks.build.js( utils.parseArguments() );
+		return tasks.build.js( parsedArguments );
+	} );
+
+	// Tasks specific for `gulp docs` builder.
+	gulp.task( 'build:clean:js:esnext', () => {
+		return tasks.clean.js( { formats: [ 'esnext' ] } );
 	} );
 
-	gulp.task( 'build:js:esnext', [ 'build:clean:js' ], () => {
+	gulp.task( 'build:js:esnext', [ 'build:clean:js:esnext' ], () => {
 		return tasks.build.js( { formats: [ 'esnext' ] } );
 	} );
 

+ 49 - 27
dev/tasks/build/utils.js

@@ -20,6 +20,8 @@ const sass = require( 'node-sass' );
 const del = require( 'del' );
 const minimist = require( 'minimist' );
 const sprite = require( 'gulp-svg-sprite' );
+const pipe = require( 'multipipe' );
+const filter = require( 'gulp-filter' );
 
 const utils = {
 	/**
@@ -406,20 +408,12 @@ require( [ 'tests' ], bender.defer(), function( err ) {
 	},
 
 	/**
-	 * Given the input stream of .scss files, this method finds entry-point
-	 * files (theme.scss) and returns them as a stream.
+	 * Filters theme entry points only from a stream of SCSS files.
 	 *
 	 * @returns {Stream}
 	 */
 	filterThemeEntryPoints() {
-		return through.obj( function( file, enc, callback ) {
-			if ( file.path.match( /\/theme\.scss$/ ) ) {
-				gutil.log( `Found theme entry point '${ gutil.colors.cyan( file.path ) }'...` );
-				this.push( file );
-			}
-
-			callback();
-		} );
+		return filter( '**/theme.scss' );
 	},
 
 	/**
@@ -442,7 +436,7 @@ require( [ 'tests' ], bender.defer(), function( err ) {
 		}
 
 		function renderThemeFromEntryPoints( callback ) {
-			gutil.log( `Compiling theme from entry points into '${ gutil.colors.cyan( fileName ) }'...` );
+			gutil.log( `Compiling '${ gutil.colors.cyan( fileName ) }' from ${ gutil.colors.cyan( paths.length ) } entry points...` );
 
 			const dataToRender = paths.map( p => `@import '${ p }';` )
 				.join( '\n' );
@@ -465,6 +459,22 @@ require( [ 'tests' ], bender.defer(), function( err ) {
 	},
 
 	/**
+	 * Parses command line arguments and returns them as a user-friendly hash.
+	 *
+	 * @param {String} dataToRender
+	 * @returns {Object}
+	 */
+	getSassOptions( dataToRender ) {
+		return {
+			data: dataToRender,
+			sourceMap: true,
+			sourceMapEmbed: true,
+			outputStyle: 'expanded',
+			sourceComments: true
+		};
+	},
+
+	/**
 	 * Removes files and directories specified by `glob` starting from `rootDir`
 	 * and gently informs about deletion.
 	 *
@@ -509,25 +519,21 @@ require( [ 'tests' ], bender.defer(), function( err ) {
 	},
 
 	/**
-	 * Parses command line arguments and returns them as a user-friendly hash.
+	 * Given a stream of .svg files it returns a stream containing JavaScript
+	 * icon sprite file.
 	 *
-	 * @param {String} dataToRender
-	 * @returns {Object}
+	 * @returns {Stream}
 	 */
-	getSassOptions( dataToRender ) {
-		return {
-			data: dataToRender,
-			sourceMap: true,
-			sourceMapEmbed: true,
-			outputStyle: 'expanded',
-			sourceComments: true
-		};
-	},
-
 	compileIconSprite() {
 		return sprite( utils.getIconSpriteOptions() );
 	},
 
+	/**
+	 * Returns svg-sprite util options to generate <symbol>-based, JavaScript
+	 * sprite file.
+	 *
+	 * @returns {Object}
+	 */
 	getIconSpriteOptions() {
 		return {
 			shape: {
@@ -541,7 +547,7 @@ require( [ 'tests' ], bender.defer(), function( err ) {
 			},
 			mode: {
 				symbol: {
-					dest: '.', // Flatten symbol/
+					dest: './', // Flatten symbol/
 					inline: true,
 					render: {
 						js: {
@@ -554,9 +560,25 @@ require( [ 'tests' ], bender.defer(), function( err ) {
 		};
 	},
 
-	getThemeDestsForFormats( distDir, formats ) {
+	/**
+	 * Given a stream of files it returns an array of gulp-mirror streams outputting
+	 * files to `build/[formats]/theme/` directories for each of desired output formats (cjs, amd, etc.).
+	 *
+	 * @param {String} buildDir A path to /build directory.
+	 * @param {Array} formats An array of desired output formats.
+	 * @param {Function} [transformationStream] A stream used to transform files before they're saved to
+	 * desired `build/[formats]/theme` directories. Useful for transpilation.
+	 * @returns {Stream[]} An array of streams.
+	 */
+	getThemeFormatDestStreams( buildDir, formats, transformationStream ) {
 		return formats.map( f => {
-			return gulp.dest( path.join( distDir, f, 'theme' ) );
+			return pipe(
+				transformationStream ? transformationStream( f ) : utils.noop(),
+				gulp.dest( path.join( buildDir, f, 'theme' ) ),
+				utils.noop( ( file ) => {
+					gutil.log( `Output for ${ gutil.colors.cyan( f ) } is '${ gutil.colors.cyan( file.path ) }'.` );
+				} )
+			);
 		} );
 	}
 };

+ 39 - 1
dev/tests/build/utils.js

@@ -562,7 +562,7 @@ describe( 'build-utils', () => {
 	} );
 
 	describe( 'filterThemeEntryPoints', () => {
-		it( 'returns a stream containing theme entry points', ( done ) => {
+		it( 'returns a stream containing theme entry points only', ( done ) => {
 			const stream = require( 'stream' );
 			const entryPoints = [];
 
@@ -682,4 +682,42 @@ describe( 'build-utils', () => {
 			expect( options ).to.have.property( 'sourceComments', true );
 		} );
 	} );
+
+	describe( 'parseArguments', () => {
+		it( 'returns object with defaults', () => {
+			const args = utils.parseArguments();
+
+			expect( args.formats ).to.have.members( [ 'amd' ] );
+			expect( args.watch ).to.be.equal( false );
+		} );
+	} );
+
+	describe( 'getIconSpriteOptions', () => {
+		it( 'returns object with defaults', () => {
+			const options = utils.getIconSpriteOptions();
+
+			expect( options ).to.have.all.keys( [ 'shape', 'svg', 'mode' ] );
+		} );
+
+		it( 'returns icon ids generator out of svg file names', () => {
+			const options = utils.getIconSpriteOptions();
+
+			expect( options.shape.id.generator( 'foo.svg' ) ).to.equal( 'ck-icon-foo' );
+		} );
+
+		it( 'returns configuration to output JavaScript sprite', () => {
+			const options = utils.getIconSpriteOptions();
+
+			expect( options.mode.symbol.render.js.dest ).to.equal( 'icons.js' );
+		} );
+	} );
+
+	describe( 'getThemeFormatDestStreams', () => {
+		it( 'returns array of streams for each format', () => {
+			const streams = utils.getThemeFormatDestStreams( 'foo', [ 'a', 'b' ] );
+
+			expect( streams ).to.be.an( 'array' );
+			expect( streams ).to.have.length( 2 );
+		} );
+	} );
 } );