@@ -28,10 +28,9 @@ import { searchForWorkspaceRoot } from '../server/searchRoot'
2828
2929const debug = createDebugger ( 'vite:esbuild' )
3030
31- const INJECT_HELPERS_IIFE_RE =
32- / ^ ( .* ?) ( (?: c o n s t | v a r ) \s + \S + \s * = \s * f u n c t i o n \s * \( [ ^ ) ] * \) \s * \{ \s * " u s e s t r i c t " ; ) / s
33- const INJECT_HELPERS_UMD_RE =
34- / ^ ( .* ?) ( \( f u n c t i o n \( [ ^ ) ] * \) \s * \{ .+ ?a m d .+ ?f u n c t i o n \( [ ^ ) ] * \) \s * \{ \s * " u s e s t r i c t " ; ) / s
31+ // IIFE content looks like `var MyLib = function() {`. Spaces are removed when minified
32+ const IIFE_BEGIN_RE =
33+ / ( c o n s t | v a r ) \s + \S + \s * = \s * f u n c t i o n \( \) \s * \{ .* " u s e s t r i c t " ; / s
3534
3635const validExtensionRE = / \. \w + $ /
3736const jsxExtensionsRE = / \. (?: j | t ) s x \b /
@@ -333,22 +332,30 @@ export const buildEsbuildPlugin = (config: ResolvedConfig): Plugin => {
333332 if ( config . build . lib ) {
334333 // #7188, esbuild adds helpers out of the UMD and IIFE wrappers, and the
335334 // names are minified potentially causing collision with other globals.
336- // We use a regex to inject the helpers inside the wrappers.
335+ // We inject the helpers inside the wrappers.
336+ // e.g. turn:
337+ // <esbuild helpers> (function(){ /*actual content/* })()
338+ // into:
339+ // (function(){ <esbuild helpers> /*actual content/* })()
340+ // Not using regex because it's too hard to rule out performance issues like #8738 #8099 #10900 #14065
341+ // Instead, using plain string index manipulation (indexOf, slice) which is simple and performant
337342 // We don't need to create a MagicString here because both the helpers and
338343 // the headers don't modify the sourcemap
339- const injectHelpers =
340- opts . format === 'umd'
341- ? INJECT_HELPERS_UMD_RE
342- : opts . format === 'iife'
343- ? INJECT_HELPERS_IIFE_RE
344- : undefined
345- if ( injectHelpers ) {
346- res . code = res . code . replace (
347- injectHelpers ,
348- ( _ , helpers , header ) => header + helpers ,
349- )
344+ const esbuildCode = res . code
345+ const contentIndex =
346+ opts . format === 'iife'
347+ ? esbuildCode . match ( IIFE_BEGIN_RE ) ?. index || 0
348+ : opts . format === 'umd'
349+ ? esbuildCode . indexOf ( `(function(` ) // same for minified or not
350+ : 0
351+ if ( contentIndex > 0 ) {
352+ const esbuildHelpers = esbuildCode . slice ( 0 , contentIndex )
353+ res . code = esbuildCode
354+ . slice ( contentIndex )
355+ . replace ( `"use strict";` , `"use strict";` + esbuildHelpers )
350356 }
351357 }
358+
352359 return res
353360 } ,
354361 }
0 commit comments