Digest dynamic/async imports in javascript assets #6003
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
esbuild supports ES6 dynamic module imports, but they're not currently compatible with the
mix phx.digest
process as the import paths aren't digested.This PR adds support for digesting any async and promise based imports inside a JS file, so a developer can use these without giving up cache busting, etc. Dynamic imports are great for front end performance as expensive libraries can be loaded on-demand rather than up front.
Before this PR, the following code would be the same after
mix phx.digest
runs. A digested file will load a non-digestedother-module.js
, and so not benefit from cache busting, etc.After this PR
mix phx.digest
will switch the import path for the digested path, e.g.Note: esbuild in Phoenix doesn't use async imports out of the box, it need to be enabled by changing the args to include following flags:
--chunk-names=js/chunks/[name]-[hash] --splitting --format=esm
. (Technically, it does, but the promise just resolves instantly to content that's in the same file.) I think there's an argument for changing the default flags to do this, but I understand if that might add more complexity than desired to the default asset pipeline.I think there is value in supporting dynamic imports in the digester even if we don't flip the defaults, because it allows users who want to implement their own esbuild config to benefit from splitting + dynamic imports, without having to throw out the Phoenix digesting process entirely. Throwing out the Phoenix digest process is fairly annoying, as it means finding a solution for digesting the non-JS assets, which esbuild doesn't really support.
This PR doesn't digest any static chunk imports, eg.
import { foo } from "./chunks/chunk-abcdef.js"
. These already have a hash appended and so the benefit would mostly aesthetic, but it's probably still worth implementing to minimise any surprises.Anyway, let me know what you think and whether this is something you'd like to add to Phoenix. If there's support for it, I suggest I add some documentation, support for chunk imports and handle the optional
options
argument thatimport()
can support.