-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Update RCL template to use 5.0 features #25613
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
Update RCL template to use 5.0 features #25613
Conversation
| public ExampleJsInterop(IJSRuntime jsRuntime) | ||
| { | ||
| moduleTask = jsRuntime.InvokeAsync<IJSObjectReference>( | ||
| "import", "./_content/Company.RazorClassLibrary1/exampleJsInterop.js").AsTask(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so nice!
I agree
This is something I've been giving some thought to with regards to things like prerendering. Doing things like that in the constructor is problematic, so we should think of ways of improving that in the future. Right now we tell you to do JS interop within OnAfterRender and we "bail out" after that, but I've come up with situations where that is just not enough (like when using DI to inject the JS runtime or when you want to do something during OnInitializedAsync). I think what we have for 5.0 is great, but we should revisit some of these things in 6.0 to make folks more successful. As I said, it looks great for 5.0 |
That's a really good point. I've updated the implementation to use It's a bit more boilerplate code, so adds further to the argument for having a base class in the future. |
|
Hello human! Please make sure you've included the Shiproom Template in a comment or (preferably) the PR description. Also, make sure this PR is not marked as a draft and is ready-to-merge. |
|
@Pilchie Can this be approved for RC2? |
|
Approved for .NET 5.0 RC2, but has a conflict that needs to be resolved. |
7a0a1f1 to
6bc0978
Compare
|
@mkArtakMSFT Ready to merge. |
Note This PR is based on
javiercn/css-isolation-follow-ups, not because I actually want to merge into that branch, but because it builds on functionality added in #25565 and can't be merged until that one is.Description
This PR improves the Razor Class Library template to use 5.0 features:
<link>tag for the library's styles - it's auto-bundled.<script>tag for the library's JS - it's auto-loaded on demand.Customer Impact
Makes clear how the 5.0 features are meant to be used in RCLs, and avoids the weirdness of shipping an RCL template that inexplicably fails to use the features that are obviously designed for this scenario.
Regression
No
Risk
As long as we actually do some verification on this, very low chance of causing any bugs.
Design note
It does make the
ExampleJsInterop.cscode quite a bit longer and involves more concepts.Previously it was just a few-lines-long
staticfunction you could invoke and pass in anIJSRuntimeinstance, and it relied on the associated.jsfile already being loaded in the global namespace. The new version is set up to be used as a DI service (not astatic) and contains code to lazy-load the associated.jsfile.I've made it an
IAsyncDisposablebecause you could think of it as a good practice to remind people thatIJSObjectReferenceinstances areIAsyncDisposable. In practice, as long asExampleJsInteropis consumed as a scoped or singleton instance, there would be no need ever to dispose the lazy-loaded JS module so it's kind of redundant, but I think we should do it like I have here in order to be more risk averse and not set a bad example that disposability can be ignored.On balance I think the new version of
ExampleJsInterop.csis more useful than the previous one and guides people to be more successful, so it's worth the extra 20 lines of code there.Design note 2
Most of the lines of code in
ExampleJsInterop.cscould be factored out into an abstract base class, e.g.,JSModuleBase. This could contain methods likeInvokeAsync(...)etc. that pass through the call to(await ModuleTask).InvokeAsync(...)so you wouldn't even have to think about awaiting the module load. This base class constructor would take care of callingimport, and obviously it could deal withIAsyncDisposabletoo. Then the developer's own code could be reduced to something like:Not suggesting we do that right now, but if customers start using JS modules a lot, it might be worth thinking as a feature for 6.0.