yesodweb / yesod

A RESTful Haskell web framework built on WAI.
http://www.yesodweb.com/
MIT License
2.61k stars 367 forks source link

Use Purescript #1377

Open mac10688 opened 7 years ago

mac10688 commented 7 years ago

I want to use purescript for my front end, but I'm trying to figure out how to integrate this with Devel.

I looked at yesod-purescript but it's not being maintained anymore. The author recommends using another tool.

Pulp which is a build tool for purescript.

How do I integrate a pulp build script with devel? Are there other tips to provide?

Thanks

jezen commented 7 years ago

Not sure if this is of any use to you, but I'm loading a compiled Elm script in a page in Yesod. My template is at templates/dashboard.hamlet, and Elm outputs the compiled JavaScript at templates/dashboard.julius. This works, but now compilation for the Dashboard handler takes a long time. It might just be a case of using a js extension instead of julius. I stumbled upon your question because this slow compile time is exactly what I'm investigation right now.

paul-rouse commented 7 years ago

I have been doing a decent sized project using PureScript and Halogen for the front end, and Yesod on the server. (To be strict, Yesod is actually only used during development, since the final product is a single page application served statically, but that doesn't diminish Yesod's very valuable contribution - I'll try to write it up on the blog when the dust has settled.)

To get a little closer to answering your question, I opted for building the PureScript code separately, and linking to the single, browserified, minified JavaScript file from the Yesod template. Quite a lot of data is inserted into templates by Yesod, for use by the PureScript code. It is all combined into one large JavaScript object, with a global name, which is referenced by a PureScript foreign. Of course that's the one weak point, and I had to use add-hoc scripts to check that the shape of the JavaScript object constructed by Yesod matched the PureScript declaration of it.

This worked well for my SPA architecture, but wouldn't be so good if you needed multiple, smaller PureScript modules. We do plan to make the source code available, and write up the experience, but meanwhile, if it gives you any encouragement to continue with PureScript (and perhaps Halogen), do have a look at at the result: expo.neumes.org.uk (the large screen version, which requires at least 1680x1050).

arrowd commented 4 years ago

Was there any progress on this front?

paul-rouse commented 4 years ago

Well, I never got round to writing a blog article, if that's what you mean.

I have now got another project under way, rewriting the client side of an existing Yesod project using Purescript and Halogen. Again the client code is a single-page application, built as a single, static file which is delivered by Yesod. Yesod also provides the JSON API for it.

I am not quite sure what you are looking for, but I would be happy to answer questions if you can be more specific!

arrowd commented 4 years ago

@paul-rouse So, you first call purs to generate HTML/JS files, then drop then into Yesod's static directory and then cabal build/stack build?

I was thinking about some quasiquoter that would handle calling purescript compiler for me.

paul-rouse commented 4 years ago

Yes, that's the pattern. Most of the time in development only one or the other (Purescript or Haskell) needs to be rebuilt, except when the API changes. Bear in mind that what I'm doing is a single-page application, so my Purescript compiles to just one, large JS file. Once started on the client, the application is in control of the UI, complete with client-side routing, and only uses Yesod as an API server. (I am using Yesod mainly for historical reasons, and you could argue its full power is no longer being used, but I think it still has value.)

It sounds as if you are thinking more in terms of adding small snippets of Purescript to a Yesod project, in much the same way that Julius templates provide small javascript snippets. I don't know of a complete solution like that geared around Yesod, but if you are going to write something, it might be worth looking at purescript-bridge, which is used in servant-purescript. (There is an extremely old yesod-purescript package on hackage, but the github repository no longer exists.)

dariooddenino commented 3 years ago

My frontend is made of various halogen widgets. What I'm doing is exposing their mount function from my purs main, and then I have a Yesod widget which is basically


halogenWidget :: ToJSON a => WidgetName -> HtmlSelector -> a -> Widget
halogenWidget name id_ payload =
  toWidget [julius|
(function($) { 
  $(function() {
    window.psWidgets.#{rawJS name}.mount('#{rawJS id_}')(#{toJSON payload})()
  }
})(jQuery)
|]