How to make webpack+terser inline functions across chunks?
Asked Answered
S

0

9

I've got a function defined in an ES module that I'd like to make sure inlines. This works fine when it's only used in one chunk, but if I call the function from two separate chunks, webpack generates module lookup patterns that prevent inlining:

// common.js
export function inlineMe(x) {
  return x;
}

// main.js
import {inlineMe} from './common';
import('./ext').then(ext => {
  if (inlineMe(true)) {
    ext.f();
  } else {
    console.log('not inlined');
  }
});

// ext.js
import {inlineMe} from './common';
export function f() {
  console.log(inlineMe(true) ? 'inlined' : 'not inlined');
}

Running this through webpack with the TerserPlugin with the following reasonably standard options

// webpack.config.js
module.exports = {
  mode: 'production',
  entry: './main.js',
  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {passes: 50, inline: true, unsafe: true},
        },
      }),
    ],
  },
};

produces a result with no inlining. On the other hand, if I don't split code into chunks (i.e. change the import() expression into a normal top-level import), or if I don't use inlineMe from both chunks, the inlining works correctly. I expect it has something to do with the way webpack rewrites the chunks (it ends up as some sort of Object(r.a)(!0) where r.a seems indirectly to be defined by function r(e){return e}n.d(t,"a",(function(){return r})), so it's not surprising terser can't do anything with that).

Is there some incantation to make this kind of inlining work across multiple chunks? Maybe some way to tell webpack that this function/module should be somehow more available than others?

Squamosal answered 21/5, 2020 at 8:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.