-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #683 from ckeditor/dll-integration
Feature (utils): Added a module (`builds.getDllPluginWebpackConfig()`) that produces the webpack configuration for DLL. See ckeditor/ckeditor5#8395.
- Loading branch information
Showing
6 changed files
with
297 additions
and
0 deletions.
There are no files selected for viewing
136 changes: 136 additions & 0 deletions
136
packages/ckeditor5-dev-utils/lib/builds/getdllpluginwebpackconfig.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/** | ||
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const path = require( 'path' ); | ||
const webpack = require( 'webpack' ); | ||
const TerserPlugin = require( 'terser-webpack-plugin' ); | ||
const bundler = require( '../bundler' ); | ||
const styles = require( '../styles' ); | ||
const tools = require( '../tools' ); | ||
|
||
/** | ||
* Returns a webpack configuration that creates a bundle file for the specified package. Thanks to that, plugins exported | ||
* by the package can be added to ready-to-use builds. | ||
* | ||
* @param {Object} options | ||
* @param {String} options.themePath An absolute path to the theme package. | ||
* @param {String} options.packagePath An absolute path to the root directory of the package. | ||
* @param {String} options.manifestPath An absolute path to the DLL manifest file. | ||
* @param {Boolean} options.isDevelopmentMode Whether to build a dev mode of the package. | ||
* @returns {Object} | ||
*/ | ||
module.exports = function getDllPluginWebpackConfig( options ) { | ||
const packageName = tools.readPackageName( options.packagePath ); | ||
|
||
const webpackConfig = { | ||
mode: options.isDevelopmentMode ? 'development' : 'production', | ||
|
||
performance: { hints: false }, | ||
|
||
entry: path.join( options.packagePath, 'src', 'index.js' ), | ||
|
||
output: { | ||
library: [ 'CKEditor5', getGlobalKeyForPackage( packageName ) ], | ||
|
||
path: path.join( options.packagePath, 'build' ), | ||
filename: getIndexFileName( packageName ), | ||
libraryTarget: 'umd', | ||
libraryExport: 'default' | ||
}, | ||
|
||
optimization: { | ||
minimize: false | ||
}, | ||
|
||
plugins: [ | ||
new webpack.BannerPlugin( { | ||
banner: bundler.getLicenseBanner(), | ||
raw: true | ||
} ), | ||
new webpack.DllReferencePlugin( { | ||
manifest: require( options.manifestPath ), | ||
scope: 'ckeditor5/src', | ||
name: 'CKEditor5.dll' | ||
} ) | ||
], | ||
|
||
module: { | ||
rules: [ | ||
{ | ||
test: /\.svg$/, | ||
use: [ 'raw-loader' ] | ||
}, | ||
{ | ||
test: /\.css$/, | ||
use: [ | ||
{ | ||
loader: 'style-loader', | ||
options: { | ||
injectType: 'singletonStyleTag', | ||
attributes: { | ||
'data-cke': true | ||
} | ||
} | ||
}, | ||
{ | ||
loader: 'postcss-loader', | ||
options: styles.getPostCssConfig( { | ||
themeImporter: { | ||
themePath: options.themePath | ||
}, | ||
minify: true | ||
} ) | ||
} | ||
] | ||
} | ||
] | ||
} | ||
}; | ||
|
||
if ( options.isDevelopmentMode ) { | ||
webpackConfig.devtool = 'source-map'; | ||
} else { | ||
webpackConfig.optimization.minimize = true; | ||
|
||
webpackConfig.optimization.minimizer = [ | ||
new TerserPlugin( { | ||
terserOptions: { | ||
output: { | ||
// Preserve CKEditor 5 license comments. | ||
comments: /^!/ | ||
} | ||
}, | ||
extractComments: false | ||
} ) | ||
]; | ||
} | ||
|
||
return webpackConfig; | ||
}; | ||
|
||
/** | ||
* Transforms the package name (`@ckeditor/ckeditor5-foo-bar`) to the name that will be used while | ||
* exporting the library into the global scope. | ||
* | ||
* @param {String} packageName | ||
* @returns {String} | ||
*/ | ||
function getGlobalKeyForPackage( packageName ) { | ||
return packageName | ||
.replace( /^@ckeditor\/ckeditor5?-/, '' ) | ||
.replace( /-([a-z])/g, ( match, p1 ) => p1.toUpperCase() ); | ||
} | ||
|
||
/** | ||
* Extracts the main file name from the package name. | ||
* | ||
* @param packageName | ||
* @returns {String} | ||
*/ | ||
function getIndexFileName( packageName ) { | ||
return packageName.replace( /^@ckeditor\/ckeditor5?-/, '' ) + '.js'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** | ||
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
module.exports = { | ||
getDllPluginWebpackConfig: require( './getdllpluginwebpackconfig' ) | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
123 changes: 123 additions & 0 deletions
123
packages/ckeditor5-dev-utils/tests/builds/getdllpluginwebpackconfig.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/** | ||
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const path = require( 'path' ); | ||
const chai = require( 'chai' ); | ||
const sinon = require( 'sinon' ); | ||
const mockery = require( 'mockery' ); | ||
const webpack = require( 'webpack' ); | ||
const TerserPlugin = require( 'terser-webpack-plugin' ); | ||
const expect = chai.expect; | ||
|
||
describe( 'builds/getDllPluginWebpackConfig()', () => { | ||
let sandbox, stubs, getDllPluginWebpackConfig; | ||
|
||
const manifest = { | ||
content: { | ||
'../../node_modules/lodash-es/_DataView.js': { | ||
id: '../../node_modules/lodash-es/_DataView.js', | ||
buildMeta: { | ||
buildMeta: 'namespace', | ||
providedExports: [ | ||
'default' | ||
] | ||
} | ||
} | ||
} | ||
}; | ||
|
||
beforeEach( () => { | ||
sandbox = sinon.createSandbox(); | ||
|
||
stubs = { | ||
tools: { | ||
readPackageName: sandbox.stub() | ||
} | ||
}; | ||
|
||
sandbox.stub( path, 'join' ).callsFake( ( ...args ) => args.join( '/' ) ); | ||
|
||
mockery.enable( { | ||
useCleanCache: true, | ||
warnOnReplace: false, | ||
warnOnUnregistered: false | ||
} ); | ||
|
||
mockery.registerMock( '../tools', stubs.tools ); | ||
mockery.registerMock( '/manifest/path', manifest ); | ||
|
||
getDllPluginWebpackConfig = require( '../../lib/builds/getdllpluginwebpackconfig' ); | ||
} ); | ||
|
||
afterEach( () => { | ||
mockery.disable(); | ||
sandbox.restore(); | ||
} ); | ||
|
||
it( 'returns the webpack configuration in production mode by default', () => { | ||
stubs.tools.readPackageName.returns( '@ckeditor/ckeditor5-dev' ); | ||
|
||
const webpackConfig = getDllPluginWebpackConfig( { | ||
packagePath: '/package/path', | ||
themePath: '/theme/path', | ||
manifestPath: '/manifest/path' | ||
} ); | ||
|
||
expect( webpackConfig ).to.be.an( 'object' ); | ||
|
||
expect( webpackConfig.mode ).to.equal( 'production' ); | ||
|
||
expect( webpackConfig.entry ).to.equal( '/package/path/src/index.js' ); | ||
expect( webpackConfig.output.library ).to.deep.equal( [ 'CKEditor5', 'dev' ] ); | ||
expect( webpackConfig.output.path ).to.equal( '/package/path/build' ); | ||
expect( webpackConfig.output.filename ).to.equal( 'dev.js' ); | ||
|
||
expect( webpackConfig.plugins ).to.be.an( 'array' ); | ||
expect( webpackConfig.plugins.length ).to.equal( 2 ); | ||
expect( webpackConfig.plugins[ 1 ] ).to.be.an.instanceOf( webpack.DllReferencePlugin ); | ||
|
||
expect( webpackConfig.plugins[ 1 ].options.manifest ).to.deep.equal( manifest ); | ||
expect( webpackConfig.plugins[ 1 ].options.scope ).to.equal( 'ckeditor5/src' ); | ||
expect( webpackConfig.plugins[ 1 ].options.name ).to.equal( 'CKEditor5.dll' ); | ||
|
||
expect( webpackConfig.optimization.minimize ).to.equal( true ); | ||
expect( webpackConfig.optimization.minimizer ).to.be.an( 'array' ); | ||
expect( webpackConfig.optimization.minimizer.length ).to.equal( 1 ); | ||
|
||
// Due to versions mismatch, the `instanceof` check does not pass. | ||
expect( webpackConfig.optimization.minimizer[ 0 ].constructor.name ).to.equal( TerserPlugin.name ); | ||
} ); | ||
|
||
it( 'transforms package with many dashes in its name', () => { | ||
stubs.tools.readPackageName.returns( '@ckeditor/ckeditor5-html-embed' ); | ||
|
||
const webpackConfig = getDllPluginWebpackConfig( { | ||
packagePath: '/package/path', | ||
themePath: '/theme/path', | ||
manifestPath: '/manifest/path' | ||
} ); | ||
|
||
expect( webpackConfig ).to.be.an( 'object' ); | ||
expect( webpackConfig.output.library ).to.deep.equal( [ 'CKEditor5', 'htmlEmbed' ] ); | ||
expect( webpackConfig.output.filename ).to.equal( 'html-embed.js' ); | ||
} ); | ||
|
||
it( 'does not minify the destination file when in dev mode', () => { | ||
stubs.tools.readPackageName.returns( '@ckeditor/ckeditor5-dev' ); | ||
|
||
const webpackConfig = getDllPluginWebpackConfig( { | ||
packagePath: '/package/path', | ||
themePath: '/theme/path', | ||
manifestPath: '/manifest/path', | ||
isDevelopmentMode: true | ||
} ); | ||
|
||
expect( webpackConfig.mode ).to.equal( 'development' ); | ||
expect( webpackConfig.optimization.minimize ).to.equal( false ); | ||
expect( webpackConfig.optimization.minimizer ).to.be.undefined; | ||
} ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const chai = require( 'chai' ); | ||
const expect = chai.expect; | ||
|
||
describe( 'builds', () => { | ||
let tasks; | ||
|
||
beforeEach( () => { | ||
tasks = require( '../../lib/builds/index' ); | ||
} ); | ||
|
||
describe( 'getDllPluginWebpackConfig()', () => { | ||
it( 'should be a function', () => { | ||
expect( tasks.getDllPluginWebpackConfig ).to.be.a( 'function' ); | ||
} ); | ||
} ); | ||
} ); |