Skip to content

Extend chunk information on plugin hooks #2549

Description

@isidrok

Feature Use Case

Since code splitting, dynamic imports and chunks became a thing the complexity of some use cases has increased, particularly when bundling web applications, specially due to auto-generated names and hashes.

This complexity makes it sometimes compulsory to rely on implementation details that are not guaranteed to keep working in the future or to use some non-intuitive workarounds in order to avoid manual configuration.

Feature Proposal

Next is a list of information I think would be useful to have available in a chunk:

fileName

Contains the reference to the file that originated the chunk, that is, an entry module or a dynamically imported one.

This would allow to map an original file to its hashed output, making it possible to:

  • Programatically generated script tags into an html file.
  • Generation of a static manifest to handle caching or referencing chunks by its entry point without having to worry about their hash (see Cache manifest #2520).

Here is a workaround although it's not confirmed to always work, it is based on assuming that the last module will always be the file that originated the chunk:

function getOriginaFile(chunk) {
  const files = Object.keys(chunk.modules);
  return files[files.length - 1];
}

chunkName

Contains the name of the chunk. Similar to fileName, and in most cases would coincide, except for auto-generated chunks.

Would allow to do things such as load specific chunk assets when loading the actual chunk (thinking about loading css here, for more information see tivac/modular-css#525)

Only workaround I can think of here is creating a regexp from the chunk/entry names pattern but seems a pretty bad solution.

hash

Once we have the fileName and the chunkName it would be logical to also include the hash, so one could have the placeholders information ("[name]-[hash].js") without reverse-engineering it into a RegExp.

isEntryModuleFacade

When there is a shared chunk (sometimes?) facade modules are generated, those are used in order to guarantee that the correct exports are available and are meant to be used for loading the chunk from outside of the other ones.

Given two modules foo.1.js and foo.2.js, it would be interesting to know which one is the facade, in order to consume it from outside the bundle (sharing a dependency/module between two projects?)

Current workaround is to check if the chunk has no modules, this is confirmed to always hold:

function isEntryModuleFacade(chunk) {
  return chunk.isEntry && Object.keys(chunk.modules).length === 0;
}

isDynamicImport

Flags the chunk to indicate that the reason it has been generated is due to a dynamic import, can't think about an use case right now but seems interesting.

Current way to know this could be to store the inputFiles in the options hook and then filter away the modules whose fileName is included in those and the facade ones, again I'm not 100% sure about this one.

function isDynamicImport (chunk) {
  return (
    chunk.isEntry &&
    !inputFiles.includes(getOriginalFile(chunk)) &&
    !isEntryModuleFacade(chunk);
}

Summary

I think being able to decompose the output.entryFileNames and output.chunkFileNames patterns would lead to greater flexibility when working with files to do things that rollup doesn't currently handle and may be quite useful.

Having information from the origin or reason of the chunk more specific than isEntry may come in handy in some situations.

I have no problem using some of the previously mentioned workarounds as long as they are not workarounds but instead become well documented conventions on how to solve some of this problems and are not tied to possible implementation changes, which could be the case of isEntryModuleFacade.

Would love to hear your opinions and ideas!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions