Skip to content
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

fix encoding of chunks, fix chunk (re)loading for css #6424

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

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

Original file line number Diff line number Diff line change
Expand Up @@ -1290,7 +1290,10 @@ function getOrInstantiateRuntimeModule(
* Returns the URL relative to the origin where a chunk can be fetched from.
*/
function getChunkRelativeUrl(chunkPath: ChunkPath): string {
return `${CHUNK_BASE_PATH}${chunkPath}`;
return `${CHUNK_BASE_PATH}${chunkPath}`
.split("/")
.map((p) => encodeURIComponent(p))
.join("/");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ async function loadWebAssemblyModule(

// [TODO] need to match behavior as similar to UrlAssetReference
function resolveAbsolutePath(modulePath?: string) {
throw new Error('resolveAbsolutePath is not implemented in the DOM runtime');
throw new Error("resolveAbsolutePath is not implemented in the DOM runtime");
}

(() => {
Expand Down Expand Up @@ -97,7 +97,9 @@ function resolveAbsolutePath(modulePath?: string) {
const chunkUrl = getChunkRelativeUrl(chunkPath);

if (chunkPath.endsWith(".css")) {
const links = document.querySelectorAll(`link[href="${chunkUrl}"]`);
const links = document.querySelectorAll(
`link[href="${chunkUrl}"],link[href^="${chunkUrl}?"]`
);
for (const link of Array.from(links)) {
link.remove();
}
Expand All @@ -106,7 +108,9 @@ function resolveAbsolutePath(modulePath?: string) {
// runtime once evaluated.
// However, we still want to remove the script tag from the DOM to keep
// the HTML somewhat consistent from the user's perspective.
const scripts = document.querySelectorAll(`script[src="${chunkUrl}"]`);
const scripts = document.querySelectorAll(
`script[src="${chunkUrl}"],script[src^="${chunkUrl}?"]`
);
for (const script of Array.from(scripts)) {
script.remove();
}
Expand All @@ -122,15 +126,10 @@ function resolveAbsolutePath(modulePath?: string) {
return;
}

const encodedChunkPath = chunkPath
.split("/")
.map((p) => encodeURIComponent(p))
.join("/");

const chunkUrl = getChunkRelativeUrl(encodedChunkPath);
const chunkUrl = getChunkRelativeUrl(chunkPath);

const previousLinks = document.querySelectorAll(
`link[rel=stylesheet][href^="${chunkUrl}"]`
`link[rel=stylesheet][href="${chunkUrl}"],link[rel=stylesheet][href^="${chunkUrl}?"]`
);

if (previousLinks.length == 0) {
Expand Down Expand Up @@ -230,28 +229,50 @@ function resolveAbsolutePath(modulePath?: string) {
const chunkUrl = getChunkRelativeUrl(chunkPath);

if (chunkPath.endsWith(".css")) {
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = chunkUrl;
link.onerror = () => {
resolver.reject();
};
link.onload = () => {
const previousLinks = document.querySelectorAll(
`link[rel=stylesheet][href="${chunkUrl}"],link[rel=stylesheet][href^="${chunkUrl}?"]`
);
if (previousLinks.length > 0) {
// CSS chunks do not register themselves, and as such must be marked as
// loaded instantly.
resolver.resolve();
};
document.body.appendChild(link);
} else {
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = chunkUrl;
link.onerror = () => {
resolver.reject();
};
link.onload = () => {
// CSS chunks do not register themselves, and as such must be marked as
// loaded instantly.
resolver.resolve();
};
document.body.appendChild(link);
}
} else if (chunkPath.endsWith(".js")) {
const script = document.createElement("script");
script.src = chunkUrl;
// We'll only mark the chunk as loaded once the script has been executed,
// which happens in `registerChunk`. Hence the absence of `resolve()` in
// this branch.
script.onerror = () => {
resolver.reject();
};
document.body.appendChild(script);
const previousScripts = document.querySelectorAll(
`script[src="${chunkUrl}"],script[src^="${chunkUrl}?"]`
);
if (previousScripts.length > 0) {
// There is this edge where the script already failed loading, but we
// can't detect that. The Promise will never resolve in this case.
for (const script of Array.from(previousScripts)) {
script.addEventListener("error", () => {
resolver.reject();
});
}
} else {
const script = document.createElement("script");
script.src = chunkUrl;
// We'll only mark the chunk as loaded once the script has been executed,
// which happens in `registerChunk`. Hence the absence of `resolve()` in
// this branch.
script.onerror = () => {
resolver.reject();
};
document.body.appendChild(script);
}
} else {
throw new Error(`can't infer type of chunk from path ${chunkPath}`);
}
Expand Down

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

Loading
Loading