Skip to content

Commit

Permalink
[v3.0] New hashing algorithm that "fixes (nearly) everything" (#4543)
Browse files Browse the repository at this point in the history
* Initial new hashing idea

* Simplify external import path generation

197 broken tests left

* Use correct file names in chunk info

197 broken tests left

* Implement first draft for hashing algorithm

189 broken tests left

* Remove active deprecations

this.emitAsset
this.emitChunk
this.getAssetFileName
this.getChunkFileName
import.meta.ROLLUP_ASSET_URL_
import.meta.ROLLUP_CHUNK_URL_

* Reduce render parameters

* Always scan all chunks for hashes

* Fix asset emission and remaining tests

* Reintroduce augmentChunkHash and get OutputChunk by converting RenderedChunk

* Provide chunk graph in renderChunk

* Handle hash collisions

* Remove deprecated hacky asset emission

* Allow to configure hash sizes per file

* Update documentation

* Extend tests

* Minor improvements

* Improve documentation about hashing

* Replace hash in sourcemap file

* Provide ChunkInfo in banner/footer/intro/outro

* Extract hashing logic

* Clean up hashing logic

* Add ExternalChunk wrapper

* Store inputBase on Chunk

* Store snippets on Chunk

* Align chunk interfaces

* Reduce this. property access

* Move dynamicImportFunction warning to options normalization

* Restructure rendering logic

* Do not run on Node 10

* Update documentation

* Try to fix Windows tests

* Improve coverage

* Remove graph background colors

3.0.0-0
  • Loading branch information
lukastaegert committed Sep 6, 2022
1 parent 6efb181 commit 804d72c
Show file tree
Hide file tree
Showing 381 changed files with 3,099 additions and 1,542 deletions.
56 changes: 35 additions & 21 deletions docs/05-plugin-development.md

Large diffs are not rendered by default.

21 changes: 14 additions & 7 deletions docs/999-big-list-of-options.md
Expand Up @@ -389,17 +389,24 @@ The pattern to use for naming custom emitted assets to include in the build outp

- `[extname]`: The file extension of the asset including a leading dot, e.g. `.css`.
- `[ext]`: The file extension without a leading dot, e.g. `css`.
- `[hash]`: A hash based on the name and content of the asset.
- `[hash]`: A hash based on the content of the asset. You can also set a specific hash length via e.g. `[hash:10]`.
- `[name]`: The file name of the asset excluding any extension.

Forward slashes `/` can be used to place files in sub-directories. When using a function, `assetInfo` is a reduced version of the one in [`generateBundle`](guide/en/#generatebundle) without the `fileName`. See also [`output.chunkFileNames`](guide/en/#outputchunkfilenames), [`output.entryFileNames`](guide/en/#outputentryfilenames).

#### output.banner/output.footer

Type: `string | (() => string | Promise<string>)`<br> CLI: `--banner`/`--footer <text>`
Type: `string | ((chunk: ChunkInfo) => string | Promise<string>)`<br> CLI: `--banner`/`--footer <text>`

A string to prepend/append to the bundle. You can also supply a function that returns a `Promise` that resolves to a `string` to generate it asynchronously (Note: `banner` and `footer` options will not break sourcemaps).

If you supply a function, `chunk` contains additional information about the chunk using the same `ChunkInfo` type as the [`generateBundle`](guide/en/#generatebundle) hook with the following differences:

- `code` and `map` are not set as the chunk has not been rendered yet.
- all referenced chunk file names that would contain hashes will contain hash placeholders instead. This includes `fileName`, `imports`, `importedBindings`, `dynamicImports` and `implicitlyLoadedBefore`. When you use such a placeholder file name or part of it in the code returned from this option, Rollup will replace the placeholder with the actual hash before `generateBundle`, making sure the hash reflects the actual content of the final generated chunk including all referenced file hashes.

`chunk` is mutable and changes applied in this hook will propagate to other plugins and to the generated bundle. That means if you add or remove imports or exports in this hook, you should update `imports`, `importedBindings` and/or `exports`.

```js
// rollup.config.js
export default {
Expand All @@ -421,10 +428,10 @@ Type: `string | ((chunkInfo: ChunkInfo) => string)`<br> CLI: `--chunkFileNames <
The pattern to use for naming shared chunks created when code-splitting, or a function that is called per chunk to return such a pattern. Patterns support the following placeholders:

- `[format]`: The rendering format defined in the output options, e.g. `es` or `cjs`.
- `[hash]`: A hash based on the content of the chunk and the content of all its dependencies.
- `[hash]`: A hash based only on the content of the final generated chunk, including transformations in [`renderChunk`](guide/en/#renderchunk) and any referenced file hashes. You can also set a specific hash length via e.g. `[hash:10]`.
- `[name]`: The name of the chunk. This can be explicitly set via the [`output.manualChunks`](guide/en/#outputmanualchunks) option or when the chunk is created by a plugin via [`this.emitFile`](guide/en/#thisemitfile). Otherwise, it will be derived from the chunk contents.

Forward slashes `/` can be used to place files in sub-directories. When using a function, `chunkInfo` is a reduced version of the one in [`generateBundle`](guide/en/#generatebundle) without properties that depend on file names. See also [`output.assetFileNames`](guide/en/#outputassetfilenames), [`output.entryFileNames`](guide/en/#outputentryfilenames).
Forward slashes `/` can be used to place files in sub-directories. When using a function, `chunkInfo` is a reduced version of the one in [`generateBundle`](guide/en/#generatebundle) without properties that depend on file names and no information about the rendered modules as rendering only happens after file names have been generated. You can however access a list of included `moduleIds`. See also [`output.assetFileNames`](guide/en/#outputassetfilenames), [`output.entryFileNames`](guide/en/#outputentryfilenames).

#### output.compact

Expand All @@ -439,10 +446,10 @@ Type: `string | ((chunkInfo: ChunkInfo) => string)`<br> CLI: `--entryFileNames <
The pattern to use for chunks created from entry points, or a function that is called per entry chunk to return such a pattern. Patterns support the following placeholders:

- `[format]`: The rendering format defined in the output options, e.g. `es` or `cjs`.
- `[hash]`: A hash based on the content of the entry point and the content of all its dependencies.
- `[hash]`: A hash based only on the content of the final generated entry chunk, including transformations in [`renderChunk`](guide/en/#renderchunk) and any referenced file hashes. You can also set a specific hash length via e.g. `[hash:10]`.
- `[name]`: The file name (without extension) of the entry point, unless the object form of input was used to define a different name.

Forward slashes `/` can be used to place files in sub-directories. When using a function, `chunkInfo` is a reduced version of the one in [`generateBundle`](guide/en/#generatebundle) without properties that depend on file names. See also [`output.assetFileNames`](guide/en/#outputassetfilenames), [`output.chunkFileNames`](guide/en/#outputchunkfilenames).
Forward slashes `/` can be used to place files in sub-directories. When using a function, `chunkInfo` is a reduced version of the one in [`generateBundle`](guide/en/#generatebundle) without properties that depend on file names and no information about the rendered modules as rendering only happens after file names have been generated. You can however access a list of included `moduleIds`. See also [`output.assetFileNames`](guide/en/#outputassetfilenames), [`output.chunkFileNames`](guide/en/#outputchunkfilenames).

This pattern will also be used when setting the [`output.preserveModules`](guide/en/#outputpreservemodules) option. Here a different set of placeholders is available, though:

Expand Down Expand Up @@ -809,7 +816,7 @@ There are some additional options that have an effect on the generated interop c

#### output.intro/output.outro

Type: `string | (() => string | Promise<string>)`<br> CLI: `--intro`/`--outro <text>`
Type: `string | ((chunk: ChunkInfo) => string | Promise<string>)`<br> CLI: `--intro`/`--outro <text>`

Similar to [`output.banner/output.footer`](guide/en/#outputbanneroutputfooter), except that the code goes _inside_ any format-specific wrapper.

Expand Down
1 change: 1 addition & 0 deletions docs/build-hooks.mmd
@@ -1,4 +1,5 @@
flowchart TB
classDef default fill:transparent, color:#000;
classDef hook-parallel fill:#ffb3b3,stroke:#000;
classDef hook-sequential fill:#ffd2b3,stroke:#000;
classDef hook-first fill:#fff2b3,stroke:#000;
Expand Down
64 changes: 42 additions & 22 deletions docs/output-generation-hooks.mmd
@@ -1,5 +1,5 @@
flowchart TB
classDef default fill:#fff;
classDef default fill:transparent, color:#000;
classDef hook-parallel fill:#ffb3b3,stroke:#000;
classDef hook-sequential fill:#ffd2b3,stroke:#000;
classDef hook-first fill:#fff2b3,stroke:#000;
Expand All @@ -9,25 +9,25 @@ flowchart TB
augmentchunkhash("augmentChunkHash"):::hook-sequential-sync
click augmentchunkhash "/guide/en/#augmentchunkhash" _parent

banner("banner"):::hook-parallel
banner("banner"):::hook-sequential
click banner "/guide/en/#banner" _parent

closebundle("closeBundle"):::hook-parallel
click closebundle "/guide/en/#closebundle" _parent

footer("footer"):::hook-parallel
footer("footer"):::hook-sequential
click footer "/guide/en/#footer" _parent

generatebundle("generateBundle"):::hook-sequential
click generatebundle "/guide/en/#generatebundle" _parent

intro("intro"):::hook-parallel
intro("intro"):::hook-sequential
click intro "/guide/en/#intro" _parent

outputoptions("outputOptions"):::hook-sequential-sync
click outputoptions "/guide/en/#outputoptions" _parent

outro("outro"):::hook-parallel
outro("outro"):::hook-sequential
click outro "/guide/en/#outro" _parent

renderchunk("renderChunk"):::hook-sequential
Expand All @@ -54,27 +54,47 @@ flowchart TB

outputoptions
--> renderstart
--> banner & footer & intro & outro
--> beforerenderdynamicimport(( ))
--> beforeaugmentchunkhash(( ))
--> |each chunk|augmentchunkhash
--> renderchunk
.-> generatebundle
--> writebundle
.-> closebundle
--> |each chunk|beforerenderdynamicimport

beforerenderdynamicimport
--> |"each import()"|renderdynamicimport
--> beforeaugmentchunkhash
afteraddons
--> |each chunk|renderchunk

augmentchunkhash
--> |each import.meta.*|beforeimportmeta(( ))
--> |import.meta.url|resolvefileurl
.-> renderchunk
--> generatebundle
--> writebundle
.-> closebundle

beforeimportmeta
--> |other|resolveimportmeta
.-> renderchunk
subgraph generateChunks [" "]
direction TB
beforerenderdynamicimport(( ))
---> beforeresolveimportmeta(( ))
----> beforereaddons(( ))
--> banner & footer & intro & outro
--> afteraddons(( ))
.-> |next chunk|beforerenderdynamicimport

beforerenderdynamicimport
--> |"each import()"|renderdynamicimport
--> beforerenderdynamicimport

beforeresolveimportmeta
--> |each import.meta.*|beforeimportmeta(( ))
--> |import.meta.url|resolvefileurl
--> afterresolveimportmeta(( ))

beforeimportmeta
--> |other|resolveimportmeta
--> afterresolveimportmeta

afterresolveimportmeta
--> beforeresolveimportmeta
end

renderchunk
--> augmentchunkhash
.-> |next chunk|renderchunk

style generateChunks stroke-width:0px;

rendererror
.-> closebundle
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "rollup",
"version": "2.79.0",
"version": "3.0.0-0",
"description": "Next-generation ES module bundler",
"main": "dist/rollup.js",
"module": "dist/es/rollup.js",
Expand Down

0 comments on commit 804d72c

Please sign in to comment.