-
Notifications
You must be signed in to change notification settings - Fork 147
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
Add Server-Side Rendering (SSR) #306
Conversation
Looks I forgot the ui test, I'll fix it tommorow or several days later... |
Seems like the helper is needed, other users mention it. This is because of how browser work, the solution used by react, is to create a custom "link" element. Idea being, the helper is included by default in the custom "link" so usage is transparent. |
can you please change it to the nuget package? |
@forki Just planning to do it. 😉 |
@forki Updated to nuget packages. I also tried some configuration in dotnet-watch to ignore client files in develop running, but have no luck: <?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<IsWatch Condition="'$(Configuration)' != 'DebugSSR'">false</IsWatch>
</PropertyGroup>
<ItemGroup>
<Compile Include="../Client/ReleaseNotes.fs" Watch="$(IsWatch)" />
<Compile Include="../Client/Pages.fs" Watch="$(IsWatch)" />
<Compile Include="../Client/Style.fs" Watch="$(IsWatch)" />
<Compile Include="../Client/views/Menu.fs" Watch="$(IsWatch)" />
<Compile Include="../Client/pages/Home.fs" Watch="$(IsWatch)" />
<Compile Include="../Client/pages/WishList.fs" Watch="$(IsWatch)" />
<Compile Include="../Client/pages/Login.fs" />
<Compile Include="../Client/Shared.fs" Watch="$(IsWatch)" />
</ItemGroup>
</Project> Edit: set to <ItemGroup>
<Compile Include="../Client/ReleaseNotes.fs" Watch="false" />
</ItemGroup> |
@@ -216,6 +217,30 @@ Target "Run" (fun _ -> | |||
) | |||
|
|||
|
|||
Target "RunSSR" (fun _ -> | |||
runDotnet clientPath "restore" |
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.
why do we need this? what is it doing?
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 will set a compile directive DEBUG_SSR
to use webpack-dev-server's bundle file path in the server-rendered path. Ideally, in RunSSR
we can trigger client and server to rebuild when we edit any file, so we can dev and debug with SSR; but in normal Run
we would only trigger the server to rebuild when we edit back-end files, and we can dev with webpack-dev-server and use the server code as an API service.
But I cannot pass the configuration
to dotnet-watch to make it work differently in different command, currently, I totally ignored client files' change when watch run
the server...
https://github.com/SAFE-Stack/SAFE-BookStore/pull/306/files#diff-694c6c636cd70bcc23aa716434744995R12
https://github.com/SAFE-Stack/SAFE-BookStore/pull/306/files#diff-3b3c3fd8d4441c71716037ce14cb42b0R14
can you please rebase/merge with master |
@forki Done. |
paket.dependencies
Outdated
nuget Fable.Elmish.Debugger | ||
nuget Fable.Elmish.React | ||
nuget Fable.Elmish.HMR | ||
nuget Fable.React 3.0.0-alpha-002 |
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.
@alfonsogarciacaro any timeline on when these things get released?
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.
The Fable.React 3 stablish version? At the end we're not going to touch more the API so I guess we can do it now (this PR is pending though). I'll have to make some minor but potentially breaking changes for Fable 2, but we can bump another major version then.
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.
For the PR you linked, I think a new nuget should be created.
Bumping the major version for Fable 2, is ok no need to hold the prerelease for it I think.
nuget Fable.Elmish 2.0.0-beta-2 are these things released properly? @MangelMaxime @et1975 any chance for a release? |
@zaaack what's that package-lock.json file? |
@forki I'm afraid not, these prerelease versions are added to using this PR: elmish/react#19
Probably is added when I ran UITest locally... |
@zaaack yes I'd rather not depend on prereleases for public sample |
@zaaack The Perhaps there is a call somewhere to @forki I am currently porting my work app to the latest prerelease version. Problem, is if we want people to understand how to use this new version we need some more documentation. @vbfox Should be working on a third article in it Fable + React series, explaining how to write the view functions with Elmish to benefit of react optimization. IMO, we need to address this lack of documenation before releasing a stable version. |
@MangelMaxime I'm very much in favor of extending docs - but if we don't break stuff then we should still release the versions and extend the samples. It's always bad to have samples on prereleases |
@zaaack this PR does not run SSR on normal build or does it? what hapens if I do just "build.cmd"? |
@forki We are breaking stuff :) The major breaking change being: arguments order has been reversed in view and update function |
yes just saw that. how about minor then? with the hydrate stuff? |
@forki Just did some refactoring for
Neither of these would auto restart your server when you edit your client files. |
well I'm not talking about dev mode. I'm talking about the "build.cmd Deploy" |
is it possible to start a command in SSR? |
@zaaack in my app I have to kick of a bunch of actions after the page is served. Like loading a map and showing current pos |
@forki Not really, you can start any command you like, but they would be ignored in SSR. However, here have |
I'm assuming the map component is written in js native, and imported by FFI, these native component cannot be rendered in SSR. Also including fetch api based on FFI, unless you are using some isomorphic http client library like this:haf/Http.fs#142 If this land I think we can figure out a way to run some initial fetch commands in SSR. |
Looks Travis ci need a rerun again. |
@zaaack I don't want them to be rendered server side. I just want that command to spin off after the client loaded the bundle. |
@forki Just add commands in your |
oh crazy. that works! |
I think I'm ready to take it in. what are others saying? |
still hoping we can find a way without cookies. It's such a hard thing in the EU |
@forki This really depends on your needs. If you don't use cookies to store the login state, then the login state won't be auto carried when requesting pages, so SSR won't get the login state and render it. As far as I know, the most use case of SSR is SEO, pages need login are actually not much need to be rendered on the server side. For SAFE-BookStore, then there only remains the home page's SSR makes sense if we don't use cookies, I can remove login/wishList's SSR if you want. |
tbh I think that's what we should do. restrict it to when it's logged out. |
src/Client/App.fs
Outdated
PageModel = HomePageModel }, | ||
Navigation.newUrl (toHash Page.Home) | ||
PageModel = HomePageModel }, | ||
Cmd.batch [ |
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.
don't need to batch here
I just had a look at the infamous EU directive on cookies and it says:
Maybe this can be applied to our case? The tricky part here is the duration of the session (persistent cookies do need user consent), would it be ok if the validity of the token is less than 24 hours for example? |
This look really great. Wondering whether it should be by default or opt-in in SAFE-Template? |
merged! thank you so much @zaaack ! |
SSR from fable-react!
This PR is actually working, however, it is still waiting fable-react been published, and elmish-react's
withReactHydrate
to be merged and published. Currently, it's using paket's GitHub dependences feature.What's more, here are some breaking changes to add SSR:
Urls are
path
nothash
anymore, which means we would create more routes for each page. Also, click on a direct links would cause a browser refresh which not in the oldhash
urls, I added a helper function to executeElmish.Browser.Navigation.Navigation.newUrl
directly to avoid it, but not sure it's right. @MangelMaximeAdd jwt to cookies to make SSR support rendering login state, but I didn't remove the jwt in localStorage, this might cause problems...
Because the Server project is now depending on the Client project's files, edit view files would trigger the server to rebuild which takes too long. Perhaps we can optimize the development process, e.g. adding a fake target which only builds Server project when files in the Server folder changes?