New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add hook for dynamic entry chunk emission #2809
Conversation
@guybedford Not yet ready for review but this may still be interesting for you to have a look at and maybe add some comments. I will update this PR until everything is resolved. |
Looks amazing. A second argument seems like it could permit the alias of the chunk nicely. I've also been wanting to see entry chunks with the same modules permitted (effectively just referencing the same shared chunk right?). Seems like a lot to review in one PR (manual chunks + entry chunks work), but I can aim to take a look at the manual chunks approach too when its ready. |
As stated in the description, this should work, but I am actually not sure if I added a test for this, will need to check.
Thanks. I have been wondering about this, another way of approaching it could be to allow the same syntax as for |
On second thought, having more than one entry would cause problems as to how the ids should be returned, so yes, a second parameter would make more sense. |
4ae4643
to
de17955
Compare
@guybedford @surma @jakearchibald @philipwalton This is now mostly ready from my side (except documentation updates, hopefully I can finish them as well soon). Please give this a spin. In the PR description, I added a suggestion for how to use this with workers. Note that ESM support for workers in browsers is rather poor so I also outlined how this could be used with AMD or SystemJS (basically a proxy chunk is added that loads the runtime). |
Really excited to hear about this. A few of us are on deadlines for Google I/O right now, so don't take slow reviews as a sign of disinterest 😄. Looking forward to giving this a spin. |
(I'm also excited about how this could allow HTML to be an entry point, as the plugin could scan for |
Documentation is now updated as well |
Interesting point. You could already achieve this via the |
Hey @lukastaegert I'm in the same situation as Jake (don't have a lot of time to really dig in) but after an initial look, I'm pretty happy with these changes, and I think the I'm also excited to read about the ManualChunks improvements, as hopefully this will solve the feature request I proposed in #2688. Nice work! |
Thanks!
Not yet but it is now only a small step that is left and I hope I manage to add it (or to a second PR) and release this together. |
points and introducing a manualChunkAlias for colouring to resolve this confusing double use of chunkAlias
* Allow manual chunks to contain entry points without name or with the same name * Throw if an emitted chunk is not found * Throw if there is a conflict between manual chunk entries * Allow nesting of manual chunks without requiring a specific order
- if the alias matches, the manual chunk becomes the entry chunk - otherwise a facade is created
function to `emitChunk`
This PR contains:
Are tests included?
Breaking Changes?
List any relevant issue numbers:
Will resolve #2742
Description
This PR will allow the emission of additional chunks and refine a lot of related logic.
Emitting new chunks
With this PR, a new plugin context function
this.emitChunk(moduleId: string, options?: {name?: string}): string
is added. This function allows to both split chunks by specifying amoduleId
that resolves to a module that is already in the graph as well as add new chunks if themoduleId
resolves to a new module. If Rollup has already completed the loading and parsing phase, emitting new chunks will fail with an error. With regard to tree-shaking, all exports of the module are automatically included.Emitted chunks will follow the naming scheme for auto-generated chunks. By supplying a
name
option, the[name]
part of the generated chunk name can be set. If this name is already assigned to a chunk with a different entry module or if there is already another chunk name assigned to the entry module (e.g. via the object form of theinput
option), bundling will fail with an error.The function returns a reference id that can be used to reference the chunk later via
this.getChunkFileName(referenceId: string): string
on the plugin context (can only be called duringbundle.generate
), or viaROLLUP_CHUNK_URL_referenceId
from code generated inload
andtransform
plugin hooks.Note that if you do not need a new module to be an entry point that creates a chunk that can be referenced, the recommended way of adding new modules to the graph is still creating virtual modules via the
resolveId
/load
/transform
hooks as this will result in fewer chunks and better tree-shaking.Internally, a separate
ModuleLoader
has been extracted that accepts additional entry points and manual chunks before and while the module loading is running.How to use this for workers
One idea behind this PR is the dynamic creation of workers. Depending on the format, there are different possible approaches.
ES modules
To my knowledge there is NO BROWSER that supports ES modules in workers (i.e. `new Worker(..., {type: 'module'})). Still, this is how you could do this in a plugin:
AMD and SystemJS
What does work today is AMD and SystemJS support. However here, you need a proxy chunk that takes care the corresponding module loader is loaded first:
AMD improvements:
AMD chunks will no longer use the
.js
extension for relative dependencies. This will make it possible to use abaseUrl
for a project as this changes resolution behaviour for AMD modules: https://requirejs.org/docs/api.html#jsfilesThere are now also some tests that actually run an AMD module loader to test the chunking
Bugfix: Empty dynamic entry points
In this PR, a bug was discovered where Rollup would fail if a dynamic entry point would contain nothing but reexports. This is fixed now.
New
resolveFileUrl
hookThis combines both the existing
resolveAssetUrl
hook but also resolves chunk URLs. To discern them, atype
parameter is provided.Named and unnamed entry points
To refine the chunking behaviour and especially the interaction with
manualChunks
, the logic follows a concept of named and unnamed entry points:input
input
name
is provided, otherwise they are unnamed.There no longer is a hard restriction preventing duplicate entry points, i.e. having more than one entry point referencing the same module. On the contrary, this is now permitted to e.g. allow a dynamically emitted entry point to coincide with an existing one. This means:
Also, dynamic entry points will now receive the name of the imported module as
[name]
in the file name pattern.ManualChunks improvements
Manual chunks have been very much refined: