@@ -195,6 +195,10 @@ function createConfig(format, output, plugins = []) {
195
195
]
196
196
: [ ]
197
197
198
+ if ( format === 'cjs' ) {
199
+ nodePlugins . push ( cjsReExportsPatchPlugin ( ) )
200
+ }
201
+
198
202
return {
199
203
input : resolve ( entryFile ) ,
200
204
// Global and Browser ESM builds inlines everything so that they can be
@@ -329,3 +333,46 @@ function createMinifiedConfig(format) {
329
333
]
330
334
)
331
335
}
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