#3 Configuring a Spago Build

Saravanan M
5 min readMar 8, 2024

--

Spago is a build tool that helps us seamlessly manage our dependencies, build our project, and handle tasks like bundling and testing with ease. In this article, we’re going to explore how to tweak the build options in your spago.yaml. This post is part of a series on the Spago tool, so if you're new here or not familiar with Spago, I suggest reading the previous articles or just skimming through the official Spago documentation to get a quick start.

Configuring the Build Options

In the context of spago, building is the process of compiling your purescript source code, converting them to js(or your chosen backend) and putting them inside the build folder, which defaults to output

Let’s see how we can configure things related to compiling such as linting rules, output folder, the choice of backend etc.

Photo by Tory Bishop on Unsplash

1. Configuring Linting rules:

Linting helps enforce code quality rules and sometimes even help catching potential bugs(like shadowed variables) which the compiler gracefully ignores.

  • Turning warning into an error

It used to be that converting warnings into errors required purescript-psa, but now you can simply set the strict flag to true under the package > build section.

packages:
build:
strict: true
  • Censoring warnings

There may be times when not all warnings are useful. Spago makes it easy to censor warnings, both from library dependencies and your own package.

  • To censor warnings arising from your spago dependencies , set the flag censor_library_warnings under workspace > build_opts
  • For package level warnings, the ones coming from your source code, enable the flag censor_project_warnings under package > build

Methods of Censoring Warnings

You can censor warnings in three ways, applicable to both censor_library_warnings and censor_project_warnings:

  • Remove all the warnings
package:
censor_project_warnings:
all
  • Censor warnings by warning code

If you know the specific warning code you wish to censor, you can list them here.

package:
censor_project_warnings:
- WarningCodename1 -- e.g UnusedName
- WarningCodename2
- WarningCodenameN

Note : Spago will show the warning codes when the warnings are being displayed, but you can also find a list of error & warning codes here

  • Censor warnings by prefix

This is useful for filtering warnings based on the warning message itself, especially useful for custom warnings without a specific code.

For example, if a warning message is The import of Data.Maybe is redundant. I want to censor the warning I can simply do,


censor_project_warnings:
- by_prefix: >
"The import"

Note the block quote > , this is a way of specifying multi-line text in yaml files but for single line you can simply use plain old double quotes.

  • By Mixing the censor methods

One more thing to note here is you can mix both the censor by error code and prefix-based censorship.

censor_project_warnings:
- ImplicitImport
- by_prefix: "The import"
- UnusedName
- by_prefix: "Module Prelude"

3. Stats

  • One thing I find a nice add-on in spago is, is its ability to print statistics for every rebuild. It can provide insights like how many errors, warnings are there and from where they are coming from(whether libraries/your source files).
  • There are three levels of stats: no-stats, compact-stats(default), verbose-stats. You can change the stats level by assigning one of the above 3 values to the field stat_verbosity under workspace > build_opts
workspace:
build_opts:
stat_verbosity: "verbose-stats"
compact-stats
verbose stats

4. Chaning the output directory

You might know how to change the build directory by passing output options to spago build

spago build --output output_folder
  • You can also specify the build directory in spago.yaml itself, using the field output under the section workspace > build_opts
workspace:
build_opts:
output: "output_folder"

5. Pedantic Packages

There are instance when,

  • You may have a package specified in your spago.yaml dependency list but not actually using it, making it a redundant import
  • You could use a package ‘x’ without explicitly listing it in spago.yaml’s dependency list. It’s added to your .spago folder as it’s a transitive dependency of ‘y’. But what if you remove ‘y’ from your dependencies? Here, the package ‘x’ is termed as an underspecified import, as it’s used without being explicitly specified as a dependency.

Redundant and underspecified imports cannot be identified by censor warnings or the compiler. To address these issues, Spago offers a feature called pedantic_packages under package > build. When set to true, encountering either of the two cases mentioned will result in a compilation error.

package:
build:
pedantic_packages : true

6. Alternate backend

This might be something new to you if you don’t know that purescript can compile to several other languages other than javascript, and they are termed as purescript (alternate) backends By default, purescript, when no backend is specified explicitly uses js as backend(that’s why you might not be aware of this feature)

Spago offers support for compiling with different backends. For example, purescript has a Erlang backend, to use that, first install purerl and then you specify the command to build the project on cmd section of workspace > backend

workspace:
backend:
// first make sure `purerl` is in your path
// you can download it from the below page
// https://github.com/purerl/purerl/releases/tag/v0.0.22
cmd: purerl
args:
- "arg1"
- "arg2"
- "arg3"

Features/Supports Removed in new spago

1. Watch Option

  • Unfortunately, the watch option has been removed in the latest version of Spago. However, this functionality can be substituted by utilizing your Purescript LSP (Purescript IDE if you are a VScode user, purescriptls for nvim users etc) can do the automatic rebuilds and provide diagnostics in realtime.
  • In cases where you still need watch mode functionality, such as running tests whenever files change, you can utilize third-party file watching libraries like watchexec.
watchexec --exts purs,js,yaml -- spago test
  • The command above triggers spago test whenever there are changes to any files with the extensions .purs, .js, or .yaml inside the current working directory.

2. Specifying source files

If you’ve used the old Spago configuration (spago.dhall / packages.dhall), you may recall a field called “sources” which specifies globs to indicate which files should be compiled.

-- spago.dhall
{
-- other configs
, sources = [ "src/**/*.purs"
, "test/**/*.purs"
, "other/**/*.purs" ]

}
  • In the new version of spago, only files under src and test folder are compiled.If you need to compile files from additional folders, consider using a monorepo approach.

Thanks for sticking around till the end😊! Now you’re armed with all the wisdom you need for configuring Spago builds. In the next article, we’ll delve into configuring run and bundle options. So stay tuned!

If you enjoy delving into Purescript or functional programming in general, consider following for more useful content.

--

--

Saravanan M

A place where I share my perspective on the tech topics I've read and enjoyed. Sometimes highly opinionated.