How do I deploy a single-page app. written in Cloj

2019-06-16 20:53发布

问题:

I'm playing with Figwheel and writing a simple single-page app that doesn't require any server-side intelligence.

In principle, this app. could be placed on any static web-server.

But how do I actually deploy it? It looks like the main.js which is in my Figwheel development environment is setting up the figwheel connection.

What js and html files do I actually need to put on my static server? Has Figwheel created them, or do I need to create a new main.js and index.html? And where can I find examples?

The documentation is great for how to get started using Figwheel but surprisingly reticent on what to do after you've finished development.

回答1:

Step 1: Make the production build: lein do clean, cljsbuild once min

Step 2: Put everything in resources/public in a publicly accessible place.

Here is the script I use to do this in an example project: https://github.com/timothypratley/whip/blob/master/deploy.sh

The HTML resources don't change between local development and deployment. The only thing that is different are the compiled artifacts. You can deploy in fact development compiled artifacts just fine too. The only reason it is recommended to do a "production build" is that when developing locally the intermediate JS files are not stitched together, because it is faster to load only the changed code into the browser. For deployment, having a single compiled artifact is better. That single compiled JS can have advanced optimizations, or just simple optimizations depending on how you configure the builds in your project.clj. You don't really need to worry about any of this, I'm just explaining because you asked specifically what changes.

It might sound strange that the HTML page doesn't change at all, so lets explain that a little more. The HTML page includes a compiled JS, when you are running figwheel, if you open up that JS you will see it in turn just loads other JS files. But if you exit figwheel and do a clean "production" build, you will see all the code goes into the one JS file. Pretty tricky huh?

That whip project should provide the example you are seeking, please let me know if any of this is unclear.

It uses github pages and the deployment target, but again you just need everything in the resources/public directory hosted somewhere. So you can use a very similar script with any deployment target.



回答2:

Hat tip to Timothy Pratley for his answer.

I built on it with more details. See https://github.com/deg/clojure-then-you-think/wiki/Static-website-deploy-to-GitHub

But, since the Stack Overflow moderators are rightly worried about off-site answers going stale, here's a full copy, correct as of now:


(Hat tip to Timothy Pratley! The ideas here are based on his, from his whip project and Stack Overflow answer).

Many ClojureScript projects need no explicit server support. Either they do everything in the browser, or they use a cloud-based existing solution for their back-end. An example is my Trilystro toy project which is a re-frame browser app on the front-end and uses a Firebase app for persistent storage.

For this kind of project, a very easy deployment technique is to create a GitHub Pages project page. The cost is zero, and site availability seems to be good (in my very light testing).

Setup

GitHub configuration

GitHub's detailed instructions are on that page, but the steps are really amazingly simple: - On GitHub, go into your projects Settings|Options. - Turn on GitHub Pages (near the bottom of the options pages). - Deploy your compiled project to the gh-pages branch of your project. (see below!) - Your project will now be available at http://YOUR-GITHUB-ID.github.io/YOUR-GITHUB-REPOSITORY - Optionally setup a custom domain - Add your new URL as the custom domain in the options - At your DNS provider, add a CNAME record pointing YOUR-GITHUB-ID.github.io. Important: do not include the repository name here. (A CNAME must point to a host, not a URL). - Add a file named CNAME at the root of your deployed project, containing just the URL

Clojure deployment

We brushed over one critical step above. You must compile your ClojureScript project and get it into the gh-pages branch of your GitHub repository.

In broad strokes, this is very easy: just do a lein cljsbuild and push the results up to GitHub. As always, the devil is in the details. Based on Timothy Pratley's ideas, I've created two scripts that I use in Trilystro. The latest versions are here:

  • First project deployment: first-deploy.sh
  • Ongoing deployments: deploy.sh

Let's look at them in detail: (Note, of course, that I'll probably continue to change these files in the future. The source will be more accurate than the copies below)

Trilystro is still hard-coded into these scripts in a few place. You'll need to search and replace for your own project.

first-deploy.sh
  • Create a directory structure outside the local repo. This is where we will keep our working copy of the deployed site.
  • Initialize a git repo locally
  • Add the CNAME file
  • Associate this repo with the gh-pages branch on GitHub

```

#!/bin/bash

DEPLOYDIR=../trilystro-website
mkdir $DEPLOYDIR
pushd $DEPLOYDIR

git init

cat > CNAME <<EOF
trilystro.vuagain.com
EOF

git add .
git commit -m "Initial deploy to GitHub Pages"
git push --force --quiet "git@github.com:deg/trilystro.git" master:gh-pages

git branch gh-pages
git checkout gh-pages

popd

```

deploy.sh
  • Check that the project is fully committed. We will be marking the deployment with a a git commit SHA, so we want to avoid capturing any stray changes.
  • Clean and build the project. Abort if any errors occur.
  • Clean the deployment directory, then reconstruct the CNAME file and copy in the compilation results.
  • Also copy info about the build into the deployment, in a file called git-describe.txt
  • Commit the new version to GitHub, with a comment describing the version

```

#!/bin/bash
# Adapted from https://github.com/timothypratley/whip/blob/master/deploy.sh
# See also https://stackoverflow.com/questions/37667931/how-do-i-deploy-a-single-page-app-written-in-clojurescript-figwheel-to-a-stat
set -e

DEPLOYDIR=../trilystro-website

RED='\033[0;31m'
NOCOLOR='\033[0m'

function die(){
  echo -e ${RED}"$1"${NOCOLOR}
  exit 1
}

if [ -n "$(git status --untracked-files=no --porcelain)" ]; then
  die "Aborting deploy. There are uncommited changes.";
fi


lein clean
lein cljsbuild once min || die "Lein cljsbuild failed!"

GIT_COMMIT=$(git show -s --oneline HEAD)

pushd $DEPLOYDIR
rm -rf *
cp -r ../trilystro/resources/public/* .
cat > CNAME <<EOF
trilystro.vuagain.com
EOF
popd

git describe --always               > $DEPLOYDIR/git-describe.txt
git log -1 --format=%cd --date=iso >> $DEPLOYDIR/git-describe.txt

pushd $DEPLOYDIR
git add .
git commit -m "Deploy $GIT_COMMIT"
git push "git@github.com:deg/trilystro.git" gh-pages:gh-pages

popd

```