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

Use http://electron.atom.io to make standalone applications #111

Open
jeffreyrosenbluth opened this issue Jun 28, 2015 · 14 comments
Open

Use http://electron.atom.io to make standalone applications #111

jeffreyrosenbluth opened this issue Jun 28, 2015 · 14 comments

Comments

@jeffreyrosenbluth
Copy link

No description provided.

@HeinrichApfelmus
Copy link
Owner

I have already taken a look at Electron and very much liked what I saw. I think this is the most promising avenue for standalone applications with JavaScript.

@jeffreyrosenbluth
Copy link
Author

That's great, let me know if you would like any help.

@HeinrichApfelmus
Copy link
Owner

@jeffreyrosenbluth Since you're offering help: Writing JS driver code the Electron shell should be no problem for me, but I wonder how or if it's possible to integrate this with cabal. It would be great if we could build some kind of cabal-electron package that offers post-build hooks to assemble package bundles from Haskell source files. I'm thinking of something similar to cabal-macosx.

@jeffreyrosenbluth
Copy link
Author

Let me see what would be involved and whether is seems do-able.

@jeffreyrosenbluth
Copy link
Author

This doesn't seem like it would be too difficult so let me see if I understand correctly what would be required. First, if we were going to do it "by hand" we would build the user's application, say app.hs, which imports the threepenny modules to a binary using cabal build. Then we would package this binary together with the JS driver code, a package.json file, and an index.html file if desired we could then use an asar archive to make this into a single app file. The package.json and index.html files would be the same for every app?

If this is correct I think that cabal integration would be fairly straight forward. Much of cabal-macosx deals with handling dependencies. I don't think we would have any dependencies that are not handled by regular cabal or are included in our static js code.

Let me know if you agree with this assessment and we can decide the best way to proceed.

@HeinrichApfelmus
Copy link
Owner

Yes, pretty much. Essentially, we need a post-build hook that copies the executable and the index.html and package.json files into a common directory, so that Electron can find a complete directory structure.

My problem is that I don't know much about Cabal. If you could figure out how to make such a post-build hook, then that would help me a lot.

@jeffreyrosenbluth
Copy link
Author

I don't know that much about Cabal either but I think I'll be able to figure it out.
I'll start working on it.

@HeinrichApfelmus
Copy link
Owner

I have successfully hooked up Threepenny-GUI to Electron.

I still don't know how to offer this functionality via .cabal files, though. Electron is an external dependency, the precompiled binary weighs 30-40MB (for version 0.33) for each platform. Application bundles have to be built by copying the relevant files.

@jeffreyrosenbluth
Copy link
Author

I have to apologize, I thought I would have time to work on this, but I'm tied up on a large project for the foreseeable future. Sorry about that, I may still be able to do it, just not for a while.

@HeinrichApfelmus
Copy link
Owner

No worries, this is a completely voluntary activity, after all. 😄

@tr00per
Copy link

tr00per commented Oct 6, 2015

I have successfully hooked up Threepenny-GUI to Electron.

Do you consider releasing a HOWTO for that?

@bradrn
Copy link
Contributor

bradrn commented Feb 19, 2017

I think I've figured out how to hook up Threepenny-GUI to Electron. What you do is:

  1. Build the Haskell program and move the executable to the root of the program
  2. Add this as your package.json:
    {
        "name": "<name>",
        "version": "0.1.0",
        "main": "./main.js",
        "scripts": {
            "start": "electron ."
        }
    }
  3. Run npm install --save-dev electron
  4. Put this as your index.html:
    <webview src="http://localhost:<port>" style="width: 100%; height: 100%"></webview>
  5. Add the quickstart main.js file here.
  6. Add the following to main.js just before it says mainWindow.loadURL(url.format({ (line 19):
    const execFile = require('child_process').execFile;
    const child = execFile('./<haskell-program-name>');
  7. You might want to remove the lines of code which open the developer tools from main.js (it's well-commented, so they should be easy to find)
  8. Run the program using npm start

I've managed to get the sample programs distributed with threepenny-gui working using this method.

@jerbaroo
Copy link
Contributor

jerbaroo commented Feb 28, 2017

Here's a method of doing this without custom HTML or moving an executable, it starts the app on a free port and waits until the Threepenny app is running before starting an Electron renderer process (display window).

  • Add the following files to your project root directory:
  • Edit your Haskell main to take a port as an argument and run on that port:
module Main where

import System.Environment (getArgs)
import YourApp            (start)

main :: IO ()
main = do
    [port] <- getArgs
    start (read port)
  • Edit line 41 of electron.js to run your application, currently:
child = spawn('stack', ['exec', 'your-app-exe', `${port}`]);

Now to run the whole thing:

npm install
stack build
./node_modules/.bin/electron electron.js

Edit: Note the only Stack specific instructions for this are: stack build; to build the binary, and line 41 of electron.js; to run the binary. These can be replaced respectively with another command to build your application and an edited form of line 41 to run the binary.

@bradrn
Copy link
Contributor

bradrn commented Mar 1, 2017

... without moving the executable ...

The reason I used the method of 'moving the executable' instead of stack exec <program> is that the threepenny-gui executable can then be used on a computer without stack.


I'm going to create a repo with all the config files in it as an example of how to integrate threepenny-gui and electron. I'm having a bit of trouble with pushing the files though so I'll do it after I fix that.

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

5 participants