Skip to content

Commit 4904b69

Browse files
committed
Add getting-started doc, more soon
1 parent f4ddd27 commit 4904b69

File tree

3 files changed

+283
-0
lines changed

3 files changed

+283
-0
lines changed

Diff for: docs/advanced.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Advanced Topics
2+
3+
Coming soon!

Diff for: docs/beginner.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Beginner Topics
2+
3+
Coming soon!

Diff for: docs/getting-started.md

+277
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
# Getting Started
2+
3+
I assume you're here because you want to write a React app using PureScript! Good, good, because that's what this guide is all about.
4+
5+
Before we begin you'll need to install [Node.js](https://nodejs.org/). If you aren't sure what editor to use, try [VSCode](https://code.visualstudio.com/). It's got great PureScript language support via the [PureScript IDE](https://marketplace.visualstudio.com/items?itemName=nwolverson.ide-purescript) extension.
6+
7+
Done? Ok, we're going to set up this project from scratch so you have a basic idea of how all the parts work together. Don't worry, it won't take long!
8+
9+
## Creating a PureScript web project
10+
11+
Let's create a directory for the project.
12+
13+
```sh
14+
mkdir purs-react-app && cd purs-react-app
15+
```
16+
17+
Initialize `npm` (comes with Node.js). The command below creates a `package.json` file (and a `package-lock.json` file, but that's for `npm` to manage) to track our JavaScript dependencies (i.e. React) and dev tooling (PureScript, etc). We'll also put some useful scripts in here later.
18+
19+
```sh
20+
npm init -y
21+
```
22+
23+
Install PureScript and Spago (project management tool for PureScript).
24+
25+
```sh
26+
npm i -D purescript spago
27+
```
28+
29+
Next, use Spago to set up the PureScript files we need to get started. Spago is installed locally via `npm`, so we need to prefix this command with `npx` to run it.
30+
31+
```sh
32+
npx spago init
33+
```
34+
35+
You should now have a few new directories and files. `packages.dhall` defines the PureScript package source the project will use. The default will be fine. `spago.dhall` is where our PureScript dependencies are defined. Let's add `react-basic-hooks` to that list using Spago. We'll grab `react-basic-dom` too, since we'll need it soon.
36+
37+
```sh
38+
npx spago install react-basic-hooks react-basic-dom
39+
```
40+
41+
We also need to install React and ReactDOM, since `react-basic-hooks` and `react-basic-dom` rely on them, respectively.
42+
43+
```sh
44+
npm i -S react react-dom
45+
```
46+
47+
Ok, we're almost done.. We're now able to write React code using PureScript, but the only thing we can do with it is compile it to JavaScript and stare at it! Which is actually a good time and you'll learn a lot about PureScript in doing so, but let's save that for a future guide.
48+
49+
What we really want next is to start a server with a basic HTML skeleton so we can actually run our React app!
50+
51+
We can set this up pretty quick with existing bundlers like Parcel. Let's install it.
52+
53+
```sh
54+
npm i -D parcel
55+
```
56+
57+
Parcel's a bit picky about project setup. We're building an app, not a JavaScript library. Remove the following line from the `package.json` file to appease it.. :pray:
58+
59+
```json
60+
"main": "index.js",
61+
```
62+
63+
Now we need an entry-point HTML file to point Parcel at. Create the file `src/index.html` with the following content.
64+
65+
```html
66+
<!DOCTYPE html>
67+
<html lang="en">
68+
<head>
69+
<meta charset="UTF-8">
70+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
71+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
72+
<title>PureScript React App</title>
73+
<script async type="module" src="index.js"></script>
74+
</head>
75+
<body>
76+
<div id="root"></div>
77+
</body>
78+
</html>
79+
```
80+
81+
Now that HTML file is pointing to a mysterious `index.js` file! Create `src/index.js` with this content.
82+
83+
```js
84+
import { main } from "../output/Main";
85+
86+
main();
87+
```
88+
89+
More mysteries! What's this "Main" file with a "main" function inside!?
90+
91+
It's our PureScript! Let's take a look at the `src/Main.purs` file Spago created for us earlier. It probably looks like this.
92+
93+
```purs
94+
module Main where
95+
96+
import Prelude
97+
98+
import Effect (Effect)
99+
import Effect.Console (log)
100+
101+
main :: Effect Unit
102+
main = do
103+
log "🍝"
104+
```
105+
106+
Let's change that `log` call at the bottom so it logs something with deep, personal significance. We'll be that much more proud of our work once we see it in action.
107+
108+
```purs
109+
main :: Effect Unit
110+
main = do
111+
log "guuu"
112+
```
113+
114+
## Building and running the app
115+
116+
Building is a two-step process. The PureScript compiler (via Spago) handles the PureScript, emitting it as JavaScript in the `output/` folder. Parcel handles everything from that point on, serving (in dev mode), bundling, and minifying the JavaScript side.
117+
118+
The first thing you should always do is build your PureScript once, like so.
119+
120+
```sh
121+
npx spago build
122+
```
123+
124+
Then you can run Percel in "serve" mode to see it all running in your browser (`ctrl + c` to quit).
125+
126+
```sh
127+
npx parcel serve src/index.html
128+
```
129+
130+
Parcel will give you a URL for your dev server. Open it and take a look at the console. If everything went as planned, you should feel an inspiring sense of accomplishment! Good job! What? You wanted more than an empty white web page? We're getting there, soon, soon!
131+
132+
If you change your HTML or JavaScript files (including by rebuilding the PureScript code), you'll see those changes live-reload in your browser. Nice.
133+
134+
Let's create a production build.
135+
136+
```sh
137+
npx parcel build --dist-dir dist src/index.html
138+
```
139+
140+
This command directs the bundled output to the `dist/` folder. Add this folder to the `.gitignore` Spago made for us earlier!
141+
142+
```sh
143+
echo "dist/" >> .gitignore
144+
```
145+
146+
Ignore Parcel's cache dir as well.
147+
148+
```sh
149+
echo ".parcel-cache/" >> .gitignore
150+
```
151+
152+
You can deploy that `dist/` directory to a server, or upload it to S3 or GitHub Pages. The possibilities are endless!
153+
154+
For example, you can use `npx` to install and run the `serve` tool, a quick and easy way to spin up a server in a given directory (`ctrl + c` to quit).
155+
156+
```sh
157+
npx serve dist
158+
```
159+
160+
Parcel can do quite a bit for you. I recommend [learning more about it](https://parceljs.org/docs/) (or whatever bundler or dev server you choose) when you have a chance.
161+
162+
## Making "future you's" life easier
163+
164+
Remembering all these commands is a pain. Let's make some shortcuts.
165+
166+
You can add scripts to your `package.json` and invoke them with `npm`. These scripts don't need the `npx` prefix.
167+
168+
```json
169+
{
170+
"name": "purs-react-app",
171+
"version": "1.0.0",
172+
"description": "",
173+
"scripts": {
174+
"test": "spago test",
175+
"start": "spago build && parcel serve src/index.html",
176+
"build": "spago build && parcel build --dist-dir dist src/index.html"
177+
},
178+
"keywords": [],
179+
"author": "",
180+
"license": "ISC",
181+
"devDependencies": {
182+
"parcel": "^2.0.1",
183+
"purescript": "^0.14.5",
184+
"spago": "^0.20.3"
185+
},
186+
"dependencies": {
187+
"react": "^17.0.2",
188+
"react-dom": "^17.0.2"
189+
}
190+
}
191+
```
192+
193+
The `start` and `test` scripts are special, you can run them like this: `npm start` or `npm test`
194+
195+
Any other commands you add need the "run" prefix: `npm run build`
196+
197+
We haven't talked about `spago test` yet. You can learn more about general PureScript testing elsewhere. Testing PureScript React components will be a separate guide at some point.
198+
199+
## Rendering your first component
200+
201+
Since this is your first component, I'll write it for you. Don't worry, there's an entire guide on how to write your own components. I'll send you there next!
202+
203+
Copy this content into `src/App/Pages/Home.purs`. You can read it if you like, but don't sweat the details.
204+
205+
```purs
206+
module App.Pages.Home where
207+
208+
import Prelude
209+
210+
import React.Basic.DOM as DOM
211+
import React.Basic.DOM.Events (capture_)
212+
import React.Basic.Hooks (Component, component, useState, (/\))
213+
import React.Basic.Hooks as React
214+
215+
type HomeProps = Unit
216+
217+
mkHome :: Component HomeProps
218+
mkHome = do
219+
component "Home" \_props -> React.do
220+
221+
counter /\ setCounter <- useState 0
222+
223+
pure $ DOM.div
224+
{ children:
225+
[ DOM.h1_ [ DOM.text "Home" ]
226+
, DOM.p_ [ DOM.text "Try clicking the button!" ]
227+
, DOM.button
228+
{ onClick: capture_ do
229+
setCounter (_ + 1)
230+
, children:
231+
[ DOM.text "Clicks: "
232+
, DOM.text (show counter)
233+
]
234+
}
235+
]
236+
}
237+
```
238+
239+
If you're already familiar with writing React components in JavaScript and you squint this will probably look familiar!
240+
241+
Now we need to replace the content of `src/Main.purs` so it renders our new component.
242+
243+
```purs
244+
module Main where
245+
246+
import Prelude
247+
248+
import App.Pages.Home (mkHome)
249+
import Data.Maybe (Maybe(..))
250+
import Effect (Effect)
251+
import Effect.Exception (throw)
252+
import React.Basic.DOM (render)
253+
import Web.DOM.NonElementParentNode (getElementById)
254+
import Web.HTML (window)
255+
import Web.HTML.HTMLDocument (toNonElementParentNode)
256+
import Web.HTML.Window (document)
257+
258+
main :: Effect Unit
259+
main = do
260+
root <- getElementById "root" =<< (map toNonElementParentNode $ document =<< window)
261+
case root of
262+
Nothing ->
263+
throw "Root element not found."
264+
Just r -> do
265+
home <- mkHome
266+
render (home unit) r
267+
```
268+
269+
Once you're done, run `npm start`. Spago's going to complain that we're now using additional modules we didn't explicitly depend on. Go ahead and run the command it suggests. It should look like this (don't forget to prefix with `npx`).
270+
271+
```sh
272+
npx spago install exceptions maybe web-dom web-html
273+
```
274+
275+
Now run `npm start` again and open the link.
276+
277+
If you see the click counting button you've succeeded! You're ready to head to the [beginner guide](beginner.md) to learn how to build your own components! Good luck!

0 commit comments

Comments
 (0)