Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to build command to watch for file changes #65

Closed
alex-ketch opened this issue Jan 5, 2019 · 13 comments
Closed

Add ability to build command to watch for file changes #65

alex-ketch opened this issue Jan 5, 2019 · 13 comments

Comments

@alex-ketch
Copy link

Hi there, and thanks for Spago!

As I was creating a fork of a react-basic-starter to use Spago, I wanted to recommend a way to have the project be auto-built when making changes.
Right now there is in a workaround for people using IDE PureScript, but it would be nice to have an alternative for people who don't use the plugin.

I realize this is a little bit more complicated since Spago uses purs under the hood, and unlike pulp it doesn't support the watch flag.

As an aside, the project seems to work like a treat combined with Parcel 🎉

@alex-ketch alex-ketch changed the title Add ability watch flag to the build command Add ability to build command to watch for file changes Jan 5, 2019
@justinwoo
Copy link
Contributor

Personally I use either the normal psc-ide plugins or https://github.com/watchexec/watchexec

@f-f
Copy link
Member

f-f commented Jan 6, 2019

Hi @alex-ketch, and thank you for making the spago-react-basic-starter!

As Justin already noted, if you use psc-ide with some editor you get this rebuilding for free, and if you're not you can use watchexec (e.g. like watchexec -i src spago build).

So in the end it is possible, but not super nice (as you have to install another tool), and I agree that it might be worth to just integrate the file watching into Spago.
I probably won't get around implementing this soon, so I'll leave here a draft for a possible implementation:

  • depend on fsnotify
  • when the --watch flag is specified, watch on src folder and run build on modifications
  • fsnotify supports debouncing (e.g. if you save the same file twice in a short amount of time, you should build only on the second time), but particular attention should be put on tweaking the debounce value, and probably it'd be necessary to have a semaphore (e.g. a data Building = NotBuilding | FinalBuild | ShouldBuildAgain in an MVar) to signal if we are building, and if we should enqueue another build (as you don't want two builds going on at the same time)

@f-f
Copy link
Member

f-f commented Jan 27, 2019

Here's Stack's implementation of this feature. It's 100 lines, so it should be easy to port here

@f-f f-f added this to the 1.0 milestone Feb 6, 2019
@f-f
Copy link
Member

f-f commented Mar 10, 2019

Fix up in #126

@f-f f-f closed this as completed in #126 Mar 14, 2019
@dlight
Copy link

dlight commented Jun 14, 2019

So.. how do you run parcel (or some other custom command) after every time a build is triggered?

Something like this would be useful:

spago bundle-app --to dist/index.js --watch --run-after "parcel blabla"

@JordanMartinez
Copy link
Collaborator

@dlight I think you need to invert your thinking.

Make parcel watch for file changes where one of its files (say an HTML file) references the bundled app or module that spago produces (which will cause parcel to watch that file for changes, too) and then make spago bundle its app/module using its watch command.

When you make changes to your source code, spago sees the change and rebundles the app/module, which is seen by parcel and causes parcel to rebuild the page.

@dlight
Copy link

dlight commented Jun 16, 2019

@JordanMartinez if I understand correctly, this require running two long living processes in two terminal tabs, which is what I'm trying to avoid.

A workaround is running watchexec, and make it run spago then parcel on each invocation.

@JordanMartinez
Copy link
Collaborator

Ah, with that criteria, then yeah, it requires a workaround.

@dlight
Copy link

dlight commented Jul 16, 2019

Just in case it's useful for someone, I ended up writing this script

#!/bin/bash

function cleanup {
    trap - SIGTERM
    kill -- -$$
}

trap cleanup SIGINT SIGTERM EXIT

rm -f dist/*

while [[ ! -f dist/app.js ]]; do sleep 0.01; done && \
    parcel serve asset index.html -o dist/index.html > \
           >(sed 's/^/(parcel): /') 2>&1 &

spago bundle-app --watch -m App -t dist/app.js #> >(sed 's/^/(spago): /') 2>&1

It runs Spago on the foreground to enable running commands, like build. Parcel hangs if there's no app.js file (even if one is created later), that's why it needs this sleep. I wanted Spago to drive Parcel in order to avoid those kinds of quirks (however, this wouldn't work with parcel serve anyway).

The commented out part would prefix Spago's output with (spago): but it doesn't work because Spago appears to not do line buffering when writing to something that isn't a tty, so nothing shows up until ctrl+d -- then everything appears at once (but Parcel works fine - just without colors - so maybe this counts as a Spago bug?)

I tried working around with stdbuf -oL spago bundle-app --watch -m App -t dist/app.js > >(sed 's/^/(spago): /') 2>&1 but it also doesn't work.

@f-f
Copy link
Member

f-f commented Jul 16, 2019

@dlight just curious about your use-case: why is it a requirement to avoid running two long-lived processes for the watchers?

Also you might be interested in #134 which discusses a possible integration with Parcel (so if that would exist you'd only need to run Parcel and it would call the relevant Spago stuff or keep a watcher and run things in order, etc)

@dlight
Copy link

dlight commented Jul 17, 2019

@f-f I just wanted to avoid opening two terminal tabs, that's all

And, integration with Parcel sounds awesome!

@milesfrain
Copy link
Contributor

milesfrain commented Feb 1, 2020

As Justin already noted, if you use psc-ide with some editor you get this rebuilding for free, and if you're not you can use watchexec (e.g. like watchexec -i src spago build).

Note for new readers, the -i "ignore path" flag should be replaced with the -w "watch path" flag.
@f-f Feel free to edit to prevent additional confusion.

I'm using a combination of these commands in separate terminals for automatic page reloading upon file changes:

  • watchexec -w src -e purs -- spago bundle-app .......
  • parcel serve ........

@windmaomao
Copy link

I used to use nodemon but seems not as general as watchexec.

This works for me, thank you.

  watchexec -w src -e purs -- spago test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants