diff --git a/packages/ckeditor5-dev-build-tools/src/plugins/replace.ts b/packages/ckeditor5-dev-build-tools/src/plugins/replace.ts index 51de1aae2..ed1745b84 100644 --- a/packages/ckeditor5-dev-build-tools/src/plugins/replace.ts +++ b/packages/ckeditor5-dev-build-tools/src/plugins/replace.ts @@ -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 { @@ -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 ); @@ -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; } diff --git a/packages/ckeditor5-dev-build-tools/tests/plugins/replace/fixtures/replaced-dependency.js b/packages/ckeditor5-dev-build-tools/tests/plugins/replace/fixtures/replaced-dependency.js new file mode 100644 index 000000000..b2db88b9b --- /dev/null +++ b/packages/ckeditor5-dev-build-tools/tests/plugins/replace/fixtures/replaced-dependency.js @@ -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; diff --git a/packages/ckeditor5-dev-build-tools/tests/plugins/replace/replace.test.ts b/packages/ckeditor5-dev-build-tools/tests/plugins/replace/replace.test.ts index acc38e23b..7299878f7 100644 --- a/packages/ckeditor5-dev-build-tools/tests/plugins/replace/replace.test.ts +++ b/packages/ckeditor5-dev-build-tools/tests/plugins/replace/replace.test.ts @@ -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: [] @@ -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: [