Search code examples
javascriptnode.jsgithubgithub-pagesharp

Are there any best practices for folder structure with Harp.js and GitHub pages?


I'm using Harp to create a static website that shall be hosted on GitHub pages. So far, everything works, but I'm a little bit concerned about the folder structure.

This is because GitHub pages expects the files that shall be delivered in the root folder of the repository.

So I ended up with the current structure:

/
  .gitignore
  index.html
  _sources/
    harp.json
    README.md
    public/
      index.ejs

What bothers me is that I can not have the README.md file on top-level (which means that when going to the repository on GitHub, I am always told that I should create one, and that I need to step down one level manually), if I do not want the README.md to be public via GitHub pages as well.

Additionally, the build step feels strange. From within the _sources folder I need to run:

$ harp compile --output ..

This somehow feels wrong, compiling something and putting the result in the parent folder. It's a theoretical question, but if there was a _sources folder within the public folder, I'd end up with a big ball of mud :-/

Is there any way of how to structure this so that I can have everything in the _sources folder on top-level, while still being able to serve everything as it now is from GitHub pages?


Solution

  • I've found a great solution for this with the fantastic gh-pages npm module. Here is my setup:

    Relevant dirs/files:

    README.md
    bin/
        publish
    dist/
    node_modules/
    package.json
    src/
        _layout.jade
        index.md
    

    Relevant lines of package.json:

    "scripts": {
      "compile": "harp compile src dist",
      "publish": "npm run compile && bin/publish"
    },
    "devDependencies": {
      "coffee-script": "^1.9.2",
      "gh-pages": "^0.2.0",
      "harp": "^0.13.0"
    },
    

    Contents of bin/publish (this is coffeescript, but you can easily convert it to JS):

    #!/usr/bin/env coffee
    
    ghpages = require 'gh-pages'
    path = require 'path'
    
    handle_error = (error) ->
      if error
        console.error error
        process.exit error.code or 1
    
    dist = path.join __dirname, '..', 'dist'
    
    ghpages.publish dist, handle_error
    

    To publish, I simply run:

    npm run publish

    and it creates the gh-pages branch with the contents of the dist dir as the root of the repo, and pushes it to github!

    In more detail, from the gh-pages docs:

    Calling this function will create a temporary clone of the current repository, create a gh-pages branch if one doesn't already exist, copy over all files from the base path, or only those that match patterns from the optional src configuration, commit all changes, and push to the origin remote.

    This works like a charm for me. Hope it helps others!

    For a full working example, here is a live example repo using all of the configuration described above (and more).