Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Welcome to our site

Take a moment to join our board

Sign in to follow this  

Recommended Posts

FSharp Vue SPA Start Guide/Template

While it might not fit in with every situation having a functional language behind you backed, such as fsharp, could be very nice. This guide is not about setting up api handlers, but rather setting up giraffe routing to forward front end related things to the front end. To learn more about the HttpHandlers to go along with the api I would suggest reading up on the Giraffe documentation page

Microsoft has some ASP.NET Core SPA examples which I take some ideas from, but they have some extra stuff I don't wish to implement in this template such as JQuery and Bootstrap. Vue discourages the use of JQuery. I set out to create a good template that I can use later on and hopefully some other people can use it as a starting point. 

Technologies Used:

  • Webpack
    • Hot Module Replacement
    • vue-loader
  • Asp.net Core 2.0
  • Vue
    • vue-router

Prerequisites:

  • dotnet core 2.x
  • nodejs >= 8.9.4
  • VSCode or VS2017 
    • If VSCode Ionide Fsharp extension

Project Setup:

  •  Create a new folder with the name of your Project (FSharpVue in my case)
  • Install Giraffe Template
dotnet new -i "giraffe-template::*"

 

  • Use the Giraffe Template to create some boiler plate code.
dotnet new giraffe -lang F#
  • Navigate into the project folder (src->FSharpVue) and remove WebRoot folder
  • open Program.fs
    • Remove the model and view bit of code under the last open. 
    • Change the web router to use our webpack index file.
      • let webApp =
            choose [
                GET >=>
                    choose [
                        route "/" >=> htmlFile "wwwroot/dist/index.html"
                    ]
                htmlFile "wwwroot/dist/index.html" ]
      • This lets the front end handle any type of non static 404
    • Remove the custom WebRoot references (we will use default wwwroot)
      •  
        let main _ =
            let contentRoot = Directory.GetCurrentDirectory()
            WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(contentRoot)
                .UseIISIntegration()
                .Configure(Action<IApplicationBuilder> configureApp)
                .ConfigureServices(configureServices)
                .ConfigureLogging(configureLogging)
                .Build()
                .Run()
            0

         

    • Add Microsoft.AspNetCore.SpaServices via nuget or paket.

    • open(import) Microsoft.AspNetCore.SpaServices.Webpack

    •  While the application is in development environment use Webpack dev middleware

      • (match env.IsDevelopment() with
            | true  ->
                app.UseWebpackDevMiddleware(
                    WebpackDevMiddlewareOptions(HotModuleReplacement = true,
                                                ConfigFile = "build/webpack.dev.conf.js")) 
                app.UseDeveloperExceptionPage()
            | false -> app.UseGiraffeErrorHandler errorHandler)

          

This is where importing vue project gets dicey, I would argue it is not important to follow this point of the tutorial, but rather just look at how I did it in the attached template. For the most part forward we will just import vue and change a good bit of webpack config. I would not use the following as a guide to webpack, rather just a method of getting by. Though if you would like to follow along to get a better understand on the vue cli and webpack it might be helpful. TBH I don't know webpack the best and @Omicron had to help me out a bit with it. 

  •  Install the vue-cli via npm
    • npm install -g @vue/cli

       

  • In the main project directory create a new vue project with webpack and name it clientapp (to match microsoft template convention)

    • vue init webpack

       

    • ? Project name clientapp
      ? Project description A Vue.js FSharp Template
      ? Author Smallxmac <smallxmac@cooldown.io>
      ? Vue build standalone
      ? Install vue-router? Yes
      ? Use ESLint to lint your code? Yes
      ? Pick an ESLint preset Standard
      ? Set up unit tests No
      ? Setup e2e tests with Nightwatch? No
      ? Should we run `npm install` for you after the project has been created? (recommended) npm

       

  • Now we have to heavily modify the mess that just got thrown into the directory. 

    • Rename src to ClientApp

    • In webpack.base.config change src to ClientApp

  • Remove dev server
    • Remove the config in config/index.js under "//Various Dev Server settings"
    • In package.json remove the dev and start script and you can remove the webpack-dev-server package.

    • Remove the devServer section in build/webpack.dev.config.js

      • replace module.exports with 

        module.exports = devWebpackConfig;

         

      • remove new webpack.HotModuleReplacementPlugin(),

      • In config/index.js change all 'dist' to 'wwwroot'

        • under dev change assetsPublicPath to /wwwroot

  • At this point if you run npm run build it should emit the correct production files in the wwwroot folder. 
  • Add extra needed packages

    • npm install cross-env -D

       

    • npm install aspnet-webpack -D

       

    • npm install webpack-hot-middleware -D

       

  • Add script to package.json

    • "dev": "cross-env ASPNETCORE_ENVIRONMENT=Development NODE_ENV=development dotnet run",

       

That webpack sutff was a bit tedious to write so please just download the attached template and run it.  

Using Attached Template:

  • unzip the template somewhere
  • navigate to src/FSharpVue
  • npm install or yarn install
  • npm run dev

How to build/run:

  • DEVELOPMENT:
    • npm run dev or dotnet run
      • if you use dotnet run make sure your ASPNETCORE_ENVIROMENT is set to Development
  • Production
    • Build the wwwroot folder
      • npm run build
    • Run the aspnetcore project in production with dotnet run.

 

Finial Thoughts:

I have to be very clear with this. I would rather run backend api and frontend completely separate and not use kestrel to serve the ClientApp.  I would like to make a better examples that uses a giraffe handler for some sort of API, but I figured that just setting up a template is enough for now. It is quite easy to add the api routing vs setting up this project in general.

 

FSharpVue.zip

  • Like 2

Share this post


Link to post
Share on other sites

Huh. This is pretty awesome. I've never seen F# used before. How do you like it for web server programming?

Share this post


Link to post
Share on other sites

@Leo in terms of making handlers it is quite a nice feel. Giraffe really adds some nice features that make aspnetcore more functional. 

I could do something like this to handle route authentication assuming the middleware for jwt is there:

let authorize =
    requiresAuthentication (challenge JwtBearerDefaults.AuthenticationScheme)

let webApp = 
	choose [
		GET >=>
			choose [
				route "/" >=> text "Public"
				routef "/%s" >=> authoize >=> text 
			]
	]

 

this will allow you to goto the route / and it will return "Public" and if you goto /sdfsdf it will authorize you and then give you "sdfsdf". 

This the idea of chaining and function composition of handlers are quite nice. Handlers can also do alot more than just return some text. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using this site, you agree to our Terms of Use.