Skip to content

Conversation

@susnux
Copy link
Contributor

@susnux susnux commented Dec 9, 2025

Summary

Currently apps are broken if they have exports in the JS entry point, because they then will import from the entry point but because they do not know about the Nextcloud cache buster they will import without cache buster.

This results in two problem:

  1. The module might be outdated (old cached)
  2. The module is duplicated, so the module will be loaded twice and will have two different - out of sync - states. This also means it will re-run sideeffects of the entry point.

To fix this we generate an import map which basically maps the plain entry point script to the script with cache buster added.

Why this can happen?
If we want to reduce chunks the bundler can include exports from submodules into entry points and thus reduce the number of files. This is more performant on the web so this is a valid reason.


For example:

// entry.mjs
console.error('called')

async function onClick() {
  await import('./chunk.mjs')
}

export const name = 'foo'

// chunk.mjs
import { name } from './entry.mjs'

console.error(name)

When calling onClick without this fix the output will be:

called
called
foo

With this fix:

called
foo

Checklist

@susnux susnux added this to the Nextcloud 33 milestone Dec 9, 2025
@susnux susnux requested a review from a team as a code owner December 9, 2025 23:07
@susnux susnux requested review from Altahrim, CarlSchwan, ShGKme, artonge, come-nc, icewind1991 and leftybournes and removed request for a team, Altahrim and icewind1991 December 9, 2025 23:07
susnux added a commit to nextcloud/end_to_end_encryption that referenced this pull request Dec 9, 2025
Vite will try to minimize the number of chunks to increase performance,
but this will inline chunks in the entry point and thus adding exports
that can be imported by other modules causing the entry point to be
re-evaluated.
So we need to disabled this until fixed in server:
- ref: nextcloud/server#56941

Signed-off-by: Ferdinand Thiessen <[email protected]>
Currently apps are broken if they have exports in the JS entry point,
because they then will import from the entry point but because they do
not know about the Nextcloud cache buster they will import without cache
buster.

This results in two problem:
1. The module might be outdated (old cached)
2. The module is duplicated, so the module will be loaded twice and will
   have two different - out of sync - states. This also means it will
   re-run sideeffects of the entry point.

To fix this we generate an import map which basically maps the plain
entry point script to the script with cache buster added.

(Some background: Bundler will try to minimize chunks (reduce page
loading time) so they can inline modules into entry points and thus
extend the entry point exports and then this issue would be caused).

For example:
```js
// entry.mjs
console.error('called')

async function onClick() {
  await import('./chunk.mjs')
}

export const name = 'foo'

// chunk.mjs
import { name } from './entry.mjs'

console.error(name)
```

When calling `onClick` without this fix the output will be:
> called
> called
> foo

With this fix:
> called
> foo

Signed-off-by: Ferdinand Thiessen <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants