Skip to content

Commit

Permalink
improve fw lite dx by using vite dev (#1345)
Browse files Browse the repository at this point in the history
* setup services in OnAfterRenderAsync which plays better with server pre rendering

* when an override service is null, remove it from the services object instead of setting it to null

* move invokeOnWindow to new Root component so it's shared between web and Maui, use that instead of Routes in each project

* use vite dev for serving js
  • Loading branch information
hahn-kev authored Jan 8, 2025
1 parent bdace23 commit 72d9840
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 56 deletions.
2 changes: 1 addition & 1 deletion backend/FwLite/FwLiteMaui/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
x:Class="FwLiteMaui.MainPage">
<BlazorWebView x:Name="blazorWebView" HostPage="wwwroot/index.html">
<BlazorWebView.RootComponents>
<RootComponent Selector="#app" ComponentType="{x:Type shared:Routes}"/>
<RootComponent Selector="#app" ComponentType="{x:Type shared:Root}"/>
</BlazorWebView.RootComponents>
</BlazorWebView>

Expand Down
10 changes: 0 additions & 10 deletions backend/FwLite/FwLiteMaui/wwwroot/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,6 @@
<title>FwLiteMaui</title>
<base href="/" />
<link rel="icon" type="image/png" href="_content/FwLiteShared/favicon.png"/>
<script>
window.invokeOnWindow = function (methodName, args) {
if (!(methodName in window)) {
//todo not sure how to handle this for now, maybe we wait until the app is ready?
console.error(`Method ${methodName} not found`);
return;
}
window[methodName](...args);
};
</script>
</head>

<body>
Expand Down
32 changes: 26 additions & 6 deletions backend/FwLite/FwLiteShared/Layout/SvelteLayout.razor
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
@inherits LayoutComponentBase
@using FwLiteShared.Services
@using Microsoft.Extensions.Hosting
@using Microsoft.Extensions.Logging
@inject IJSRuntime JS
@inject ILogger<SvelteLayout> Logger
@inject FwLiteProvider FwLiteProvider
@inject IHostEnvironment Environment;
@implements IAsyncDisposable

<link rel="modulepreload" href="@Assets["_content/FwLiteShared/viewer/svelte-ux.js"]">
<link rel="stylesheet" href="@Assets["_content/FwLiteShared/viewer/index.css"]"/>
@if (useDevAssets)
{
<script type="module" src="http://localhost:5173/@@vite/client"></script>
}
else
{
<link rel="modulepreload" href="@Assets["_content/FwLiteShared/viewer/svelte-ux.js"]">
<link rel="stylesheet" href="@Assets["_content/FwLiteShared/viewer/main.css"]"/>
}
<script>
window['setOverrideService'] = (key, service) => {
window.lexbox ??= {};
Expand All @@ -16,7 +24,11 @@
window.lexbox.DotNetServiceProvider.setOverrideServices(window.lexbox.FwLiteProvider);
}
const services = window.lexbox.FwLiteProvider;
services[key] = service;
if (service) {
services[key] = service;
} else {
delete services[key];
}
};
//called from FwLiteProvider.InjectCrdtProject
window['notifyEntryUpdated'] = (projectName, entry) => {
Expand All @@ -32,6 +44,8 @@
@Body
@code {
private bool useDevAssets => Environment.IsDevelopment();
// private bool useDevAssets => false;
private IJSObjectReference? module;
protected override async Task OnAfterRenderAsync(bool firstRender)
Expand All @@ -44,8 +58,14 @@
await FwLiteProvider.SetService(JS, serviceKey, service);
}
module = await JS.InvokeAsync<IJSObjectReference>("import",
"/" + Assets["_content/FwLiteShared/viewer/index.js"]);
if (useDevAssets)
{
module = await JS.InvokeAsync<IJSObjectReference>("import", "http://localhost:5173/src/main.ts");
} else
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"/" + Assets["_content/FwLiteShared/viewer/main.js"]);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion backend/FwLite/FwLiteShared/Pages/CrdtProject.razor
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@

private IAsyncDisposable? _disposable;

protected override async Task OnInitializedAsync()
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender) return;
var fwLiteProvider = ScopedServices.GetRequiredService<FwLiteProvider>();
_disposable = await fwLiteProvider.InjectCrdtProject(JS, ScopedServices, ProjectName);
}
Expand Down
3 changes: 2 additions & 1 deletion backend/FwLite/FwLiteShared/Pages/FwdataProject.razor
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@

private IAsyncDisposable? _disposable;

protected override async Task OnInitializedAsync()
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender) return;
var fwLiteProvider = ScopedServices.GetRequiredService<FwLiteProvider>();
_disposable = await fwLiteProvider.InjectFwDataProject(JS, ScopedServices, ProjectName);
}
Expand Down
5 changes: 3 additions & 2 deletions backend/FwLite/FwLiteShared/Pages/Home.razor
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
@*this looks empty because it is, but it's required to declare the route which is then used by the svelte router*@
@code
{
protected override async Task OnInitializedAsync()
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await FwLiteProvider.SetService(JS, DotnetService.MiniLcmApi, null);
if (firstRender)
await FwLiteProvider.SetService(JS, DotnetService.MiniLcmApi, null);
}
}
14 changes: 14 additions & 0 deletions backend/FwLite/FwLiteShared/Root.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script>
window.invokeOnWindow = function (methodName, args) {
if (!(methodName in window)) {
//todo not sure how to handle this for now, maybe we wait until the app is ready?
console.error(`Method ${methodName} not found`);
return;
}
window[methodName](...args);
};
</script>
<Routes/>
@code {

}
9 changes: 8 additions & 1 deletion backend/FwLite/FwLiteShared/Routes.razor
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
@inject IJSRuntime jsRuntime
@code {
bool firstNavigation = true;
private async Task OnNavigateAsync(NavigationContext context)
{
await jsRuntime.DurableInvokeVoidAsync("svelteNavigate", context.Path);
if (firstNavigation)
{
firstNavigation = false;
return;
}
if (RendererInfo.IsInteractive)
await jsRuntime.DurableInvokeVoidAsync("svelteNavigate", context.Path);
}
}
<Router AppAssembly="typeof(Layout.SvelteLayout).Assembly" OnNavigateAsync="OnNavigateAsync">
Expand Down
15 changes: 2 additions & 13 deletions backend/FwLite/FwLiteWeb/Components/App.razor
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,11 @@
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<base href="/"/>
<link rel="icon" type="image/png" href="_content/FwLiteShared/favicon.png"/>
<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)"/>
<script>
window.invokeOnWindow = function (methodName, args) {
if (!(methodName in window)) {
//todo not sure how to handle this for now, maybe we wait until the app is ready?
console.error(`Method ${methodName} not found`);
return;
}
window[methodName](...args);
};
</script>
<link rel="icon" type="image/png" href="_content/FwLiteShared/viewer/icon.svg"/>
</head>

<body>
<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)"/>
<Root @rendermode="new InteractiveServerRenderMode(prerender:false)"/>
<script src="_framework/blazor.web.js"></script>
</body>

Expand Down
16 changes: 16 additions & 0 deletions frontend/viewer/src/lib/append-head-hack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
if (import.meta.env.DEV) {
//when in dev mode, svelte and vite want to put style sheets in the head
//however blazor will remove them, so we need to put them in the body instead
// eslint-disable-next-line @typescript-eslint/unbound-method
const headerAppend = document.head.appendChild;
document.head.appendChild = function newAppend<T extends Node>(node: T) {
//this is used for both svelte and vite imports
if (node.nodeName === 'STYLE') {
document.getElementById('svelte-app')?.appendChild(node);
} else {
headerAppend.call(document.head, node);
}
return node;
};
}

9 changes: 2 additions & 7 deletions frontend/viewer/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//*// v1 Run with normal Svelte App (advantages: tailwind classes stay up to date)

import 'vite/modulepreload-polyfill';
import './lib/append-head-hack';
import './app.postcss';

import App from './App.svelte';
Expand All @@ -9,9 +10,3 @@ setupDotnetServiceProvider();
new App({
target: document.getElementById('svelte-app')!,
});

/*/// v2 Run with web-component in shadow dom
import './web-component';
//*/
22 changes: 8 additions & 14 deletions frontend/viewer/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import {svelte} from '@sveltejs/vite-plugin-svelte';
import {svelteTesting} from '@testing-library/svelte/vite';

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
export default defineConfig(({ mode, command }) => {
const webComponent = mode === 'web-component';
return {
base: '/_content/FwLiteShared/viewer',
base: !webComponent && command == "build" ? '/_content/FwLiteShared/viewer' : '/',

build: {
...(webComponent ? {
lib: {
Expand All @@ -16,11 +17,13 @@ export default defineConfig(({ mode }) => {
outDir: 'dist-web-component',
} : {
outDir: '../../backend/FwLite/FwLiteShared/wwwroot/viewer',
manifest: true,
}),
minify: false,
sourcemap: true,
chunkSizeWarningLimit: 1000,
rollupOptions: {
input: webComponent ? undefined : ['src/main.ts'],
output: {
entryFileNames: '[name].js',
chunkFileNames: '[name].js',
Expand All @@ -46,18 +49,9 @@ export default defineConfig(({ mode }) => {
handler(warning);
},
}), svelteTesting()],
...(!webComponent ? {
server: {
open: 'http://localhost:5173/testing/project-view',
proxy: {
'/api': {
target: 'http://localhost:5137',
secure: false,
ws: true
}
}
}
} : {}),
server: {
origin: 'http://localhost:5173',
},
test: {
environment: 'happy-dom',
setupFiles: ['./vitest-setup.js'],
Expand Down

0 comments on commit 72d9840

Please sign in to comment.