Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bundling #193

Merged
merged 27 commits into from
Jul 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d8b6540
Added bundlign task.
oskarwrobel May 30, 2016
4f61a09
Removed babel plugin for rollup.
oskarwrobel May 31, 2016
70a8370
Added unit tests for bundle task.
oskarwrobel May 31, 2016
9a2f889
Adjusted bundling to new creators.
oskarwrobel Jun 1, 2016
e204705
Merge branch 'master' of https://github.com/ckeditor/ckeditor5 into t…
oskarwrobel Jun 1, 2016
988301f
Fixed typo, updated comment.
oskarwrobel Jun 2, 2016
06a62d9
Merge branch 'master' of https://github.com/ckeditor/ckeditor5 into t…
oskarwrobel Jun 3, 2016
39c660e
Replaced filesize with pretty-bytes.
oskarwrobel Jun 3, 2016
04894e8
Merge branch 'master' into t/187
oskarwrobel Jun 3, 2016
16c133b
Added gzipped size to bundle summary.
oskarwrobel Jun 6, 2016
a2de0ed
Merge branch 'master' into t/187
oskarwrobel Jun 29, 2016
74a49a5
Updated rollup.
oskarwrobel Jun 29, 2016
ac89105
Changed the way of generating bundle - from static hard coded entry f…
oskarwrobel Jul 4, 2016
aadf375
Added tmp directory to .gitignore.
oskarwrobel Jul 4, 2016
2c40681
Added posiibility to pass only plugin name instead of whole path to b…
oskarwrobel Jul 5, 2016
ffaa295
Updated docs.
oskarwrobel Jul 5, 2016
d941fcc
Refactored bundling tasks.
oskarwrobel Jul 5, 2016
f6bf398
Removed unnecessary definition from gitignore.
oskarwrobel Jul 5, 2016
2c25569
Removed bundle config file.
oskarwrobel Jul 5, 2016
eae2c6b
Updated docs.
oskarwrobel Jul 7, 2016
f9c69ef
Fixed typo.
oskarwrobel Jul 7, 2016
4149e88
Merge branch 'master' into t/187
Reinmar Jul 7, 2016
f9817dd
Minor API doc fixes.
Reinmar Jul 7, 2016
9494de6
Let's not require the extension, to align the config format to what P…
Reinmar Jul 7, 2016
614e9ca
Concretized method name.
Reinmar Jul 7, 2016
e070bcb
Make sure to fail early.
Reinmar Jul 7, 2016
91d8e17
Fixed documentation.
Reinmar Jul 7, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@

node_modules/**
build/**
bundle/**
coverage/**
dist/**
2 changes: 1 addition & 1 deletion dev/tasks/build/iconmanagermodel.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

'use strict';

import Model from '/ckeditor5/ui/model.js';
import Model from '../ckeditor5/ui/model.js';

const iconIds = [ {{#shapes}}'{{name}}',{{/shapes}} ];
const iconPrefix = 'ck-icon-';
Expand Down
17 changes: 14 additions & 3 deletions dev/tasks/build/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ module.exports = ( config ) => {
clean: {
/**
* Removes "themes" folder from "./build/{format}" directory.
*
* @param {Object} options
* @param {String} options.formats
*/
themes() {
return utils.clean( buildDir, path.join( `@(${ utils.parseArguments().formats.join( '|' ) })`, 'theme' ) );
themes( options = {} ) {
let formats = options.formats || args.formats;

return utils.clean( buildDir, path.join( `@(${ formats.join( '|' ) })`, 'theme' ) );
},

/**
Expand Down Expand Up @@ -332,9 +337,15 @@ module.exports = ( config ) => {
gulp.task( 'build:icons', () => tasks.build.icons( args ) );
gulp.task( 'build:js', [ 'build:clean:js' ], () => tasks.build.js( args ) );

// Tasks specific for `gulp docs` builder.
// Tasks specific for preparing build with unmodified source files. Uses by `gulp docs` or `gulp bundle`.
gulp.task( 'build:clean:js:esnext', () => tasks.clean.js( { formats: [ 'esnext' ] } ) );
gulp.task( 'build:clean:themes:esnext', () => tasks.clean.themes( { formats: [ 'esnext' ] } ) );
gulp.task( 'build:sass:esnext', () => tasks.build.sass( { formats: [ 'esnext' ] } ) );
gulp.task( 'build:icons:esnext', () => tasks.build.icons( { formats: [ 'esnext' ] } ) );
gulp.task( 'build:js:esnext', [ 'build:clean:js:esnext' ], () => tasks.build.js( { formats: [ 'esnext' ] } ) );
gulp.task( 'build:themes:esnext', ( callback ) => {
runSequence( 'build:clean:themes:esnext', 'build:icons:esnext', 'build:sass:esnext', callback );
} );

// Tasks specific for testing under node.
gulp.task( 'build:clean:js:cjs', () => tasks.clean.js( { formats: [ 'cjs' ] } ) );
Expand Down
23 changes: 4 additions & 19 deletions dev/tasks/build/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ const PassThrough = require( 'stream' ).PassThrough;
const through = require( 'through2' );
const fs = require( 'fs' );
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 mainUtils = require( '../utils' );

const utils = {
/**
Expand Down Expand Up @@ -135,7 +135,7 @@ require( [ 'tests' ], bender.defer(), function( err ) {
*/
transpile( format, options ) {
return gulpBabel( options )
.on( 'error', function( err ) {
.on( 'error', ( err ) => {
gutil.log( gutil.colors.red( `Error (Babel:${ format })` ) );
gutil.log( gutil.colors.red( err.message ) );
console.log( '\n' + err.codeFrame + '\n' );
Expand Down Expand Up @@ -489,22 +489,6 @@ require( [ 'tests' ], bender.defer(), function( err ) {
};
},

/**
* Removes files and directories specified by `glob` starting from `rootDir`
* and gently informs about deletion.
*
* @param {String} rootDir The path to the root directory (i.e. "dist/").
* @param {String} glob Glob specifying what to clean.
* @returns {Promise}
*/
clean( rootDir, glob ) {
return del( path.join( rootDir, glob ) ).then( paths => {
paths.forEach( p => {
gutil.log( `Deleted file '${ gutil.colors.cyan( p ) }'.` );
} );
} );
},

/**
* Parses command line arguments and returns them as a user-friendly hash.
*
Expand Down Expand Up @@ -628,4 +612,5 @@ require( [ 'tests' ], bender.defer(), function( err ) {
}
};

module.exports = utils;
// Extend top level utils.
module.exports = Object.assign( utils, mainUtils );
185 changes: 185 additions & 0 deletions dev/tasks/bundle/tasks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/**
* @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

'use strict';

const fs = require( 'fs' );
const path = require( 'path' );
const gulp = require( 'gulp' );
const gulpCssnano = require( 'gulp-cssnano' );
const gulpUglify = require( 'gulp-uglify' );
const gutil = require( 'gulp-util' );
const runSequence = require( 'run-sequence' );
const utils = require( './utils' );
const rollup = require( 'rollup' ).rollup;
const rollupBabel = require( 'rollup-plugin-babel' );
const mkdirp = require( 'mkdirp' );

module.exports = ( config ) => {
const args = utils.parseArguments();
const sourceBuildDir = path.join( config.ROOT_DIR, config.BUILD_DIR, 'esnext' );
const bundleDir = path.join( config.ROOT_DIR, config.BUNDLE_DIR );
const bundleTmpDir = path.join( bundleDir, 'tmp' );
const temporaryEntryFilePath = path.join( bundleTmpDir, 'entryfile.js' );

const tasks = {
/**
* Removes all files from bundle directory.
*/
clean() {
return utils.clean( bundleDir, '*.*' );
},

/**
* Combines whole editor files into two files `ckeditor.js` and `ckeditor.css`.
*
* For JS bundle is required to pass configuration file `gulp bundle --config path/to/file.js` where
* we need to specify which editor and features we want to include in our bundle.
*
* // example-config-file.js:
*
* module.exports = {
* // Name of CKEditor instance exposed as global variable by a bundle.
* moduleName: 'MyCKEditor',
*
* // Path to specified editor module.
* // It could be a path relative to `build/esnext/ckeditor5` directory e.g. `editor-classic/classic`
* // or path relative to directory where build task will be executed `./full/path/to/custom/editor`.
* //
* // Note: file extension is appended automatically.
* editor: 'editor-classic/classic',
*
* // List of features.
* //
* // Note: file extension is appended automatically.
* features: [
* // It could be a plugin name only if plugin is a default CKEditor plugin.
* 'delete',
*
* // It could be a path relative to `build/esnext/ckeditor5` directory.
* `typing/typing`,
*
* // Or it could be a path relative to directory where build task will be executed.
* './path/to/some/custom/feature',
* ]
* };
*
* @param {String} configFilePath Path to the bundle configuration file.
* @returns {Promise} Promise that resolve bundling for CSS and JS.
*/
generate( configFilePath ) {
// When config file is not specified.
if ( !configFilePath ) {
// Then log error.
gutil.log( gutil.colors.red( `Bundle Error: Path to the config file is required. 'gulp bundle --config path/to/file.js'` ) );

// And stop task as failed.
return Promise.reject();
}

// Get configuration from the configuration file.
const config = require( path.resolve( '.', configFilePath ) );

// Create a temporary entry file with proper directory structure if not exist.
mkdirp.sync( bundleTmpDir );
fs.writeFileSync( temporaryEntryFilePath, utils.renderEntryFileContent( bundleTmpDir, config ) );

// Bundling JS by Rollup.
function bundleJS() {
const outputFile = path.join( bundleDir, 'ckeditor.js' );

return rollup( {
entry: temporaryEntryFilePath,
plugins: [
rollupBabel( {
presets: [ 'es2015-rollup' ]
} )
]
} )
.then( ( bundle ) => {
return bundle.write( {
dest: outputFile,
format: 'iife',
moduleName: config.moduleName
} );
} )
.then( () => {
// If everything went well then remove tmp directory.
utils.clean( bundleTmpDir, path.join( '' ) );
} )
.catch( ( err ) => {
// If something went wrong then log error.
gutil.log( gutil.colors.red( err.stack ) );

// And remove tmp directory.
utils.clean( bundleTmpDir, path.join( '' ) );

throw new Error( 'Build error.' );
} );
}

// CSS is already bundled by a build task, so we need only to copy it.
function bundleCss() {
const cssSource = path.join( sourceBuildDir, 'theme', 'ckeditor.css' );

return utils.copyFile( cssSource, bundleDir );
}

// Lets wait for both - JS and CSS.
return Promise.all( [ bundleJS(), bundleCss() ] );
},

minify: {
/**
* JS minification by UglifyJS.
*/
js() {
let stream = gulp.src( path.join( bundleDir, 'ckeditor.js' ) )
.pipe( gulpUglify() );

return utils.saveFileFromStreamAsMinified( stream, bundleDir );
},

/**
* CSS minification by cssnano.
*/
css() {
let stream = gulp.src( path.join( bundleDir, 'ckeditor.css' ) )
.pipe( gulpCssnano() );

return utils.saveFileFromStreamAsMinified( stream, bundleDir );
}
},

register() {
gulp.task( 'bundle:clean', tasks.clean );
gulp.task( 'bundle:generate',
[
'bundle:clean',
'build:js:esnext',
'build:themes:esnext'
],
() => tasks.generate( args.config )
);
gulp.task( 'bundle:minify:js', tasks.minify.js );
gulp.task( 'bundle:minify:css', tasks.minify.css );

gulp.task( 'bundle', ( callback ) => {
runSequence( 'bundle:generate', [ 'bundle:minify:js', 'bundle:minify:css' ], () => {
const files = [ 'ckeditor.js', 'ckeditor.css', 'ckeditor.min.js', 'ckeditor.min.css' ];
const filesStats = utils.getFilesSizeStats( files, bundleDir );

// Show bundle summary on console.
utils.showFilesSummary( 'Bundle summary', filesStats );

// Finish the task.
callback();
} );
} );
}
};

return tasks;
};
Loading