Skip to content

Commit

Permalink
Add a 'Getting Started With Parcel' to docs (#461)
Browse files Browse the repository at this point in the history
* filter out files in .spago folder from watch list

* add #430 to changelog

* Update src/Spago/Build.hs

Co-Authored-By: Jan Hrcek <honza.hrk@gmail.com>

* fix build by importing split directories

* added step-by-step guide to setting up a spago + parcel project to documentation

* cleanup

* changelog
  • Loading branch information
Benjmhart authored and mergify[bot] committed Oct 26, 2019
1 parent 377473a commit 8429904
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ New features:
- `spago build` now uses shared output folder to reduce build duplication. Pass `--no-share-output` flag to disable this behavior (#377)
- `spago install purescript-XYZ` will now strip `purescript-` prefix and install XYZ (if it exists in package set) instead of just failing with a warning (#367)
- `spago run` now recognizes backend specified in the configuration file and calls the backend with `--run` argument.
- documentation now includes a step-by-step guide on setting up a Spago/Parcel project (#456)

Bugfixes:
- Warn (but don't error) when trying to watch missing directories (#406)
Expand Down
106 changes: 82 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -698,31 +698,89 @@ To skip this build you can add the `--no-build` flag.

### Make a project with PureScript + JavaScript

Take a look at [TodoMVC with react-basic + spago + parcel][todomvc] to have a starting point.

This generally consists of two separate build steps:

1. Build the project with `spago`:
- this will compile your project to JS
- you can use either `spago build` - which will create many files that you can require in your JS -
or `spago bundle-module`, which will create only one Dead-Code-Eliminated file that you can require.
- the tradeoff between the two is compile times vs bundle size: `bundle-module` will be more expensive
to build, but will generally be smaller, while just requiring the artifacts from `build` is very fast
to compile but might lead to a bigger bundle (you should benchmark this though)
2. Bundle the project with a JS bundler:
- this will usually bundle everything in a single JS file, after resolving all the `require`s
and including the JS dependencies
- you'll usually have a `index.js` file in your project, that will include something like:
```js
..
// So you require the PureScript file from js
var PureScriptMain = require('./output/Main');
..
// Then you can just call its functions from js
PureScriptMain.somemethod();
```
- the above example project uses `parcel`, but you can use `webpack`, `browserify`, etc.
Take a look at [TodoMVC with react-basic + spago + parcel][todomvc] for a working example.

#### Getting Started from Scratch

To start a project using Spago and Parcel together, here's the cammands and file setup you'll need:

0. install Node Package Manager(NPM): `curl https://www.npmjs.org/install.sh | sh`
1. Install Spago and PureScript: `npm i -g spago purescript`
2. Create a folder for your project: `mkdir <project folder name>`
3. Move to the project folder: `cd <project folder name>`
4. Create your PureScript project with Spago: `spago init`, This also produces a `./src/Main.purs` file which contains some starter code.
5. Initialize the JavaScript/NPM project `npm init`
6. Install Parcel as a dependency `npm i parcel`
7. Add a JavaScript file which imports and calls the `main` function from the output of `./src/Main.purs`. This can be placed in the root directory for your project. Traditionally this file is named `index.js`. The `main` function from `Main.purs` can accept arguments, this is useful since parcel will replace environment variables inside of JavaScript. It is recommended to read any environment variables in the JavaScript file and pass them as arguments to `main`. Here is an example JavaScript file:

``` JavaScript
var Main = require('./output/Main');

function main () {
/*
Here we could add variables such as
var baseUrl = process.env.BASE_URL;
Parcel will replace `process.env.BASE_URL`
with the string contents of the BASE_URL environment
variable at bundle/build time.
A .env file can also be used to override shell variables
for more information, see https://en.parceljs.org/env.html
These variables can be supplied to the Main.main function,
however, you will need to change the type to accept variables, by default it is an Effect.
You will probably want to make it a function from String -> Effect ()
*/

Main.main();
}

// HMR stuff
// For more info see: https://parceljs.org/hmr.html
if (module.hot) {
module.hot.accept(function () {
console.log('Reloaded, running main again');
main();
});
}

console.log('Starting app');

main();
```

8. Add an HTML file which sources your JavaScript file. This can be named `index.html` and placed in the root directory of your project. Here is an example HTML file:

``` HTML
<!doctype html>
<html lang="en" data-framework="purescript">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

<body>
<div id="app"></div>
<script src="./index.js"></script>
</body>
</html>
```

9. Add a development script to `package.json` which will hot-bundle the PureScript code with Spago, and then hot-reload the resulting JavaScript code using Parcel. Here, we'll call this script `dev`.

```
...
"scripts": {
"dev": "spago build --watch & parcel index.html",
},
...
```

This script will simultanously run spago and parcel. When you run it with `npm run dev`, Parcel will tell you which port your application is being served on, by default this will be `localhost:1234`. If you've followed this guide you can navigate there in a browser and open the javascript console. you will see the output of both `index.js` and the compiled `Main.purs` file. When you modify any purescript file in `./src`, you should see Spago and Parcel rebuild your application, and the browser should execute the new code. For some applications you may adjust the JavaScript function that handles hot modules to fully reload the page with `window.location.reload();`.

10. when you are ready to build and deploy your application as static html/js/css, you may add a `build` script to package.json in order to produce a final bundle, this script is usually something like `spago build && parcel build index.html`.

Other build options are available, using webpack (and purs-loader), or browserify. Parcel is used here for it's low-configuration overhead.

### Generate documentation for my project

Expand Down

0 comments on commit 8429904

Please sign in to comment.