diff --git a/CHANGELOG.md b/CHANGELOG.md index 77d0c3b..7378054 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# [5.2.0](https://github.com/aem-vite/vite-aem-plugin/compare/v5.1.0...v5.2.0) (2025-08-31) + + +### Features + +* add option to specifying which paths will be replaced when injecting vite files + + # [5.1.0](https://github.com/aem-vite/vite-aem-plugin/compare/v5.0.6...v5.1.0) (2025-08-31) diff --git a/package.json b/package.json index 7556a75..395bdad 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/aem-vite/vite-aem-plugin/issues" }, - "version": "5.1.0", + "version": "5.2.0", "type": "module", "packageManager": "pnpm@10.15.0+sha512.486ebc259d3e999a4e8691ce03b5cac4a71cbeca39372a9b762cb500cfdf0873e2cb16abe3d951b1ee2cf012503f027b98b6584e4df22524e0c7450d9ec7aa7b", "engines": { @@ -37,12 +37,12 @@ "types": "./lib/index.d.ts", "exports": { "import": { - "default": "./lib/index.js", - "types": "./lib/index.d.ts" + "types": "./lib/index.d.ts", + "default": "./lib/index.js" }, "require": { - "default": "./lib/index.cjs", - "types": "./lib/index.d.cts" + "types": "./lib/index.d.cts", + "default": "./lib/index.cjs" } }, "publishConfig": { diff --git a/src/helpers.ts b/src/helpers.ts index d5c3d18..21ff3f8 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -24,7 +24,7 @@ export function isObject(value: unknown): value is Record { * * @returns Vite DevServer tags */ -function getViteScripts() { +function getViteBaseScripts() { const entries: string[] = [] entries.push('') @@ -38,6 +38,19 @@ function getViteScripts() { `) } + return entries.join('\n') +} + +/** + * Retrieves the Vite DevServer `link`/`script` tags. + * + * @returns Vite Sources tags + */ +function getViteScripts() { + const entries: string[] = [] + + entries.push(getViteBaseScripts()) + for (const source of bundleEntries) { if (/\.(js|ts)x?/.test(source)) { entries.push(``) @@ -49,6 +62,22 @@ function getViteScripts() { return entries.join('\n') } +function getViteScript(key: string) { + const entries: string[] = [] + + const source = bundleEntries.find((entry) => entry === key) + + if (source) { + if (/\.(js|ts)x?/.test(source)) { + entries.push(``) + } else if (/\.(css|less|sass|scss|postcss)/.test(source)) { + entries.push(``) + } + } + + return entries.join('\n') +} + /** * Replace the AEM URL with the Vite DevServer URL to prevent any weird redirect bugs. * @@ -105,12 +134,22 @@ export function getKeyFormatExpressions(options: PluginOptions) { export function configureAemProxy(aemUrl: string, options: PluginOptions) { const keyFormatExpressions = getKeyFormatExpressions(options) - const clientlibsExpression = new RegExp( - `<(?:script|link).*(?:src|href)="${ - options.clientlibsExpression ?? options.publicPath - }.(?:(${keyFormatExpressions.join('|')}))?.?(?:css|js)"(([\\w+])=['"]([^'"]*)['"][^>]*>|[^>]*(?:>|>))`, - 'g', - ) + let clientlibsExpression: RegExp | Record + + if (isObject(options.clientlibsExpression)) { + clientlibsExpression = {} + for (const [key, value] of Object.entries(options.clientlibsExpression)) { + clientlibsExpression[key] = new RegExp( + `<(?:script|link).*(?:src|href)="${value}"(([w+])=['"]([^'"]*)['"][^>]*>|[^>]*(?:>|>))`, + 'g', + ) + } + } else { + clientlibsExpression = clientlibsExpression = new RegExp( + `<(?:script|link).*(?:src|href)="${options.clientlibsExpression ?? options.publicPath}.(?:(${keyFormatExpressions.join('|')}))?.?(?:css|js)"(([w+])=['"]([^'"]*)['"][^>]*>|[^>]*(?:>|>))`, + 'g', + ) + } debug('clientlibs (custom) expression', options.clientlibsExpression) debug('clientlibs expression', clientlibsExpression) @@ -147,19 +186,47 @@ export function configureAemProxy(aemUrl: string, options: PluginOptions) { debug('parsing request for:', requestUrl) debug('content length', html.length) - const matches = html.match(clientlibsExpression) + let replacedHtml = html + let matches: RegExpMatchArray | null = null - debug('total clientlib matches:', matches) + if (isObject(clientlibsExpression)) { + let matchesCount = 0 - let replacedHtml = html + for (const [key, value] of Object.entries(clientlibsExpression)) { + matches = html.match(value) + + if (matches) { + debug('stripping matched clientlibs expression:', value, matches) + + matches.forEach((match) => { + if (matchesCount === 0) { + replacedHtml = replacedHtml.replace(match, `${getViteBaseScripts()} ${getViteScript(key)}`) + } else { + replacedHtml = replacedHtml.replace(match, getViteScript(key)) + } + }) - if (matches) { - debug('stripping matched clientlibs:', matches) + matchesCount += matches.length + } + } + + debug('total clientlib matches:', matchesCount) + } else { + matches = html.match(clientlibsExpression) + + if (matches) { + debug('stripping matched clientlibs:', matches) + + matches.forEach((match, index) => { + // Replace the last matched ClientLib with the Vite DevServer script tags + replacedHtml = replacedHtml.replace( + match, + index === (matches as RegExpMatchArray).length - 1 ? getViteScripts() : '', + ) + }) + } - matches.forEach((match, index) => { - // Replace the last matched ClientLib with the Vite DevServer script tags - replacedHtml = replacedHtml.replace(match, index === matches.length - 1 ? getViteScripts() : '') - }) + debug('total clientlib matches:', matches?.length) } const isHtmlModified = replacedHtml.length !== html.length diff --git a/src/index.ts b/src/index.ts index 7059505..a636127 100644 --- a/src/index.ts +++ b/src/index.ts @@ -146,7 +146,7 @@ export function viteForAem(options: PluginOptions): PluginOption[] { publicPath: options.publicPath, minify, resourcesPath, - }), + }) as PluginOption, ) } diff --git a/src/types.ts b/src/types.ts index ba35e15..22fa60e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -26,11 +26,18 @@ export interface PluginOptions { /** * The expression to use when matching ClientLibs on a page. + * Can be a string for replacing all matches with vite scripts, + * or an object mapping source paths to specific replacement values. * * @example - * /etc.clienlibs//clientlibs/(|) + * // String usage + * "/etc.clientlibs//clientlibs/(|)" + * // Object usage + * { + * "src/index.ts": "/etc.clientlibs//clientlibs/" + * } */ - clientlibsExpression?: string + clientlibsExpression?: string | Record /** * A list of AEM paths to watch and replace ClientLib paths within.