Systematic web apps development (notes towards…). The method I follow with my still work in progress Constitution stack.
-
Project
Initialize codebase, workflow.
(The least important step. Nu, from a marketing perspective (funnel), assuming a long tail distribution of adoption (time spent with this stack), it makes sense to emphasize painless installation and… but, at what price? I do 1,000 hours scale projects. It’s astonishing how frameworks fuss about the first five minutes, and hardly give thought to the rest. Market failure much?)
-
Skeletons
- Download as zip, unzip it, and init Git/flow.
- Or, clone it:
$ mkdir $PROJECT/Code; cd $PROJECT/Code # (How I usually name a repo.) $ git clone $SKELETON .
But, don’t need history:
$ git clone --depth 1 --branch master $SKELETON .
Records cloned remote as “origin”. Remove:
$ git remote rm origin
Or keep and rename that remote, so can diff against future skeleton updates?
$ git remote rename origin skeleton
- Or, copy repository? .gitignore? Then, init Git/flow.
- Or, start from scratch.
-
From scratch
- Git/flow
- .gitignore (GitHub can generate it, if repo created there.)
- README.md (or index.html for GHP? Separate branch?)…
-
Git/flow
- Have Gitflow installed globally.
- Initialize:
$ git flow init --defaults
creates a local development repo, if wasn’t cloned from a skeleton or GitHub. Switches branch to develop.
-
Metadata
- Edit {package,bower}.json. DRY?
-
Remote
-
Setup Git
Useful .git/config, or global, settings:
- Cache passwords:
$ git config --global credential.helper "cache --timeout=9999"
Cf git help credential-cache (or man git-credential-cache).
- Force HTTPS for when (public) Wi-Fi blocks SSH port:
$ git config --global url.https://.insteadof git://
Cf git help config.
$ git config push.default current
so can just “git push” from separate local clones of different branches, particularly “gh-pages”.
- Bash aliases, prompt, and completion fix.
Etc.
- Cache passwords:
-
Go public
Release early and often!
FLOSS motto- Release:
$ git checkout master; git merge develop; git tag 0.0.1 $ git push --force
- Back to development:
$ git checkout develop
- Release:
-
It works!
- Prerequisites
- Dependencies
- Environments
- Run
- Watch
-
Dependencies
- Versions: be specific.
Use the source, Luke!
: we prefer sources over package managers’ repositories: use URL to Git (typically) repo in {package,bower}.json. Public or local.- When using private repositories on GitLab, set up SSH keys to allow (passwordless) access, when using SSH based URLs (git://gitlab.com/…), or generate access tokens for HTTPS URLs (git+https://…) — don’t use your GitLab account credentials!
- Build? Source shouldn’t contain compiled files, we must build them after installing (which clones(?) the tagged version we specified). (Package managers’ repositories (npm, Bower) usually publish pre-built packages.)
-
$ npm install; bower install
- Distribution: map files we use to (copy to) our ./dist/.
- CDN: see under Templates→Double Macchiato→Helpers→cdn_script, et al
-
Environments
- Set PORT, or run temporarily with:
$ PORT=3099 cake start browser - DOMAIN?
- Not config.coffee — feature toggling.
- PM2: ecosystem.coffee.
- Sane defaults: during build-time, prefer crashing when misconfigured, but never at runtime.
- Set PORT, or run temporarily with:
-
Run
-
$ cake start browser
-
-
SDLC
- Wireframes (UI features specifications)
- APIs (Server-side/services specifications)
- Continuous (development)
-
Wireframes
- Content
- POP
- Screens
- URLs
- Navigation
- SPAs
- Grayscreening
- Layouts
-
Content
- OOA: dictionary (inventory) of nouns and verbs. Or, ERD-like, domains and properties?
- Information architecture
-
POP
- Prototyping on paper (POP)
- Extremes first: “deep” RWD, instead of narrow first, aka mobile first, in the olden days of “shallow” RWD.
- Very narrow: break words, never scroll horizontally.
- Very wide: how to avoid letterboxing? What content can be spread horizontally? Columns?
- Input methods: pointer/touch (adapt/consolidate?).
-
Screens
- Content to display/hide when navigating within SPA.
- List screens. Per SPA. (“Screen” includes modals, mutations… anything that’s recorded in navigation history, ie back button applies. At least?)
- Widgets: inventory (sub)components of screens; separate list for recurring.
-
URLs
- URL is UI: TBL’s bar napkin
- Hierarchical navigation, directories: trailing slash, redirect.
- Redirect changed/misspelled URLs; search (cf rel:search)?
- L10n prefix
- Query: KV dictionary, unordered, named, optional, built-in form submission.
- History API
- Bookmarks
- Method semantics? Fragment?
-
Specifications
Screen URL Selector Favorites /favs #favs … Item /items/:id #item … Catalog /items/ #catalog Listing. (Redirect if missing trailing slash.) -
Navigation
- Nav conceptual structure/organization; cf “lost in hyperspace”.
- Also: redirections (eg root(s), auth’ dependent), screens without URLs (no history tracking)…
-
SPAs
- Single Page App: combine screens into (one or more) SPAs to avoid full page rendering.
- Eg: public.html, logged-in.html, admin.html, landing.html.
- When/where to render?
- Templates
- Routing
- History API
-
When/where to render?
- Server-side or in browser?
- Build-time or run-time? Both?
-
Templates
- Per SPA; eg: public.html.coffee, logged-in.html.coffee, admin.html.coffee, landing.html.coffee.
- i18n/L10n: rendered into static assets once; eg app.language.html.coffee will be rendered into app.en.html, app.es.html, etc.
- CoffeeScript modules exporting an HTML renderer:
# public.-.html.coffee module.exports=renderable (lang)-> html5bp {lang},-> title 'Skeleton (Public)' #…
(See skeleton for useful “templates”.)
- Source ordering
-
Routing
- Express routing: order significant: decreasing specificity
- Route all URLs to corresponding SPA, so they can be bookmarked, shared.
app # Express. # Public (anonymous) SPA. .all /\/(..)\/(|login|logout|terms)$/,(req,res)->res.sendfile ASSETS+"/public.#{req.params[0]}.html" # Admin SPA. .all /\/(sys|error)$/,(req,res)->res.sendfile ASSETS+'/admin.html'
- Redirects: eg, to pick language prefix:
.all /\/([a-z]{2})?$/i,(req,res)->res.redirect "/#{pick_language req}/"
(Redirect to appropriate SPA based on optional path parameter, session (cookie), or UA preferences.)
- Directories in URL path, for namespacing collections:
# Directories: redirect to append slash. .all /\/(..)\/(items|profiles|help)$/,(req,res)->res.redirect req.path+'/'
allowing for URLs like /en/items/foo and /en/items/, not /en/items.
- (Server/client side (SS/CS) scaffolding, helpers… forthcoming.)
-
History API
- Capture navigation internal to an SPA; eg:
## app.coffee page.base "/#{lang}" page '/favs',->show_screen '#favs'; set_title 'Favorites' page '/i/',->show_screen '#dir'; set_title 'Directory' page '/i/:id',->show_screen '#item'; set_title 'Item'
- Render absolute URLs, so can navigate up/down the URL path, eg app.-.html.coffee:
a href:"/#{lang}/i/123",'Item' a href:"/#{lang}/help/me",->i '.fa.fa-question';text 'Help' a href:"/#{lang}/flow",->i '.fa.fa-shopping-cart';text 'Workflow'
- Screens (HTML <section>s) have unique IDs, which show_screen copies to an attribute on <body>:
$('body').attr 'data-screen',p
so can easily target screens in CSS, eg (Stylus):
a header & color inherit [data-screen="#favs"] &.fa-star [data-screen="#profile"] &.fa-user color white
(But, second thoughts about this example: mixing state with styling smells…)
- Capture navigation internal to an SPA; eg:
-
Grayscreening
- Mockups that work in browser!
- Top-down…
- Nav links (backdoor)
-
Layouts
- RWD, eg:
- Narrow (single column): questionnaire screen has outline/nav in collapsed drawer, sliding in from right (align:end)
- Wide (double): questionnaire in right column, outline/nav in left, always expanded
- Huge (triple): wide, plus preview of results in a third column
- Patterns…
- Widgets
- Nav bars, dropdowns, modals…
- RWD, eg:
-
APIs
- No HTML on the wire. [Meteor]
- WS or AJAX? HTTP/2?
-
Continuous
-
Test
- Why?
- Libraries (independent)
- Server-side: APIs
- Client-side: unit vs integration/end-to-end
- Automated:
$ cake test
-
Client-side
- Standalone HTML: render template to load unit tests
- Partial template to embed into app for integration/end-to-end tests
- Client-side code to run, and maybe defer loading of tests
- Styling (mixins) for Mocha’s reporter
-
Release
- Gitflow: merge feature branch into develop
- Version: bump
- Update README: release notes, assign version to tickets
- Merge develop into master — release:
$ go master; git merge develop
- Tag commit with version
-
Topics
-
Editable (WYSIWYG)
-
i18n/L10n
-
Data Modeling and I/O
-
Auth²
-
Styleguide