Resolve issue with readLazyAssembly returning stale value (#26642)
* Resolve issue with readLazyAssembly returning stale value * Address feedback from peer review * Update test to exercise loaded package
This commit is contained in:
parent
8118a25e7f
commit
84e9f56bca
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -334,6 +334,10 @@ function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourceLoade
|
||||||
return BINDING.js_to_mono_obj(Promise.resolve(0));
|
return BINDING.js_to_mono_obj(Promise.resolve(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lazyResources: {
|
||||||
|
assemblies?: (ArrayBuffer | null)[],
|
||||||
|
pdbs?: (ArrayBuffer | null)[]
|
||||||
|
} = {};
|
||||||
window['Blazor']._internal.getLazyAssemblies = (assembliesToLoadDotNetArray: System_Array<System_String>): System_Object => {
|
window['Blazor']._internal.getLazyAssemblies = (assembliesToLoadDotNetArray: System_Array<System_String>): System_Object => {
|
||||||
const assembliesToLoad = BINDING.mono_array_to_js_array<System_String, string>(assembliesToLoadDotNetArray);
|
const assembliesToLoad = BINDING.mono_array_to_js_array<System_String, string>(assembliesToLoadDotNetArray);
|
||||||
const lazyAssemblies = resourceLoader.bootConfig.resources.lazyAssembly;
|
const lazyAssemblies = resourceLoader.bootConfig.resources.lazyAssembly;
|
||||||
|
|
@ -364,31 +368,40 @@ function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourceLoade
|
||||||
.map(assembly => resourceLoader.loadResource(assembly, `_framework/${assembly}`, lazyAssemblies[assembly], 'assembly'))
|
.map(assembly => resourceLoader.loadResource(assembly, `_framework/${assembly}`, lazyAssemblies[assembly], 'assembly'))
|
||||||
.map(async resource => (await resource.response).arrayBuffer()));
|
.map(async resource => (await resource.response).arrayBuffer()));
|
||||||
|
|
||||||
|
|
||||||
return BINDING.js_to_mono_obj(
|
return BINDING.js_to_mono_obj(
|
||||||
Promise.all([resourcePromises, pdbPromises]).then(values => {
|
Promise.all([resourcePromises, pdbPromises]).then(values => {
|
||||||
const resourcesToLoad = values[0];
|
lazyResources["assemblies"] = values[0];
|
||||||
const pdbsToLoad = values[1];
|
lazyResources["pdbs"] = values[1];
|
||||||
if (resourcesToLoad.length) {
|
if (lazyResources["assemblies"].length) {
|
||||||
window['Blazor']._internal.readLazyAssemblies = () => {
|
window['Blazor']._internal.readLazyAssemblies = () => {
|
||||||
const assemblyBytes = BINDING.mono_obj_array_new(resourcesToLoad.length);
|
const { assemblies } = lazyResources;
|
||||||
for (let i = 0; i < resourcesToLoad.length; i++) {
|
if (!assemblies) {
|
||||||
const assembly = resourcesToLoad[i] as ArrayBuffer;
|
return BINDING.mono_obj_array_new(0);
|
||||||
|
}
|
||||||
|
const assemblyBytes = BINDING.mono_obj_array_new(assemblies.length);
|
||||||
|
for (let i = 0; i < assemblies.length; i++) {
|
||||||
|
const assembly = assemblies[i] as ArrayBuffer;
|
||||||
BINDING.mono_obj_array_set(assemblyBytes, i, BINDING.js_typed_array_to_array(new Uint8Array(assembly)));
|
BINDING.mono_obj_array_set(assemblyBytes, i, BINDING.js_typed_array_to_array(new Uint8Array(assembly)));
|
||||||
}
|
}
|
||||||
return assemblyBytes;
|
return assemblyBytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
window['Blazor']._internal.readLazyPdbs = () => {
|
window['Blazor']._internal.readLazyPdbs = () => {
|
||||||
const pdbBytes = BINDING.mono_obj_array_new(resourcesToLoad.length);
|
const { assemblies, pdbs } = lazyResources;
|
||||||
for (let i = 0; i < resourcesToLoad.length; i++) {
|
if (!assemblies) {
|
||||||
const pdb = pdbsToLoad && pdbsToLoad[i] ? new Uint8Array(pdbsToLoad[i] as ArrayBufferLike) : new Uint8Array();
|
return BINDING.mono_obj_array_new(0);
|
||||||
|
}
|
||||||
|
const pdbBytes = BINDING.mono_obj_array_new(assemblies.length);
|
||||||
|
for (let i = 0; i < assemblies.length; i++) {
|
||||||
|
const pdb = pdbs && pdbs[i] ? new Uint8Array(pdbs[i] as ArrayBufferLike) : new Uint8Array();
|
||||||
BINDING.mono_obj_array_set(pdbBytes, i, BINDING.js_typed_array_to_array(pdb));
|
BINDING.mono_obj_array_set(pdbBytes, i, BINDING.js_typed_array_to_array(pdb));
|
||||||
}
|
}
|
||||||
return pdbBytes;
|
return pdbBytes;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return resourcesToLoad.length;
|
return lazyResources["assemblies"].length;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
||||||
// Visit the route for the lazy-loaded assembly
|
// Visit the route for the lazy-loaded assembly
|
||||||
SetUrlViaPushState("/WithLazyAssembly");
|
SetUrlViaPushState("/WithLazyAssembly");
|
||||||
|
|
||||||
var button = app.FindElement(By.Id("use-package-button"));
|
var button = Browser.Exists(By.Id("use-package-button"));
|
||||||
|
|
||||||
// Now we should have requested the DLL
|
// Now we should have requested the DLL
|
||||||
Assert.True(HasLoadedAssembly("Newtonsoft.Json.dll"));
|
Assert.True(HasLoadedAssembly("Newtonsoft.Json.dll"));
|
||||||
|
|
@ -100,11 +100,11 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
||||||
// Now the assembly has been loaded
|
// Now the assembly has been loaded
|
||||||
Assert.True(HasLoadedAssembly("LazyTestContentPackage.dll"));
|
Assert.True(HasLoadedAssembly("LazyTestContentPackage.dll"));
|
||||||
|
|
||||||
var button = app.FindElement(By.Id("go-to-lazy-route"));
|
var button = Browser.Exists(By.Id("go-to-lazy-route"));
|
||||||
button.Click();
|
button.Click();
|
||||||
|
|
||||||
// Navigating the lazy-loaded route should show its content
|
// Navigating the lazy-loaded route should show its content
|
||||||
var renderedElement = app.FindElement(By.Id("lazy-page"));
|
var renderedElement = Browser.Exists(By.Id("lazy-page"));
|
||||||
Assert.True(renderedElement.Displayed);
|
Assert.True(renderedElement.Displayed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,6 +123,39 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
||||||
AssertLogContainsCriticalMessages("DoesNotExist.dll must be marked with 'BlazorWebAssemblyLazyLoad' item group in your project file to allow lazy-loading.");
|
AssertLogContainsCriticalMessages("DoesNotExist.dll must be marked with 'BlazorWebAssemblyLazyLoad' item group in your project file to allow lazy-loading.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanLazyLoadViaLinkChange()
|
||||||
|
{
|
||||||
|
// Navigate to a page without any lazy-loaded dependencies
|
||||||
|
SetUrlViaPushState("/");
|
||||||
|
var app = Browser.MountTestComponent<TestRouterWithLazyAssembly>();
|
||||||
|
|
||||||
|
// We start off with no lazy assemblies loaded
|
||||||
|
Assert.False(HasLoadedAssembly("LazyTestContentPackage.dll"));
|
||||||
|
Assert.False(HasLoadedAssembly("Newtonsoft.Json.dll"));
|
||||||
|
|
||||||
|
// Click the first link and verify that it worked as expected
|
||||||
|
var lazyAssemblyLink = Browser.Exists(By.Id("with-lazy-assembly"));
|
||||||
|
lazyAssemblyLink.Click();
|
||||||
|
var pkgButton = Browser.Exists(By.Id("use-package-button"));
|
||||||
|
Assert.True(HasLoadedAssembly("Newtonsoft.Json.dll"));
|
||||||
|
pkgButton.Click();
|
||||||
|
|
||||||
|
// Navigate to the next page and verify that it loaded its assembly
|
||||||
|
var lazyRoutesLink = Browser.Exists(By.Id("with-lazy-routes"));
|
||||||
|
lazyRoutesLink.Click();
|
||||||
|
Browser.Exists(By.Id("lazy-load-msg"));
|
||||||
|
Assert.True(HasLoadedAssembly("LazyTestContentPackage.dll"));
|
||||||
|
|
||||||
|
// Interact with that assembly to ensure it was loaded properly
|
||||||
|
var button = Browser.Exists(By.Id("go-to-lazy-route"));
|
||||||
|
button.Click();
|
||||||
|
|
||||||
|
// Navigating the lazy-loaded route should show its content
|
||||||
|
var renderedElement = Browser.Exists(By.Id("lazy-page"));
|
||||||
|
Assert.True(renderedElement.Displayed);
|
||||||
|
}
|
||||||
|
|
||||||
private string SetUrlViaPushState(string relativeUri)
|
private string SetUrlViaPushState(string relativeUri)
|
||||||
{
|
{
|
||||||
var pathBaseWithoutHash = ServerPathBase.Split('#')[0];
|
var pathBaseWithoutHash = ServerPathBase.Split('#')[0];
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@
|
||||||
<li><NavLink href="/subdir/WithParameters/Name/Abc/LastName/McDef">With more parameters</NavLink></li>
|
<li><NavLink href="/subdir/WithParameters/Name/Abc/LastName/McDef">With more parameters</NavLink></li>
|
||||||
<li><NavLink href="/subdir/LongPage1">Long page 1</NavLink></li>
|
<li><NavLink href="/subdir/LongPage1">Long page 1</NavLink></li>
|
||||||
<li><NavLink href="/subdir/LongPage2">Long page 2</NavLink></li>
|
<li><NavLink href="/subdir/LongPage2">Long page 2</NavLink></li>
|
||||||
<li><NavLink href="/subdir/WithLazyAssembly">With lazy assembly</NavLink></li>
|
<li><NavLink href="/subdir/WithLazyAssembly" id="with-lazy-assembly">With lazy assembly</NavLink></li>
|
||||||
|
<li><NavLink href="/subdir/WithLazyLoadedRoutes" id="with-lazy-routes">With lazy loaded routes</NavLink></li>
|
||||||
<li><NavLink href="PreventDefaultCases">preventDefault cases</NavLink></li>
|
<li><NavLink href="PreventDefaultCases">preventDefault cases</NavLink></li>
|
||||||
<li><NavLink>Null href never matches</NavLink></li>
|
<li><NavLink>Null href never matches</NavLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue