parent
71dca24d9d
commit
93c34f2214
|
@ -1,8 +1,14 @@
|
||||||
/.*
|
.*
|
||||||
!/.gitignore
|
!.gitignore
|
||||||
!/.travis.yml
|
!.travis.yml
|
||||||
/bower_components/
|
!.purs-repl
|
||||||
/node_modules/
|
|
||||||
/output/
|
.spago
|
||||||
/dist/app.js
|
bower_components
|
||||||
|
node_modules
|
||||||
|
output
|
||||||
|
|
||||||
|
*.lock
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
||||||
|
dist/app.js
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
import Prelude
|
|
@ -3,8 +3,7 @@ dist: trusty
|
||||||
sudo: required
|
sudo: required
|
||||||
node_js: stable
|
node_js: stable
|
||||||
install:
|
install:
|
||||||
- npm install -g bower
|
|
||||||
- npm install
|
- npm install
|
||||||
- bower install
|
|
||||||
script:
|
script:
|
||||||
- npm run build
|
- npm run build
|
||||||
|
- npm run test
|
||||||
|
|
71
README.md
71
README.md
|
@ -1,72 +1,57 @@
|
||||||
# purescript-halogen-template
|
# Halogen Template
|
||||||
|
|
||||||
This is a template for starting a fresh project using the [purescript-halogen](https://github.com/slamdata/purescript-halogen) library for declarative user interfaces.
|
This is a template for starting a fresh project with the [Halogen](https://github.com/slamdata/purescript-halogen) library for writing declarative, type-safe user interfaces.
|
||||||
|
|
||||||
## Prerequisites
|
You can learn more about Halogen with these resources:
|
||||||
|
|
||||||
This guide assumes you already have Git and Node.js installed with `npm` somewhere on your path.
|
- The [Halogen documentation](https://github.com/purescript-halogen/purescript-halogen/tree/master/docs), which includes a quick start guide and a concepts reference.
|
||||||
|
- The [Learn Halogen](https://github.com/jordanmartinez/learn-halogen) learning repository.
|
||||||
|
- The [Real World Halogen](https://github.com/thomashoneyman/purescript-halogen-realworld) application and guide.
|
||||||
|
- The [API documentation](https://pursuit.purescript.org/packages/purescript-halogen) on Pursuit
|
||||||
|
|
||||||
In the PureScript ecosystem [Bower](http://bower.io/) is currently the most commonly used package manager and we'll be relying on it for this project, so if you don't already have it, you can install it like this:
|
You can chat with other Halogen users on the [PureScript Discourse](https://discourse.purescript.org), or join the [Functional Programming Slack](https://functionalprogramming.slack.com) ([invite link](https://fpchat-invite.herokuapp.com/)) in the `#purescript` and `#purescript-beginners` channels.
|
||||||
|
|
||||||
``` shell
|
|
||||||
npm install --global bower
|
|
||||||
```
|
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
First clone the repo and step into it:
|
**Prerequisites:** This template assumes you already have Git and Node.js installed with `npm` somewhere on your path.
|
||||||
|
|
||||||
``` shell
|
First, clone the repository and step into it:
|
||||||
git clone https://github.com/slamdata/purescript-halogen-template.git my-halogen-project
|
|
||||||
cd my-halogen-project
|
```sh
|
||||||
|
git clone https://github.com/purescript-halogen/purescript-halogen-template.git halogen-project
|
||||||
|
cd halogen-project
|
||||||
```
|
```
|
||||||
|
|
||||||
If you don't already have a global installation of the PureScript compiler and [Pulp](https://github.com/bodil/pulp) (or you want a local installation with the appropriate versions) you can run:
|
Then, install the PureScript compiler, the [Spago](https://github.com/purescript/spago) package manager and build tool, and [Webpack](https://github.com/webpack/webpack) bundler locally:
|
||||||
|
|
||||||
``` shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
Finally you'll need to install the PureScript library dependencies for this project with Bower:
|
This will automatically trigger Spago to install the PureScript library dependencies for this project.
|
||||||
|
|
||||||
``` shell
|
|
||||||
bower install
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
The project can now be built with:
|
You can now build the PureScript source code with:
|
||||||
|
|
||||||
``` shell
|
```sh
|
||||||
|
# An alias for `spago build`
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
This will build the PureScript source code and produce a bundled JS file as `dist/app.js`.
|
You can produce a bundled JS file you can run in the browser with:
|
||||||
|
|
||||||
This is an alias for the Pulp command:
|
```sh
|
||||||
|
# An alias for `spago bundle-app --to dist/app.js`
|
||||||
``` shell
|
npm run bundle
|
||||||
pulp build --to dist/app.js
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If you open `dist/index.html` you should now have a basic working Halogen app.
|
This deposits a bundled JS file named `app.js` in the `dist` directory. You can view your running Halogen app by opening the `dist/index.html` file.
|
||||||
|
|
||||||
You can also use the command:
|
Alternatively, if you use an editor that supports `purs ide` or if you are running [`pscid`](https://github.com/kRITZCREEK/pscid), then you can get near-instant builds of the app while you work:
|
||||||
|
|
||||||
``` shell
|
```sh
|
||||||
npm run watch
|
npm run bundle:watch
|
||||||
```
|
```
|
||||||
|
|
||||||
To start a process that will watch the source files and trigger a reload whenever they are modified. Alternatively...
|
|
||||||
|
|
||||||
## Fast watching with `purs ide`
|
|
||||||
|
|
||||||
If you're using an editor that supports `purs ide` or running [`pscid`](https://github.com/kRITZCREEK/pscid) there's an option for getting near-instant builds of the app while you work on it:
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
npm run watch-fast
|
|
||||||
```
|
|
||||||
|
|
||||||
This will start a watch process that uses [Webpack](https://github.com/webpack/webpack) to rebundle the app whenever the _output_ files are changed. Since `purs ide` rebuilds modules on save, this means you can use this much faster bundle-only rebuild script.
|
|
||||||
|
|
||||||
:warning: `purs ide` only rebuilds one module at a time, so sometimes the bundle will end up in an inconsistent state, resulting in runtime errors. This occurs when a change is made in one module that breaks other modules that depend on it. The solution is to run a full build when a change like this is made, as the compiler will force you to resolve those errors.
|
:warning: `purs ide` only rebuilds one module at a time, so sometimes the bundle will end up in an inconsistent state, resulting in runtime errors. This occurs when a change is made in one module that breaks other modules that depend on it. The solution is to run a full build when a change like this is made, as the compiler will force you to resolve those errors.
|
||||||
|
|
17
bower.json
17
bower.json
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"private": true,
|
|
||||||
"name": "purescript-halogen-template",
|
|
||||||
"ignore": [
|
|
||||||
"**/.*",
|
|
||||||
"node_modules",
|
|
||||||
"bower_components",
|
|
||||||
"output",
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"purescript-halogen": "^4.0.0",
|
|
||||||
"purescript-prelude": "^4.1.0",
|
|
||||||
"purescript-console": "^4.1.0",
|
|
||||||
"purescript-effect": "^2.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +1,8 @@
|
||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8" />
|
||||||
<title>My Halogen App</title>
|
<title>My Halogen App</title>
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: sans-serif;
|
|
||||||
max-width: 800px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="app.js"></script>
|
<script src="app.js"></script>
|
||||||
|
|
17
package.json
17
package.json
|
@ -1,15 +1,16 @@
|
||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "pulp build --to dist/app.js",
|
"test": "spago test",
|
||||||
"watch": "pulp -w build --to dist/app.js",
|
"build": "spago build",
|
||||||
"watch-fast": "webpack --mode=development --entry ./entry.js --output-path ./dist --output-filename app.js --progress --watch"
|
"bundle": "spago bundle-app --to dist/app.js",
|
||||||
|
"bundle:watch": "webpack --mode=development --entry ./entry.js --output-path ./dist --output-filename app.js --progress --watch"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"pulp": "^12.3.0",
|
"purescript": "^0.13.6",
|
||||||
"purescript": "^0.12.0",
|
"purescript-psa": "^0.7.3",
|
||||||
"purescript-psa": "^0.7.2",
|
"spago": "^0.15.2",
|
||||||
"webpack": "^4.16.2",
|
"webpack": "^4.43.0",
|
||||||
"webpack-cli": "^3.1.0"
|
"webpack-cli": "^3.3.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
{-
|
||||||
|
Welcome to your new Dhall package-set!
|
||||||
|
|
||||||
|
Below are instructions for how to edit this file for most use
|
||||||
|
cases, so that you don't need to know Dhall to use it.
|
||||||
|
|
||||||
|
## Warning: Don't Move This Top-Level Comment!
|
||||||
|
|
||||||
|
Due to how `dhall format` currently works, this comment's
|
||||||
|
instructions cannot appear near corresponding sections below
|
||||||
|
because `dhall format` will delete the comment. However,
|
||||||
|
it will not delete a top-level comment like this one.
|
||||||
|
|
||||||
|
## Use Cases
|
||||||
|
|
||||||
|
Most will want to do one or both of these options:
|
||||||
|
1. Override/Patch a package's dependency
|
||||||
|
2. Add a package not already in the default package set
|
||||||
|
|
||||||
|
This file will continue to work whether you use one or both options.
|
||||||
|
Instructions for each option are explained below.
|
||||||
|
|
||||||
|
### Overriding/Patching a package
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
- Change a package's dependency to a newer/older release than the
|
||||||
|
default package set's release
|
||||||
|
- Use your own modified version of some dependency that may
|
||||||
|
include new API, changed API, removed API by
|
||||||
|
using your custom git repo of the library rather than
|
||||||
|
the package set's repo
|
||||||
|
|
||||||
|
Syntax:
|
||||||
|
Replace the overrides' "{=}" (an empty record) with the following idea
|
||||||
|
The "//" or "⫽" means "merge these two records and
|
||||||
|
when they have the same value, use the one on the right:"
|
||||||
|
-------------------------------
|
||||||
|
let overrides =
|
||||||
|
{ packageName =
|
||||||
|
upstream.packageName // { updateEntity1 = "new value", updateEntity2 = "new value" }
|
||||||
|
, packageName =
|
||||||
|
upstream.packageName // { version = "v4.0.0" }
|
||||||
|
, packageName =
|
||||||
|
upstream.packageName // { repo = "https://www.example.com/path/to/new/repo.git" }
|
||||||
|
}
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Example:
|
||||||
|
-------------------------------
|
||||||
|
let overrides =
|
||||||
|
{ halogen =
|
||||||
|
upstream.halogen // { version = "master" }
|
||||||
|
, halogen-vdom =
|
||||||
|
upstream.halogen-vdom // { version = "v4.0.0" }
|
||||||
|
}
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
### Additions
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
- Add packages that aren't already included in the default package set
|
||||||
|
|
||||||
|
Syntax:
|
||||||
|
Replace the additions' "{=}" (an empty record) with the following idea:
|
||||||
|
-------------------------------
|
||||||
|
let additions =
|
||||||
|
{ package-name =
|
||||||
|
{ dependencies =
|
||||||
|
[ "dependency1"
|
||||||
|
, "dependency2"
|
||||||
|
]
|
||||||
|
, repo =
|
||||||
|
"https://example.com/path/to/git/repo.git"
|
||||||
|
, version =
|
||||||
|
"tag ('v4.0.0') or branch ('master')"
|
||||||
|
}
|
||||||
|
, package-name =
|
||||||
|
{ dependencies =
|
||||||
|
[ "dependency1"
|
||||||
|
, "dependency2"
|
||||||
|
]
|
||||||
|
, repo =
|
||||||
|
"https://example.com/path/to/git/repo.git"
|
||||||
|
, version =
|
||||||
|
"tag ('v4.0.0') or branch ('master')"
|
||||||
|
}
|
||||||
|
, etc.
|
||||||
|
}
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Example:
|
||||||
|
-------------------------------
|
||||||
|
let additions =
|
||||||
|
{ benchotron =
|
||||||
|
{ dependencies =
|
||||||
|
[ "arrays"
|
||||||
|
, "exists"
|
||||||
|
, "profunctor"
|
||||||
|
, "strings"
|
||||||
|
, "quickcheck"
|
||||||
|
, "lcg"
|
||||||
|
, "transformers"
|
||||||
|
, "foldable-traversable"
|
||||||
|
, "exceptions"
|
||||||
|
, "node-fs"
|
||||||
|
, "node-buffer"
|
||||||
|
, "node-readline"
|
||||||
|
, "datetime"
|
||||||
|
, "now"
|
||||||
|
]
|
||||||
|
, repo =
|
||||||
|
"https://github.com/hdgarrood/purescript-benchotron.git"
|
||||||
|
, version =
|
||||||
|
"v7.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-------------------------------
|
||||||
|
-}
|
||||||
|
|
||||||
|
let upstream =
|
||||||
|
https://github.com/purescript/package-sets/releases/download/psc-0.13.6-20200507/packages.dhall sha256:9c1e8951e721b79de1de551f31ecb5a339e82bbd43300eb5ccfb1bf8cf7bbd62
|
||||||
|
|
||||||
|
let overrides = {=}
|
||||||
|
|
||||||
|
let additions = {=}
|
||||||
|
|
||||||
|
in upstream // overrides // additions
|
|
@ -0,0 +1,5 @@
|
||||||
|
{ name = "halogen-project"
|
||||||
|
, dependencies = [ "halogen", "psci-support" ]
|
||||||
|
, packages = ./packages.dhall
|
||||||
|
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
module App.Button where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Data.Maybe (Maybe(..))
|
||||||
|
import Halogen as H
|
||||||
|
import Halogen.HTML as HH
|
||||||
|
import Halogen.HTML.Events as HE
|
||||||
|
|
||||||
|
type State = { count :: Int }
|
||||||
|
|
||||||
|
data Action = Increment
|
||||||
|
|
||||||
|
component :: forall q i o m. H.Component HH.HTML q i o m
|
||||||
|
component =
|
||||||
|
H.mkComponent
|
||||||
|
{ initialState: \_ -> { count: 0 }
|
||||||
|
, render
|
||||||
|
, eval: H.mkEval $ H.defaultEval { handleAction = handleAction }
|
||||||
|
}
|
||||||
|
|
||||||
|
render :: forall cs m. State -> H.ComponentHTML Action cs m
|
||||||
|
render state =
|
||||||
|
HH.div_
|
||||||
|
[ HH.p_
|
||||||
|
[ HH.text $ "You clicked " <> show state.count <> " times" ]
|
||||||
|
, HH.button
|
||||||
|
[ HE.onClick \_ -> Just Increment ]
|
||||||
|
[ HH.text "Click me" ]
|
||||||
|
]
|
||||||
|
|
||||||
|
handleAction :: forall cs o m. Action → H.HalogenM State Action cs o m Unit
|
||||||
|
handleAction = case _ of
|
||||||
|
Increment ->
|
||||||
|
H.modify_ \st -> st { count = st.count + 1 }
|
|
@ -1,48 +0,0 @@
|
||||||
module Component where
|
|
||||||
|
|
||||||
import Prelude
|
|
||||||
|
|
||||||
import Data.Maybe (Maybe(..))
|
|
||||||
|
|
||||||
import Halogen as H
|
|
||||||
import Halogen.HTML as HH
|
|
||||||
import Halogen.HTML.Events as HE
|
|
||||||
|
|
||||||
data Query a = ToggleState a
|
|
||||||
|
|
||||||
type State = { on :: Boolean }
|
|
||||||
|
|
||||||
component :: forall m. H.Component HH.HTML Query Unit Void m
|
|
||||||
component =
|
|
||||||
H.component
|
|
||||||
{ initialState: const initialState
|
|
||||||
, render
|
|
||||||
, eval
|
|
||||||
, receiver: const Nothing
|
|
||||||
}
|
|
||||||
where
|
|
||||||
|
|
||||||
initialState :: State
|
|
||||||
initialState = { on: false }
|
|
||||||
|
|
||||||
render :: State -> H.ComponentHTML Query
|
|
||||||
render state =
|
|
||||||
HH.div_
|
|
||||||
[ HH.h1_
|
|
||||||
[ HH.text "Hello world!" ]
|
|
||||||
, HH.p_
|
|
||||||
[ HH.text "Why not toggle this button:" ]
|
|
||||||
, HH.button
|
|
||||||
[ HE.onClick (HE.input_ ToggleState) ]
|
|
||||||
[ HH.text
|
|
||||||
if not state.on
|
|
||||||
then "Don't push me"
|
|
||||||
else "I said don't push me!"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
eval :: Query ~> H.ComponentDSL State Query Void m
|
|
||||||
eval = case _ of
|
|
||||||
ToggleState next -> do
|
|
||||||
_ <- H.modify (\state -> { on: not state.on })
|
|
||||||
pure next
|
|
|
@ -1,13 +1,13 @@
|
||||||
module Main where
|
module Main where
|
||||||
|
|
||||||
import Prelude
|
import Prelude
|
||||||
|
|
||||||
|
import App.Button as Button
|
||||||
import Effect (Effect)
|
import Effect (Effect)
|
||||||
import Halogen.Aff as HA
|
import Halogen.Aff as HA
|
||||||
import Halogen.VDom.Driver (runUI)
|
import Halogen.VDom.Driver (runUI)
|
||||||
|
|
||||||
import Component (component)
|
|
||||||
|
|
||||||
main :: Effect Unit
|
main :: Effect Unit
|
||||||
main = HA.runHalogenAff do
|
main = HA.runHalogenAff do
|
||||||
body <- HA.awaitBody
|
body <- HA.awaitBody
|
||||||
runUI component unit body
|
runUI Button.component unit body
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
module Test.Main where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Effect (Effect)
|
||||||
|
import Effect.Class.Console (log)
|
||||||
|
|
||||||
|
main :: Effect Unit
|
||||||
|
main = do
|
||||||
|
log "You should add some tests."
|
Loading…
Reference in New Issue