parent
71dca24d9d
commit
93c34f2214
|
@ -1,8 +1,14 @@
|
|||
/.*
|
||||
!/.gitignore
|
||||
!/.travis.yml
|
||||
/bower_components/
|
||||
/node_modules/
|
||||
/output/
|
||||
/dist/app.js
|
||||
.*
|
||||
!.gitignore
|
||||
!.travis.yml
|
||||
!.purs-repl
|
||||
|
||||
.spago
|
||||
bower_components
|
||||
node_modules
|
||||
output
|
||||
|
||||
*.lock
|
||||
package-lock.json
|
||||
|
||||
dist/app.js
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
import Prelude
|
|
@ -3,8 +3,7 @@ dist: trusty
|
|||
sudo: required
|
||||
node_js: stable
|
||||
install:
|
||||
- npm install -g bower
|
||||
- npm install
|
||||
- bower install
|
||||
script:
|
||||
- npm run build
|
||||
- npm run test
|
||||
|
|
69
README.md
69
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:
|
||||
|
||||
``` shell
|
||||
npm install --global bower
|
||||
```
|
||||
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.
|
||||
|
||||
## 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
|
||||
git clone https://github.com/slamdata/purescript-halogen-template.git my-halogen-project
|
||||
cd my-halogen-project
|
||||
First, clone the repository and step into it:
|
||||
|
||||
```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
|
||||
npm install
|
||||
```
|
||||
|
||||
Finally you'll need to install the PureScript library dependencies for this project with Bower:
|
||||
|
||||
``` shell
|
||||
bower install
|
||||
```
|
||||
This will automatically trigger Spago to install the PureScript library dependencies for this project.
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
``` shell
|
||||
pulp build --to dist/app.js
|
||||
```sh
|
||||
# An alias for `spago bundle-app --to dist/app.js`
|
||||
npm run bundle
|
||||
```
|
||||
|
||||
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
|
||||
npm run watch
|
||||
```sh
|
||||
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.
|
||||
|
|
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">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>My Halogen App</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="app.js"></script>
|
||||
|
|
17
package.json
17
package.json
|
@ -1,15 +1,16 @@
|
|||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "pulp build --to dist/app.js",
|
||||
"watch": "pulp -w build --to dist/app.js",
|
||||
"watch-fast": "webpack --mode=development --entry ./entry.js --output-path ./dist --output-filename app.js --progress --watch"
|
||||
"test": "spago test",
|
||||
"build": "spago build",
|
||||
"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": {
|
||||
"pulp": "^12.3.0",
|
||||
"purescript": "^0.12.0",
|
||||
"purescript-psa": "^0.7.2",
|
||||
"webpack": "^4.16.2",
|
||||
"webpack-cli": "^3.1.0"
|
||||
"purescript": "^0.13.6",
|
||||
"purescript-psa": "^0.7.3",
|
||||
"spago": "^0.15.2",
|
||||
"webpack": "^4.43.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
|
||||
|
||||
import Prelude
|
||||
|
||||
import App.Button as Button
|
||||
import Effect (Effect)
|
||||
import Halogen.Aff as HA
|
||||
import Halogen.VDom.Driver (runUI)
|
||||
|
||||
import Component (component)
|
||||
|
||||
main :: Effect Unit
|
||||
main = HA.runHalogenAff do
|
||||
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