Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)


Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand All @@ -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": {
Expand Down
99 changes: 83 additions & 16 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function isObject(value: unknown): value is Record<string, unknown> {
*
* @returns Vite DevServer tags
*/
function getViteScripts() {
function getViteBaseScripts() {
const entries: string[] = []

entries.push('<script type="module" src="/@vite/client"></script>')
Expand All @@ -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(`<script type="module" src="/${source}"></script>`)
Expand All @@ -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(`<script type="module" src="/${source}"></script>`)
} else if (/\.(css|less|sass|scss|postcss)/.test(source)) {
entries.push(`<link rel="stylesheet" href="/${source}"/>`)
}
}

return entries.join('\n')
}

/**
* Replace the AEM URL with the Vite DevServer URL to prevent any weird redirect bugs.
*
Expand Down Expand Up @@ -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+])=['"]([^'"]*)['"][^>]*>|[^>]*(?:></script>|>))`,
'g',
)
let clientlibsExpression: RegExp | Record<string, RegExp>

if (isObject(options.clientlibsExpression)) {
clientlibsExpression = {}
for (const [key, value] of Object.entries(options.clientlibsExpression)) {
clientlibsExpression[key] = new RegExp(
`<(?:script|link).*(?:src|href)="${value}"(([w+])=['"]([^'"]*)['"][^>]*>|[^>]*(?:></script>|>))`,
'g',
)
}
} else {
clientlibsExpression = clientlibsExpression = new RegExp(
`<(?:script|link).*(?:src|href)="${options.clientlibsExpression ?? options.publicPath}.(?:(${keyFormatExpressions.join('|')}))?.?(?:css|js)"(([w+])=['"]([^'"]*)['"][^>]*>|[^>]*(?:></script>|>))`,
'g',
)
}

debug('clientlibs (custom) expression', options.clientlibsExpression)
debug('clientlibs expression', clientlibsExpression)
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export function viteForAem(options: PluginOptions): PluginOption[] {
publicPath: options.publicPath,
minify,
resourcesPath,
}),
}) as PluginOption,
)
}

Expand Down
11 changes: 9 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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/<project>/clientlibs/(<clientlib_one>|<clientlib_two>)
* // String usage
* "/etc.clientlibs/<project>/clientlibs/(<clientlib_one>|<clientlib_two>)"
* // Object usage
* {
* "src/index.ts": "/etc.clientlibs/<project>/clientlibs/<clientlib_one>"
* }
*/
clientlibsExpression?: string
clientlibsExpression?: string | Record<string, string>

/**
* A list of AEM paths to watch and replace ClientLib paths within.
Expand Down