Skip to content
crocket edited this page Nov 12, 2016 · 14 revisions

Introduction

Using GHCJS is mostly the same as working with GHC: Most of the command-line options are the same, you install packages with Cabal or Stack. This page is for end users, a page with developer information will be added later.

Basic Project Setup with Stack

A basic understanding of stack is assumed in this section. Before diving into the explanation, I'd like to mention that Chris Allen offers a ghcjs starter project. You can learn details of setting up a GHCJS project with his starter kit.

First, learn to set up your stack.yaml for GHCJS from https://docs.haskellstack.org/en/stable/ghcjs/. After setting up stack.yaml for GHCJS, execute

stack setup

to install GHCJS. You can build your project with

stack build

To launch GHCJS REPL, execute

stack ghci

or

stack repl

With some versions of stack or GHCJS, stack ghci or stack repl may not work. In that case, try

stack exec ghcjs -- --interactive

Strangely, some versions of GHCJS don't support REPL. Thus, if GHCJS reports that it doesn't support interactive REPL, change the version of GHCJS in stack.yaml and try again.

Stack Installation Path

It seems ghcjs programs built by stack are stored in stack path --dist-dir and stack path --local-install-dir. If you want to know more stack paths, execute stack path on a shell.

In case that Stack REPL doesn't work.

In at least 2 cases, Stack REPL doesn't work.

  • Stack REPL causes a project to interpret all its modules. If there are too many modules or some modules trigger some bugs, GHCJS REPL could be crashed by segmentation faults. Refer to https://github.com/ghcjs/ghcjs/issues/542
  • If a GHCJS project on which REPL runs contains js-sources in its .cabal file, js-sources are ignored by REPL, so you can't execute functions that depend on js-sources. Check out https://github.com/ghcjs/ghcjs/issues/545 for details.

How can you work around these issues? You can just build the project and launch REPL in a minimal project that depends on the project.

Let's try to develop ghcjs-base on REPL. Let's assume that ghcjs-base is cloned at /repo/ghcjs-base. Create a minimal stack project called ghcjs-base-repl on /repo with

stack new ghcjs-base-repl

Go to /repo/ghcjs-base-repl on your shell. In /repo/ghcjs-base-repl/stack.yaml, you can set up GHCJS as below.

resolver: lts-6.21
compiler: ghcjs-0.2.0.9006021_ghc-7.10.3
compiler-check: match-exact

setup-info:
  ghcjs:
    source:
      ghcjs-0.2.0.9006021_ghc-7.10.3:
         url: http://ghcjs.tolysz.org/lts-6.21-9006021.tar.gz
         sha1: 80b83f85dcec182093418e843979f4cee092fa85

packages:
- '.'
- location: '../ghcjs-base'
  extra-dep: true

It is important to understand extra-dep in packages field. By default, every package in packages is treated as a part of the project. stack ghci tries to interpret every module in every package that is a part of the project. Thus, if you executed stack ghci, it would interpret . and ../ghcjs-base and be crashed by a segmentation fault. If extra-dep was true for ../ghcjs-base, ../ghcjs-base would be treated as a local dependency, and it would not be interpreted. By avoiding interpretation of modules in ../ghcjs-base, you can avoid segmentation faults. You are encouraged to learn more about packages field in stack.yaml configuration documentation on the internet.

You can choose a different combination of resolver and compiler that suits your needs. Set up GHCJS compiler with the following command if you haven't set up the compiler, yet.

stack setup

Are we ready to execute stack ghci in /repo/ghcjs-base-repl? Yes

Whenever you change /repo/ghcjs-base, you exit the repl and execute stack ghci in /repo/ghcjs-base-repl again. This is not ideal, but it's better than nothing. The good thing about executing stack ghci in /repo/ghcjs-base-repl is that when it's executed, it only builds changed parts in /repo/ghcjs-base. You still have semi-automatic incremental builds and REPL.

Interacting with JavaScript

To be described here

  • GHCJS features and limitations
  • Installing and booting GHCJS
    • requirements
    • known issues
    • file locations
  • Running and deploying GHCJS programs
    • testing in terminal
    • minification and compression
    • custom deployment
    • advanced linking: multiple bundles for incremental loading
  • The GHCJS runtime
    • Runtime settings
    • Haskell data: The stack and heap
    • The main loop and scheduler: Synchronous and asynchronous threads
    • Memory management: CAFs and weak references
  • Command line reference (differences from GHC only)
  • Debugging, tracing and profiling
    • debug information
    • options for debug tracing
    • using JavaScript debugging tools