The main front-end app, it will boot up a service worker (see below client-service-worker) for user's SPA project. Borrowed many code from gist-run.
The front-end worker, runs dumber bundler inside browser. Cache traced local files locally in indexedDB (localforage), cache traced npm files in globally shared https://cache.dumber.app
(https://cache.dumber.local
for local dev environment).
Npm packages are retrieved from jsdelivr. Dependencies tree is resolved using code borrowed from stackblitz turbo-resolver.
The front-end service worker, generates responses for embedded app https://[random-32-chars-hex].gist.dumber.app
.
The static resources are not cached by CloudFlare. Because:
- CloudFlare free plan doesn't cache wild card DNS name.
- it doesn't make any sense to cache unrepeatable host name.
The back-end for client to save globally shared tracing cache. Note all tracing work is done at front-end, the back-end is very simple. To avoid abuse, saving-cache only applies for front-end signed in with GitHub account. The back-end double-checks user GitHub token.
Caches are saved in server/dumber-cache/public
. The static files are served directly from nginx, not from passenger.
For privacy, only traced code for npm packages are cached globally. Users' code are cached only locally in indexedDB.
The back-end for retrieving GitHub token after user attempted GitHub signing in. The back-end exchanges a code with a token. This back-end is necessary for hiding GitHub client secret from front-end side.
The code is based on gist-run github-oauth-server.
A local nginx dev config file for local development against gist.dumber.local
. This file is for macOS. It requires some changes to work in Linux. See below for more details.
An example config file for production deployment for gist.dumber.app
, without real certificate and GitHub client secret.
It is deployed to a small box in Digital Ocean. Technical, this single VM structure doesn't scale, but this single VM structure is the simplest for local development, also nginx+passenger+nodejs with two extremely simple back-ends should be able to handle very large traffic, even on a $5/month DO box.
In addition, gist.dumber.app
and cache.dumber.app
are behind a CloudFlare free plan. Thanks for CloudFlare, all static resources of dumber gist are properly cached in a CDN to enable fast boot up.
Following dnsmasq setup resolves any.domain.ends.with.local
to 127.0.0.1
.
brew install dnsmasq
echo 'address=/local/127.0.0.1' >> `brew --prefix`/etc/dnsmasq.conf
sudo mkdir -p /etc/resolver
sudo echo 'nameserver 127.0.0.1' > /etc/resolver/local
sudo brew services start dnsmasq
brew install nginx passenger
Overwrite /usr/local/etc/nginx/nginx.conf
with the content of nginx.dev.conf
.
Then need to adjust values of few paths inside the config.
# You need to generate a self-signed certificate for these two
ssl_certificate
ssl_certificate_key
# You local nodejs path
passenger_nodejs
# Change to your local dumber-gist folder
root
Start nginx with
brew services restart nginx
You may encounter permission issue that nginx cannot open port 443, try
sudo brew services restart nginx
I don't need sudo for port 443 to work. I don't remember what I did (long time ago) to allow port below 1024.
If you use sudo to start nginx, don't worry, as a security feature, nginx will downgrade itself to a user (default to the user of the app) after started.
Before using the app, first you need to build client
code. Run
cd client/
npm i # or yarn or pnpm i
npm run build
Optionally, replace npm run build
with npm start
to build them in watch mode.
Use Safari, Chrome or Firefox to navigate to https://gist.dumber.local
.
Note, in watch mode, there is no special dev server to auto refresh browser window. You need to manually refresh browser window after the code changes were built.
Because of self-signed certificate, you will see browser complains about the security. You need to create your own certificate authority root certificate, install mkcert
brew install mkcert nss
mkcert -install
mkcert dumber.local '*.dumber.local' '*.gist.dumber.local' localhost 127.0.0.1 ::1
Note nginx.dev.conf
uses the generated certificate.
Setup acme.sh for certificate renewal. https://github.com/acmesh-official/acme.sh
Install it under root user, then run following two commands.
acme.sh --issue --dns dns_cf -d '*.gist.dumber.app' --server letsencrypt
acme.sh --install-cert -d '*.gist.dumber.app' --key-file /root/gist.dumber.app.key.pem --fullchain-file /root/gist.dumber.app.cert.pem --reloadcmd "service nginx force-reload"
acme added crontab job to renew the cert every 3 months.
Also need to make sure nginx user "www-data" has access to the app files.
chown -R o+rx /home/huocp