Three Ways Manage Resources Websharper FSharp

Jun 14th, 2016 - written by Kimserey with .

WebSharper official documentation can be found here http://websharper.com/docs/resources. The doc focus more on how to reference resources for Sitelets so today, I will explain how you can reference your own js and css file and explore the different ways available to make the SPA of your dreams.

There are three ways to reference files:

  1. Reference an external resource through url
  2. Reference a resource served from your own server
  3. Bundle your resources in the WebSharper compiled JS and CSS

If we take a look at the files generated by a SPA under \Content we should see:

1
2
3
4
5
6
7
\Content
    |
    |-- MyApp.js
    |-- MyApp.min.js
    |-- MyApp.css
    |-- MyApp.Head.js
    |-- MyApp.Head.html

MyApp.js and MyApp.min.js are the WebSharper generated JS from our F# code. MyApp.css, MyApp.Head.js and MyApp.Head.html contain the content extracted from our resources. Each of this file is loaded in the index.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
    <title>MyApp</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" type="text/css" href="Content/MyApp.css" />
    <script type="text/javascript" src="Content/MyApp.head.js"></script>
</head>
<body>
    <script type="text/javascript" src="Content/MyApp.js"></script>
</body>
</html>

So let’s see how they are generated and how they are used.

1. Reference an external resource through url

The basic of referencing resources is to inherit from BaseResource type from WebSharper.Resources and use it together with the Require attribute.

Let say we want to reference https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css. That’s how we would reference it:

1
2
3
4
5
6
7
8
open WebSharper.Resources

module Resources =
    type Bootstrap() =
        inherit BaseResource("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css")

    [<assembly:Require(typeof<Bootstrap>)>]
    do()

We first open WebSharper.Resources and then create a type Bootstrap (the name doesn’t matter) which inherit from BaseResource and give as argument the absolute url. Then we specify that the SPA requires this resource by adding some code with the attribute Require(typeof<Bootstrap>).

This piece of code will instruct WebSharper to add the link <link type="text/css" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> to the head of our index.html. If we inspect MyApp.Head.js we should find a JS code that insert the link tag into the document.

So if you need to reference an external resource, pass the absolute url to BaseResource and WebSharper will add the link tag for you in the head of your index.html.

2. Reference a resource served from your own server

For resources served by your own server, you need to pass a relative url to BaseResource.

1
2
type MyOwnCss() =
    inherit BaseResource("css/myowncss.css")

The result should be the same as explained in 1.

So if you need to reference a resource served by your own server, pass a relative url and WebSharper will add the link tag for you in the head of your index.html.

Side note - copy embedded resources to \Content

If you have embedded resources and you want it to be copied to the \Content folder along with the WebSharper generated files, you must add the attribute assembly:System.Web.UI.WebResource("file name", "mime type"); This will tell WebSharper that you have an embedded resource and that you want it to be extracted and copied into the \Content folder.

3. Bundle your resources in the WebSharper compiled JS and CSS

Even though you can reference files through relative url as explained in 2., there is a better way of handling your own resource - bundle the js and css into your app.js and app.css. This is really helpful if you have multiples JS files referenced and you want to bundle it all into a single JS file (same for your CSS). In order to do that, you must first add your JS files to your project and set it as embedded resources. After that, create your resource types and pass to BaseResource the file name.

1
2
3
4
5
6
7
8
9
module Resources =
    type Css() =
        inherit BaseResource("myapp.css")
    type Js() =
        inherit BaseResource("myapp.js")
        
    [<assembly:Require(typeof<Css>);
      assembly:Require(typeof<Js>)>]
    do()

By doing that, the JS will be bundled inside your main JS MyApp.js and the CSS will be bundled into MyApp.css under the \Content folder. So if you have 100 JS files, WebSharper will bundle it automatically under the same MyApp.js.

Fast forward

  • Use BaseResource to add the correct link and script tags to the head (1. - 2.)
  • Use assembly:System.Web.UI.WebResource to copy embedded resources to the \Content folder (2.)
  • Use embedded resources and BaseResource to bundle the JS and CSS with the WebSharper generated JS and CSS (3.)

Conclusion

WebSharper comes with a bundling functionality out of the box. It is not advertise in the documentation but it is extremely usefull. Also, managing dependency from a F# file is so much more appealing than having html tags cluttered in index.html. I hope this helped you understand better how you can manage your resources and reference it in your SPA. Let me know if this helped you, if you have any question leave a comment here or hit me on Twitter @Kimserey_Lam. See you next time!

Designed, built and maintained by Kimserey Lam.