Purescript with Vue.js - Adding Purescript

Posted on by Mandla Mbuli

I wanted to learn Purescript and the little experience I have had with vue was pleasant enough to make me want to use it with Purescript. This showed me it was possible. I didn’t want to use Spago though. Not yet anyway. So I started from scratch and here we are. I know Bower has been deprecated for a while now so I will probably switch to Spago if I stay with purescript but for now. This is how I got purescript with vue to show HelloWorld.

Getting purescript

I followed the old instructions for getting started. The latest I from the purescript website use spago and are here. I am using bower for now, I will see if I switch and what is involved and if it works with nix.

I have an existing project so I use a tmp directory to get the bowercomponents and bower.json files out and then copy them into the project. The commands were:

yarn add pulp bower
PATH=$PATH:$(yarn bin)
mkdir tmp
cd tmp 
pulp init
mv bower_components bower.json ../  
cd ..
rm tmp

I am plugging into vue which I guess uses webpack and thus I need the purs-loader:

yarn add --dev purs-loader

I then need to configure vue (got this from here):

// vue.config.js
const path = require('path');

module.exports = {
 chainWebpack: config => {
   config.module
     .rule('purescript')
     .test(/\.purs$/)
     .use('purs-loader')
     .loader('purs-loader')
     .tap(options => ({
       src: [
         path.join('src', '**', '*.purs'),
         path.join('bower_components', '**', 'src', '**', '*.purs'),
       ]
     }))
 }
}

I then create a HelloWorld.purs file next to the HelloWorld.vue file containing:

module HelloWorld where

import Prelude
import Effect (Effect)
import Effect.Console (log)

greet :: String -> String
greet name = "Hello, " <> name <> "!"

main :: Effect Unit
main = log (greet "World")

Finally I modify the HelloWorld.vue file to be:

<template>
 <div class="hello">
   <h1>{{ msg }}</h1>
 </div>
</template>

<script>
import { main, greet } from './HelloWorld.purs'
// Trying out purescript

main()
console.log(greet("Figgus"));

export default {
 name: 'HelloWorld',
 props: {
   msg: String
 }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
 margin: 40px 0 0;
}
ul {
 list-style-type: none;
 padding: 0;
}
li {
 display: inline-block;
 margin: 0 10px;
}
a {
 color: purple;
}
</style>

Run the project:

yarn serve

Then look at the console. It should have “Hello World!” and “Hello Figgus!”