# <a href="https://travis-ci.org/purescript-contrib/pulp"><img alt="Travis CI status" align="right" src="https://travis-ci.org/purescript-contrib/pulp.svg?branch=master"></a> <a href="https://ci.appveyor.com/project/hdgarrood/pulp"><img alt="AppVeyor CI status" align="right" src="https://ci.appveyor.com/api/projects/status/c1naeh5i9991na5k?svg=true"></a> Pulp
[![Join the chat at https://gitter.im/bodil/pulp](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bodil/pulp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
A build tool for PureScript.
![Jarvis Cocker dancing](http://24.media.tumblr.com/77b76c557515a801a7e99ca5507b6548/tumblr_n5cx52oT831r4ba6to1_400.gif)
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Installation](#installation)
- [Getting Started with a Pulp Project](#getting-started-with-a-pulp-project)
- [What if I need something a bit more complicated?](#what-if-i-need-something-a-bit-more-complicated)
- [Pulp Commands](#pulp-commands)
- [Global, Command Specific and Pass-Through Options](#global-command-specific-and-pass-through-options)
- [Pass-Through Options](#pass-through-options)
- [Building Projects](#building-projects)
- [Making a JavaScript Bundle](#making-a-javascript-bundle)
- [Running Your PureScript Project](#running-your-purescript-project)
- [Running Test Suites](#running-test-suites)
- [Running Commands Before and After an Action](#running-commands-before-and-after-an-action)
- [CommonJS Aware Builds](#commonjs-aware-builds)
- [Optimising Code Size](#optimising-code-size)
- [Reimporting Browserified Bundles](#reimporting-browserified-bundles)
- [Building Documentation](#building-documentation)
- [Launching a REPL](#launching-a-repl)
- [Launching a Development Server](#launching-a-development-server)
- [A Quick Example](#a-quick-example)
- [I Need More](#i-need-more)
- [Dependency Management](#dependency-management)
- [Dependency Management Cheat Sheet](#dependency-management-cheat-sheet)
- [Installing Dependencies](#installing-dependencies)
- [Housekeeping](#housekeeping)
- [Releasing Packages](#releasing-packages)
- [Development](#development)
- [Licence](#licence)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Installation
Assuming you already have [Node](https://nodejs.org/en/download/) set
up (and we recommend you also set up NPM to
[keep your global packages in your home directory](https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md)),
all you need to do to get a working PureScript environment is:
```sh
$ npm install -g purescript pulp bower
```
This installs the PureScript compiler, the Pulp build tool, and the
[Bower](http://bower.io/) package manager.
*Aside: if you're familiar with the JavaScript ecosystem and you're wondering
why PureScript uses Bower and not npm, you might be interested to read [Why the
PureScript community uses Bower](http://harry.garrood.me/blog/purescript-why-bower/).
Otherwise, please ignore this and read on.*
## Getting Started with a Pulp Project
The short version:
```sh
$ mkdir purescript-hello
$ cd purescript-hello
$ pulp init
$ pulp run
```
The structure of your project folder, after running `pulp init`, will
look like this:
```
purescript-hello
- bower.json
- src/
- test/
```
`pulp` works by convention. It expects all projects to contain a manifest file
for package management (usually `bower.json`, since package management in
PureScript is usually handled by [Bower](http://bower.io/)).
Your project source files go in the `src` folder. Your test files go in the
`test` folder. Project dependencies will be installed under the Bower standard
`bower_components` folder, and are expected to have the same basic `src`/`test`
structure. That's all there is to a `pulp` project.
We employ the `purescript-` prefix as a convention to identify PureScript
projects when they're used as dependencies. You're welcome to call your project
anything you like, but without the `purescript-` prefix it won't be picked up
by `pulp` as a dependency.
### What if I need something a bit more complicated?
If you want to change any of these defaults, you can—`pulp` offers a
number of command line flags to alter its behaviour—but try to avoid using
them unless you have a good reason to.
If you get fed up with having to remember long `pulp` invocations, try
[using `npm` as your build tool](http://substack.net/task_automation_with_npm_run).
`pulp`'s numerous command line flags make it well suited for this.
If that's still not enough, you might try using a more generic build tool,
such as [webpack](https://webpack.github.io/) with
[purs-loader](https://github.com/ethul/purs-loader), or
[gulp](http://gulpjs.com) with
[gulp-purescript](https://github.com/purescript-contrib/gulp-purescript).
## Pulp Commands
To get a quick overview of the things `pulp` can do, you can ask it to
give you a list of its available commands:
```sh
$ pulp --help
```
This will print a list of `pulp`'s global command line options, and a
list of commands it will accept.
To see the available options for a specific command, you can invoke
the command with the `--help` flag, like this:
```sh
$ pulp build --help
```
This will give you an exhaustive list of ways you can modify the basic
behaviour of the command.
### Global, Command Specific and Pass-Through Options
Notice that there's a distinction between _global_ command line
options and command specific options. Global options must appear
_before_ the name of the command, and command specific options must
appear _after_ it.
Thus, if you want to run the `build` command in watch mode (where it
will run the command once, then wait and re-run the command whenever
you change a source file) you need to put the `--watch` flag _before_
the command itself, like so:
```sh
$ pulp --watch build
```
On the other hand, if you want to tell the build command to produce
optimised code (performing dead code elimination), using the command
specific option `--optimise`, the flag needs to come _after_ the
command name:
```sh
$ pulp build --optimise
```
#### Pass-Through Options
Finally, `pulp` commands sometimes allows you to pass flags through to
the `purs` compiler. Any options appearing after `--` will be passed through to
the compiler, or whichever process a `pulp` command spawns. For instance, if
you want to tell `purs` to skip applying tail call optimisations, you would
invoke `pulp build` like this:
```sh
$ pulp build -- --no-tco
```
## Building Projects
At heart, `pulp` is just a frontend for the PureScript compiler,
`purs`. Its basic function is to compile your project, which you can do
by running `pulp build`. This will simply run `purs compile` with all your
source files, leaving the compiled JavaScript files in the `output`
folder. These files will all be CommonJS modules, which you can
`require()` using anything which supports CommonJS, such as `node`.
However, you will usually want to do more with your project than just
compile your PureScript code into a jumble of CommonJS modules. `pulp`
provides a number of commands and options for the most common use
cases.
### Making a JavaScript Bundle
`pulp build` can also call `purs bundle` for you, which is a compiler
tool whose job it is to take the output from `purs compile`, remove the code
which isn't actually being used by your program, and bundle it all up
into a single compact JavaScript file.
There are two command line options you can give `pulp build` to
accomplish this, depending on where you want the resulting code. You
can use the `--optimise` flag (or its shorthand alias, `-O`), which
will send the bundled result to standard output, or you can use the
`--to` (or `-t`) option, passing it a file name, and `pulp` will store
the bundle in a file of t