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

T/131: Introduce CKEditor 5 builds #132

Merged
merged 30 commits into from
Apr 3, 2017
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
84640ff
Feature: Introduced a script which creates an entry file for bundler.
Mar 16, 2017
a3a3084
Tests: Initial tests for bundler functions.
Mar 16, 2017
597a041
Feature: Introduced utils for generating an entry file into "ckeditor…
Mar 16, 2017
675ad25
Initial commit for "@ckeditor/ckeditor5-dev-bundler-webpack".
Mar 16, 2017
5dde142
Tests: Added tests for function which create an entry file.
Mar 17, 2017
cb4b621
Tests: Added tests for ckeditor5-dev-bundler-webpack.
Mar 17, 2017
6747044
Merged 'dev-bundler-webpack' into 'dev-webpack-plugin' and renamed as…
Mar 20, 2017
4eea8b2
Fixed indent in generated list of plugins in an entry file.
Mar 21, 2017
63aa8ec
Fixed failed test.
Mar 21, 2017
9cb6ec6
Docs: Added documentation to new functions.
Mar 22, 2017
878724b
Webpack - used preset "env" instead of "es2015".
Mar 22, 2017
ac8e956
Merge branch 'master' into t/131
Mar 22, 2017
d80bdae
Fixed invalid UMD build.
Mar 22, 2017
b41bae4
Revert: 'Webpack - used preset "env" instead of "es2015".' File: pack…
Mar 22, 2017
0fa69c4
Renamed configuration files.
Mar 22, 2017
6ea012c
Fixed invalid names of functions exported by the main file in package…
Mar 22, 2017
20d1ea2
Seperated Webpack plugin and Webpack utils.
Mar 27, 2017
a7f1958
Tests: Fixed hardcoded year in the tests.
Mar 27, 2017
8c7249f
Revert: 'Merged "dev-bundler-webpack" into "dev-webpack-plugin" and r…
Mar 27, 2017
56761b4
Webpack-utils: fixed invalid name exported by compat config.
Mar 27, 2017
b1639a5
Removed "getEditorConfig" function. Instead of it, "createEntryFile" …
Mar 27, 2017
afe979d
PA pth to an external editor configuration is now a parameter instead…
Mar 27, 2017
71fcb86
Merge branch 'master' into t/131
Reinmar Mar 30, 2017
fcdff80
Removed compiler utils (not used for a long time, but let's clean thi…
Reinmar Mar 30, 2017
3a929bc
Various minor fixes.
Reinmar Mar 30, 2017
ad97550
Fixed filenames in webpack-plugin.
Reinmar Mar 30, 2017
a695ac5
Fixed license banners – the comments:false used previously had no eff…
Reinmar Mar 31, 2017
5535ac0
Remove cwd option and module resolution setting – let's use the defau…
Reinmar Apr 3, 2017
5da0437
Added info about the new package to the main readme.
Reinmar Apr 3, 2017
90e1459
Moved configs to the build repos.
Reinmar Apr 3, 2017
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
16 changes: 8 additions & 8 deletions packages/ckeditor5-dev-bundler-rollup/lib/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
'use strict';

const rollup = require( 'rollup' );
const { tools } = require( '@ckeditor/ckeditor5-dev-utils' );
const { tools, bundler } = require( '@ckeditor/ckeditor5-dev-utils' );
const fs = require( 'fs' );
const gulp = require( 'gulp' );
const gulpCssnano = require( 'gulp-cssnano' );
Expand Down Expand Up @@ -180,21 +180,21 @@ const tasks = {
* @param {Object}
* @param {String} destiationPath
* @param {String} moduleName Module name of CKEditor instance exposed as global variable by a bundle.
* @param {String} sourceBuildDir Temporary directory.
* @param {String} editor
* @param {Array.<String>} plugins
*/
_saveLocallyTemporaryEntryFile( { destinationPath, moduleName, sourceBuildDir, editor, plugins } ) {
_saveLocallyTemporaryEntryFile( { destinationPath, moduleName, editor, plugins } ) {
mkdirp.sync( destinationPath );

const bundleTmpDir = fs.mkdtempSync( destinationPath + path.sep );
// Entry file can not be a stream because rollup requires physically existing file.
const temporaryEntryFilePath = path.join( bundleTmpDir, 'entryfile.js' );
fs.writeFileSync( temporaryEntryFilePath, utils.renderEntryFileContent(
bundleTmpDir,
{ moduleName, editor, plugins },
sourceBuildDir
) );

bundler.createEntryFile( temporaryEntryFilePath, {
moduleName,
editor,
plugins
} );

return { temporaryEntryFilePath, bundleTmpDir };
},
Expand Down
112 changes: 0 additions & 112 deletions packages/ckeditor5-dev-bundler-rollup/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,50 +36,6 @@ const utils = {
return options;
},

/**
* When module path is not relative then treat this path as a path to the one of the ckeditor5 default module
* (relative to ./bundle/exnext/ckeditor5) and add prefix `./build/esnext/ckeditor5/` to this path.
*
* This method also adds `.js` extension.
*
* @param {String} modulePath Path to the module (without extension).
* @param {String} buildDir Path to directory where build files are stored.
*/
getModuleFullPath( modulePath, buildDir ) {
// If path is not a relative path (no leading ./ or ../).
if ( modulePath.charAt( 0 ) != '.' ) {
return `${ path.join( buildDir, 'ckeditor5', modulePath ) }.js`;
}

return modulePath + '.js';
},

/**
* Resolves a simplified plugin name to a real path if only name is passed.
* E.g. 'delete' will be transformed to './build/esnext/ckeditor5/delete/delete.js'.
*
* @param {String} name
* @param {String} buildDir Path to directory where build files are stored.
* @returns {String} Path to the module.
*/
getPluginPath( name, buildDir ) {
if ( name.indexOf( '/' ) >= 0 ) {
return utils.getModuleFullPath( name, buildDir );
}

return utils.getModuleFullPath( `${ name }/${ name }`, buildDir );
},

/**
* Transforms first letter of passed string to the uppercase.
*
* @param {String} string String that will be transformed.
* @returns {String} Transformed string.
*/
capitalize( string ) {
return string.charAt( 0 ).toUpperCase() + string.slice( 1 );
},

/**
* Clean directory if the path to directory is provided
*
Expand All @@ -103,74 +59,6 @@ const utils = {
return tools.clean( destinationPath, `${fileName}.*` );
},

/**
* Renders content for the entry file which needs to be passed as main file to the Rollup.
*
* @param {String} dir Path to the entryfile directory. Import paths need to be relative to this directory.
* @param {Object} data Configuration object.
* @param {String} [data.moduleName] Name of the editor class exposed as global variable by bundle. e.g. MyCKEditor.
* @param {String} [data.editor] Path to the editor type e.g. `classic-editor/classic.js`.
* @param {Array.<String>} [data.plugins] List of paths or names to plugins which need to be included in bundle.
* @param {String} buildDir Path to directory where build files are stored.
* @returns {String} Entry file content.
*/
renderEntryFileContent( dir, data, buildDir ) {
const creatorName = utils.capitalize( path.basename( data.editor, '.js' ) );
const creatorPath = path.relative( dir, utils.getModuleFullPath( data.editor, buildDir ) );
let pluginNames = [];

// Returns a list of plugin imports.
function renderPluginImports( plugins = [] ) {
let templateFragment = '';

for ( let plugin of plugins ) {
plugin = utils.getPluginPath( plugin, buildDir );

const pluginPath = path.relative( dir, plugin );

// Generate unique plugin name.
// In case of two ore more plugins will have the same name:
// plugins: [
// 'typing',
// 'path/to/other/plugin/typing'
// ]
let pluginName = utils.capitalize( path.basename( plugin, '.js' ) );
let i = 0;

while ( pluginNames.indexOf( pluginName ) >= 0 ) {
pluginName = utils.capitalize( path.basename( plugin, `.js` ) ) + ( ++i ).toString();
}

templateFragment += `import ${ pluginName } from '${ pluginPath }';\n`;
pluginNames.push( pluginName );
}

return templateFragment;
}

return `
'use strict';

// Babel helpers.
import '${ path.relative( dir, 'node_modules/regenerator-runtime/runtime.js' ) }';

import ${ creatorName } from '${ creatorPath }';
${ renderPluginImports( data.plugins ) }

export default class ${ data.moduleName } extends ${ creatorName } {
static create( element, config = {} ) {
if ( !config.plugins ) {
config.plugins = [];
}

config.plugins = [ ...config.plugins, ${ pluginNames.join( ', ' ) } ];

return ${ creatorName }.create( element, config );
}
}
`;
},

/**
* Saves files from stream in specific destination and add `.min` suffix to the name.
*
Expand Down
18 changes: 9 additions & 9 deletions packages/ckeditor5-dev-bundler-rollup/tests/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const chai = require( 'chai' );
const expect = chai.expect;
const sinon = require( 'sinon' );
const path = require( 'path' );
const { tools } = require( '@ckeditor/ckeditor5-dev-utils' );
const { tools, bundler } = require( '@ckeditor/ckeditor5-dev-utils' );
const compiler = require( '@ckeditor/ckeditor5-dev-compiler' );
const utils = require( '../lib/utils' );
const mockery = require( 'mockery' );
Expand Down Expand Up @@ -157,10 +157,9 @@ describe( 'bundle-tasks', () => {
it( 'should create temporary file with given name', () => {
sandbox.stub( mkdirp, 'sync' );
sandbox.stub( fs, 'mkdtempSync', path => path + 'temp' );
const writeFileStub = sandbox.stub( fs, 'writeFileSync' );
sandbox.stub( utils, 'renderEntryFileContent' );
sandbox.stub( path, 'join', ( x, y ) => x + '/' + y );
sandbox.stub( path, 'sep', '/' );
const createEntryFileStub = sandbox.stub( bundler, 'createEntryFile' );

const result = tasks._saveLocallyTemporaryEntryFile( {
destinationPath: 'destinationPath',
Expand All @@ -170,14 +169,15 @@ describe( 'bundle-tasks', () => {
plugins: [ 'plugin1' ],
} );

expect( writeFileStub.called ).to.be.eq( true );
sinon.assert.calledWithExactly(
writeFileStub,
'destinationPath/temp/entryfile.js', undefined
);

expect( result.temporaryEntryFilePath ).to.deep.eq( 'destinationPath/temp/entryfile.js' );
expect( result.bundleTmpDir ).to.deep.eq( 'destinationPath/temp' );
expect( createEntryFileStub.calledOnce ).to.equal( true );
expect( createEntryFileStub.firstCall.args[ 0 ] ).to.equal( 'destinationPath/temp/entryfile.js' );
expect( createEntryFileStub.firstCall.args[ 1 ] ).to.deep.equal( {
moduleName: 'moduleName',
editor: 'editor',
plugins: [ 'plugin1' ]
} );
} );
} );

Expand Down
147 changes: 0 additions & 147 deletions packages/ckeditor5-dev-bundler-rollup/tests/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,42 +27,6 @@ describe( 'bundle-utils', () => {
sandbox.restore();
} );

describe( 'getModuleFullPath', () => {
it( 'should return full path when passed path not relative', () => {
expect( utils.getModuleFullPath( 'editor-classic/classic', 'path/to/build' ) )
.to.equal( 'path/to/build/ckeditor5/editor-classic/classic.js' );
} );

it( 'should return unmodified path when passed path is a relative', () => {
expect( utils.getModuleFullPath( './path/to/editor-classic/classic' ) ).to.equal( './path/to/editor-classic/classic.js' );
expect( utils.getModuleFullPath( '../path/to/editor-classic/classic' ) ).to.equal( '../path/to/editor-classic/classic.js' );
} );
} );

describe( 'getPluginPath()', () => {
it( 'should resolve a simple plugin name to the full path', () => {
expect( utils.getPluginPath( 'typing', 'path/to/build' ) )
.to.equal( 'path/to/build/ckeditor5/typing/typing.js' );
} );

it( 'should return full path if passed argument is a relative path', () => {
expect( utils.getPluginPath( 'typing/typing', 'path/to/build' ) )
.to.equal( 'path/to/build/ckeditor5/typing/typing.js' );
} );

it( 'should return unmodified plugin path if passed argument is a relative path', () => {
expect( utils.getPluginPath( './typing' ) ).to.equal( './typing.js' );
expect( utils.getPluginPath( '../typing' ) ).to.equal( '../typing.js' );
} );
} );

describe( 'capitalize()', () => {
it( 'should transform first letter of the passed string to uppercase', () => {
expect( utils.capitalize( 'string' ) ).to.equal( 'String' );
expect( utils.capitalize( 'multi word string' ) ).to.equal( 'Multi word string' );
} );
} );

describe( 'maybeCleanDir()', () => {
it( 'should clean directory if dir is provided', () => {
const cleanStub = sandbox.stub( tools, 'clean', () => Promise.resolve() );
Expand Down Expand Up @@ -98,117 +62,6 @@ describe( 'bundle-utils', () => {
} );
} );

describe( 'renderEntryFileContent()', () => {
it( 'should render file content with proper data', () => {
const result = utils.renderEntryFileContent( './bundle/tmp', {
moduleName: 'MyCKEditor',
editor: 'editor-classic/classic',
plugins: [
'delete',
'path/to/default',
'./path/to/custom'
]
}, 'path/to/build' );

const expected = `
'use strict';

// Babel helpers.
import '../../node_modules/regenerator-runtime/runtime.js';

import Classic from '../../path/to/build/ckeditor5/editor-classic/classic.js';
import Delete from '../../path/to/build/ckeditor5/delete/delete.js';
import Default from '../../path/to/build/ckeditor5/path/to/default.js';
import Custom from '../../path/to/custom.js';


export default class MyCKEditor extends Classic {
static create( element, config = {} ) {
if ( !config.plugins ) {
config.plugins = [];
}

config.plugins = [ ...config.plugins, Delete, Default, Custom ];

return Classic.create( element, config );
}
}
`;

expect( result ).to.equal( expected );
} );

it( 'should render file content with unique plugin names', () => {
const result = utils.renderEntryFileContent( './bundle/tmp', {
moduleName: 'MyCKEditor',
editor: 'editor-classic/classic',
plugins: [
'plugin',
'path/to/plugin',
'other/path/to/plugin'
]
}, 'path/to/build' );

const expected = `
'use strict';

// Babel helpers.
import '../../node_modules/regenerator-runtime/runtime.js';

import Classic from '../../path/to/build/ckeditor5/editor-classic/classic.js';
import Plugin from '../../path/to/build/ckeditor5/plugin/plugin.js';
import Plugin1 from '../../path/to/build/ckeditor5/path/to/plugin.js';
import Plugin2 from '../../path/to/build/ckeditor5/other/path/to/plugin.js';


export default class MyCKEditor extends Classic {
static create( element, config = {} ) {
if ( !config.plugins ) {
config.plugins = [];
}

config.plugins = [ ...config.plugins, Plugin, Plugin1, Plugin2 ];

return Classic.create( element, config );
}
}
`;

expect( result ).to.equal( expected );
} );

it( 'should render file content with proper without plugins', () => {
const result = utils.renderEntryFileContent( './bundle/tmp', {
moduleName: 'MyCKEditor',
editor: 'editor-classic/classic'
}, 'path/to/build' );

const expected = `
'use strict';

// Babel helpers.
import '../../node_modules/regenerator-runtime/runtime.js';

import Classic from '../../path/to/build/ckeditor5/editor-classic/classic.js';


export default class MyCKEditor extends Classic {
static create( element, config = {} ) {
if ( !config.plugins ) {
config.plugins = [];
}

config.plugins = [ ...config.plugins, ];

return Classic.create( element, config );
}
}
`;

expect( result ).to.equal( expected );
} );
} );

describe( 'getFileSize', () => {
it( 'should return file size in bytes', () => {
const filePath = 'path/to/file';
Expand Down
Loading