Skip to content

Commit

Permalink
Feature (build-tools): Allow replacing imports before bundling.
Browse files Browse the repository at this point in the history
  • Loading branch information
filipsobol committed May 24, 2024
1 parent 8fa6d2d commit 3b67ca9
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
32 changes: 30 additions & 2 deletions packages/ckeditor5-dev-build-tools/src/plugins/replace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ export interface RollupReplaceOptions {
* [ /find/g, 'replace' ]
* ]
*
* If the third element is set to `true`, the replacement will be done BEFORE bundling,
* meaning that the import will be replaced in the source code, not only in the resulting bundle.
*
* @default []
*/
replace: Array<[ RegExp | string, string ]>;
replace: Array<[ RegExp | string, string, true? ]>;
}

export function replaceImports( pluginOptions: RollupReplaceOptions ): Plugin {
Expand All @@ -38,9 +41,34 @@ export function replaceImports( pluginOptions: RollupReplaceOptions ): Plugin {
].includes( node.type );
}

const transformReplace: Array<[ RegExp | string, string ]> = [];
const renderReplace: Array<[ RegExp | string, string ]> = [];

options.replace.forEach( ( [ pattern, replacement, transformOnly ] ) => {
if ( transformOnly === true ) {
transformReplace.push( [ pattern, replacement ] );
} else {
renderReplace.push( [ pattern, replacement ] );
}
} );

return {
name: 'cke5-replace-import',

transform( source ) {
const magic = new MagicString( source );

transformReplace.forEach( replace => magic.replaceAll( ...replace ) );

return {
code: magic.toString(),
map: magic.generateMap( {
includeContent: true,
hires: true
} )
};
},

renderChunk( source, chunk ) {
const magic = new MagicString( source );
const ast = this.parse( source );
Expand All @@ -53,7 +81,7 @@ export function replaceImports( pluginOptions: RollupReplaceOptions ): Plugin {

const path = node.source.value as string;

const replacer = options.replace.find( ( [ pattern ] ) => {
const replacer = renderReplace.find( ( [ pattern ] ) => {
if ( typeof pattern === 'string' ) {
return pattern === path;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/

export const test = 456;
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ test( 'Accepts RegExp', async () => {
verifyChunk( output, 'input.js', 'export * from \'another-dependency\';' );
} );

test( 'Replaces import BEFORE bundling when 3rd parameter is set to true', async () => {
const output = await generateBundle( {
replace: [
[ './dependency.js', './replaced-dependency.js', true ]
]
} );

verifyChunk( output, 'input.js', 'const test = 456;' );
} );

test( 'Updates the source map', async () => {
const unmodifiedOutput = await generateBundle( {
replace: []
Expand All @@ -74,6 +84,21 @@ test( 'Updates the source map', async () => {
verifyChunk( output, 'input.js', 'another-dependency' );
} );

test( 'Updates the source map when 3rd parameter is set to true', async () => {
const unmodifiedOutput = await generateBundle( {
replace: []
}, true );

const output = await generateBundle( {
replace: [
[ './dependency.js', './replaced-dependency.js', true ]
]
}, true );

expect( ( unmodifiedOutput[ 1 ] as OutputAsset ).source ).not.toBe( ( output[ 1 ] as OutputAsset ).source );
verifyChunk( output, 'input.js', 'const test = 456;' );
} );

test( 'Replacing happens after the code is parsed and tree-shaken', async () => {
const output = await generateBundle( {
replace: [
Expand Down

0 comments on commit 3b67ca9

Please sign in to comment.