@@ -195,6 +195,10 @@ function createConfig(format, output, plugins = []) {
195195 ]
196196 : [ ]
197197
198+ if ( format === 'cjs' ) {
199+ nodePlugins . push ( cjsReExportsPatchPlugin ( ) )
200+ }
201+
198202 return {
199203 input : resolve ( entryFile ) ,
200204 // Global and Browser ESM builds inlines everything so that they can be
@@ -329,3 +333,46 @@ function createMinifiedConfig(format) {
329333 ]
330334 )
331335}
336+
337+ // temporary patch for https://github.com/nodejs/cjs-module-lexer/issues/79
338+ //
339+ // When importing a cjs module from esm, Node.js uses cjs-module-lexer to
340+ // detect * re-exports from other packages. However, the detection logic is
341+ // fragile and breaks when Rollup generates different code for the re-exports.
342+ // We were locked on an old version of Rollup because of this.
343+ //
344+ // The latest versions of Node ships an updated version of cjs-module-lexer that
345+ // has fixed https://github.com/nodejs/cjs-module-lexer/issues/38, however we
346+ // still need to support older versions of Node that does not have the latest
347+ // version of cjs-module-lexer (Node < 14.18)
348+ //
349+ // At the same time, we want to upgrade to Rollup 3 so we are not forever locked
350+ // on an old version of Rollup.
351+ //
352+ // What this patch does:
353+ // 1. Rewrite the for...in loop to Object.keys() so cjs-module-lexer can find it
354+ // The for...in loop is only used when output.externalLiveBindings is set to
355+ // false, and we do want to set it to false to avoid perf costs during SSR.
356+ // 2. Also remove exports.hasOwnProperty check, which breaks the detection in
357+ // Node.js versions that
358+ //
359+ // TODO in the future, we should no longer rely on this if we inline all deps
360+ // in the main `vue` package.
361+ function cjsReExportsPatchPlugin ( ) {
362+ const matcher =
363+ / f o r \( v a r k i n ( \w + ) \) { ( \s + i f \( k ! = = ' d e f a u l t ' ) & & ! e x p o r t s .h a s O w n P r o p e r t y \( k \) ( \) e x p o r t s \[ k \] = (?: \w + ) \[ k \] ; \s + ) } /
364+ return {
365+ name : 'patch-cjs-re-exports' ,
366+ renderChunk ( code , _ , options ) {
367+ if ( matcher . test ( code ) ) {
368+ return code . replace ( matcher , ( _ , r1 , r2 , r3 ) => {
369+ return `Object.keys(${ r1 } ).forEach(function(k) {${ r2 } ${ r3 } });`
370+ } )
371+ } else if ( options . file . endsWith ( '/vue.cjs.js' ) ) {
372+ // make sure we don't accidentally miss the rewrite in case Rollup
373+ // changes the output again.
374+ throw new Error ( 'cjs build re-exports rewrite failed.' )
375+ }
376+ }
377+ }
378+ }
0 commit comments