Skip to content

es/minifier: Inline parameters #10931

@lukesandberg

Description

@lukesandberg

Describe the feature

See playground

function complex(foo, fn) {
  // prevent inlining
  if (Math.random() > 0.5) throw new Error()
  return fn?.(foo)
}

console.log(complex("foo"))
console.log(complex("bar"))
console.log(complex("baz"))

If i remove the if (Math.random)... line then SWC will just inline this function as void 0 at all callsites, however, if the function is not a trivial inlining candidate it backs off and preserves the function pretty much as is.

In that case, i would like swc to just inline the parameter, all callsites are implicitly passing undefined to the fn parameter. If the minifier could delete that parameter and add a variable const fn = undefined then another minifier pass would just simplify the return statement to return undefined.

This example is of course somewhat trivial, but my actual usecase is wanting to pass an optional callback through a few layers of shared functions. If we could inline undefined when not passed then it would allow this callback to be eliminated altogether in the common case where it isn't passed.

The closure compiler has a pass like this: https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/OptimizeParameters.java

The semantics are that parameters will get inlined if all callsites pass the same value and that value is side effect free and 'not too big'. There was a once a code size regression where a large string literal got inlined in a way that moved it into an earlier chunk. I don't think swc needs to worry about that since it doesn't support cross chunk optimizations (does it?)

Since swc is happy to potentially inline this function and delete it, it could perhaps also be happy to modify the signature in the same situations.

Babel plugin or link to the feature description

No response

Additional context

I was hoping for something like this as i am working on the turbopack runtime and there are a number of hooks needed by HMR that are not needed in production. So to share more code i was hoping to have common functions take optional callbacks that could just be trimmed in the production usecase.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions