0

Question: How do I get the dependency chunk graph ahead of time without parsing the final bundle? Best would be as json.

Why:

With webpacks default chunk splitting strategy it creates common chunks that multiple other chunks depend on. E.g. two dynamic imports like

const foo = () => import('./foo');
const bar = () => import('./bar');

webpack may rewrite to (not exactly, but as a concept):

const foo = () => __webpack.r(['foo', 'bar']);
const bar = () => __webpack.r(['bar', 'bar.0']);

So webpack noticed that foo reuses parts of 'bar' and created a 'bar.0', with the modules just for bar and reuses everything in chunk 'bar'.

When I send a html page to the user where I definitely know it'll gonna need 'foo', i'd like to add:

<script src="chunk/foo.js"></script><script src="chunk/bar.js">

And when I send a html page to the user where I know it gonna need 'bar', i'd like to add:

<script src="chunk/bar.js"></script><script src="chunk/bar.0.js">

Just so the scripts are already loaded at html parse time and don't rely on extra roundtrips when javascript is first executed.

But how do I get the dependency chunk graph ahead of time without parsing the final bundle?

sod
  • 3,804
  • 5
  • 22
  • 28

1 Answers1

0

If there is no way to access the chunk graph from webpack, I have to define the common chunks manually. Looks roughly like:

function extraChunkForCodeReuse(name: string, chunks: RegExp): Record<string, webpack.Options.CacheGroupsOptions> {
    const cacheGroup: webpack.Options.CacheGroupsOptions = {
        name,
        priority: -20,
        minChunks: 3,
        reuseExistingChunk: false,
        chunks: (chunk) => chunks.test(chunk.name),
    };

    return {[`${name}`]: cacheGroup};
}

const config = {
    optimization: {
        splitChunks: {
            cacheGroups: {
                // the default code reuse strategy is very good, but the chunk names are nondeterministic thus we can't reliably preload them
                // via <script> tags from twig:
                default: false,

                // define custom reuse chunks that we can embed via <script> tag
                ...extraChunkForCodeReuse('shared-foo', /foo|bar|baz/),
                ...extraChunkForCodeReuse('shared-checkout', /checkout/),
            },
        },
    },
};

Then i can do

// template that needs the foo chunk
<script src="/shared-foo.js"></script>
<script src="/foo.js"></script>
<script src="/main.js"></script>
// template that needs the checkout chunk
<script src="/shared-checkout.js"></script>
<script src="/checkout.js"></script>
<script src="/main.js"></script>
sod
  • 3,804
  • 5
  • 22
  • 28