Skip to content

Module concatenation causes Terser bailout conditions #17626

@laverdet

Description

@laverdet

Bug report

I have created a simple 5-line reproduction case here:
https://gist.github.com/laverdet/1b8537f56dca2d990fe63decf66a2cc6

When we export hoistable function declarations which consume concatenated modules Webpack creates bailout conditions in Terser.

If you run this example with npm i && npx webpack && cat dist/344.js we can see the output:

// [runtime noise omitted]
const e={title:"main",aaaaaaaaaaaaaaaaaaaa:"bbbbbbbbbbbb"};function s(){console.log(e.title)}

If instead you you comment out line 2, and uncomment line 3 in async.js we get this output instead:

// [runtime noise omitted]
const c=()=>{console.log("main")}

What is the current behavior?

The code that Webpack generates cannot be optimized well because Terser assumes that as soon as the function is referenced it may be invoked. Therefore it would be incorrect to inline the object keys since the hoisted function would throw if invoked before the object is defined.

If the current behavior is a bug, please provide the steps to reproduce.

This deopt is a bug because we know from the es-262 specification that the default export of payload.js will be evaluated fully before any other module can reference the function defined in async.js.

What is the expected behavior?

If concatenated modules were injected before the export runtime invocation (sorry I don't know what you call this internally) then the code could be optimized. You can observe this effect pretty easily at the Terser REPL by pasting the two examples in:

https://try.terser.org/

const a = { aaaaaaaaaaaaaaaaa: 'a' };
globalThis.foo = function() {
  console.log(a.aaaaaaaaaaaaaaaaa);
}

output: const o="a";globalThis.foo=function(){console.log(o)};

globalThis.foo = function() {
  console.log(a.aaaaaaaaaaaaaaaaa);
}
const a = { aaaaaaaaaaaaaaaaa: 'a' };

output: globalThis.foo=function(){console.log(a.aaaaaaaaaaaaaaaaa)};const a={aaaaaaaaaaaaaaaaa:"a"};

Other relevant information:
webpack version: 5.88.2
Node.js version: main [996f3904bc]
Operating System: macOS 13.3.1(a)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions