Constitution: a Method to the Madness

Systematic web apps development (notes towards…). The method I follow with my still work in progress Constitution stack.


  1. Project

    Initialize codebase, workflow.

    1. Skeletons: quick start
    2. Metadata
    3. Remote: distributed, collaboration
    4. It works!

    (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?)

  2. Skeletons

    1. Download as zip, unzip it, and init Git/flow.
    2. 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
    3. Or, copy repository? .gitignore? Then, init Git/flow.
    4. Or, start from scratch.
  3. From scratch

    1. Git/flow
    2. .gitignore (GitHub can generate it, if repo created there.)
    3. README.md (or index.html for GHP? Separate branch?)…
  4. Git/flow

    1. Have Gitflow installed globally.
    2. Initialize:
      $ git flow init --defaults

      creates a local development repo, if wasn’t cloned from a skeleton or GitHub. Switches branch to develop.

  5. Metadata

    1. Edit {package,bower}.json. DRY?
  6. Remote

    1. GitLab: create repo there, then copy canonical URL.
    2. Set remote:
      $ git remote add origin https://gitlab.com/$ACCOUNT/$PROJECT
    3. Use canonical URLs in package.json (homepage, repository, bugs), BJ, etc.
    4. Go public
  7. Setup Git

    Useful .git/config, or global, settings:

    1. Cache passwords:
      $ git config --global credential.helper "cache --timeout=9999"

      Cf git help credential-cache (or man git-credential-cache).

    2. 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”.

    3. Bash aliases, prompt, and completion fix.

    Etc.

  8. Go public

    Release early and often!FLOSS motto

    1. Release:
      $ git checkout master; git merge develop; git tag 0.0.1
      $ git push --force
    2. Back to development:
      $ git checkout develop
  9. It works!

    1. Prerequisites
    2. Dependencies
    3. Environments
    4. Run
    5. Watch
  10. Dependencies

    1. Versions: be specific.
    2. Use the source, Luke!: we prefer sources over package managers’ repositories: use URL to Git (typically) repo in {package,bower}.json. Public or local.
    3. 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!
    4. 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.)
    5. $ npm install; bower install
    6. Distribution: map files we use to (copy to) our ./dist/.
    7. CDN: see under Templates→Double Macchiato→Helpers→cdn_script, et al
  11. Environments

    1. Set PORT, or run temporarily with:$ PORT=3099 cake start browser
    2. DOMAIN?
    3. Not config.coffee — feature toggling.
    4. PM2: ecosystem.coffee.
    5. Sane defaults: during build-time, prefer crashing when misconfigured, but never at runtime.
  12. Run

    1. $ cake start browser
  13. SDLC

    1. Wireframes (UI features specifications)
    2. APIs (Server-side/services specifications)
    3. Continuous (development)
  14. Wireframes

    1. Content
    2. POP
    3. Screens
    4. URLs
    5. Navigation
    6. SPAs
    7. Grayscreening
    8. Layouts
  15. Content

    1. OOA: dictionary (inventory) of nouns and verbs. Or, ERD-like, domains and properties?
    2. Information architecture
  16. POP

    1. Prototyping on paper (POP)
    2. Extremes first: “deep” RWD, instead of narrow first, aka mobile first, in the olden days of “shallow” RWD.
      1. Very narrow: break words, never scroll horizontally.
      2. Very wide: how to avoid letterboxing? What content can be spread horizontally? Columns?
    3. Input methods: pointer/touch (adapt/consolidate?).
  17. Screens

    1. Content to display/hide when navigating within SPA.
    2. List screens. Per SPA. (“Screen” includes modals, mutations… anything that’s recorded in navigation history, ie back button applies. At least?)
    3. Widgets: inventory (sub)components of screens; separate list for recurring.
  18. URLs

    1. URL is UI: TBL’s bar napkin
    2. Hierarchical navigation, directories: trailing slash, redirect.
    3. Redirect changed/misspelled URLs; search (cf rel:search)?
    4. L10n prefix
    5. Query: KV dictionary, unordered, named, optional, built-in form submission.
    6. History API
    7. Bookmarks
    8. Method semantics? Fragment?
  19. Specifications

    Screen URL Selector
    Favorites /favs #favs
    Item /items/:id #item
    Catalog /items/ #catalog Listing. (Redirect if missing trailing slash.)
  20. Navigation

    1. Nav conceptual structure/organization; cf “lost in hyperspace”.
    2. Also: redirections (eg root(s), auth’ dependent), screens without URLs (no history tracking)…
  21. SPAs

    1. Single Page App: combine screens into (one or more) SPAs to avoid full page rendering.
    2. Eg: public.html, logged-in.html, admin.html, landing.html.
    3. When/where to render?
    4. Templates
    5. Routing
    6. History API
  22. When/where to render?

    1. Server-side or in browser?
    2. Build-time or run-time? Both?
  23. Templates

    1. Per SPA; eg: public.html.coffee, logged-in.html.coffee, admin.html.coffee, landing.html.coffee.
    2. i18n/L10n: rendered into static assets once; eg app.language.html.coffee will be rendered into app.en.html, app.es.html, etc.
    3. CoffeeScript modules exporting an HTML renderer:
      # public.-.html.coffee
      module.exports=renderable (lang)->
      	html5bp {lang},->
      		title 'Skeleton (Public)'
      		#…
      

      (See skeleton for useful “templates”.)

    4. Source ordering
  24. Routing

    1. Express routing: order significant: decreasing specificity
    2. 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'
      
    3. 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.)

    4. 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.

    5. (Server/client side (SS/CS) scaffolding, helpers… forthcoming.)
  25. History API

    1. 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'
      
    2. 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'
      
    3. 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…)

  26. Grayscreening

    1. Mockups that work in browser!
    2. Top-down…
    3. Nav links (backdoor)
  27. Layouts

    1. RWD, eg:
      1. Narrow (single column): questionnaire screen has outline/nav in collapsed drawer, sliding in from right (align:end)
      2. Wide (double): questionnaire in right column, outline/nav in left, always expanded
      3. Huge (triple): wide, plus preview of results in a third column
    2. Patterns…
    3. Widgets
      1. Nav bars, dropdowns, modals…
  28. APIs

    1. No HTML on the wire. [Meteor]
    2. WS or AJAX? HTTP/2?
  29. Continuous

    1. Uptodate? Secure?
    2. Test
    3. Release
    4. Deploy
    5. Publish
  30. Test

    1. Why?
    2. Libraries (independent)
    3. Server-side: APIs
    4. Client-side: unit vs integration/end-to-end
    5. Automated:
      $ cake test
  31. Client-side

    1. Standalone HTML: render template to load unit tests
    2. Partial template to embed into app for integration/end-to-end tests
    3. Client-side code to run, and maybe defer loading of tests
    4. Styling (mixins) for Mocha’s reporter
  32. Release

    1. Gitflow: merge feature branch into develop
    2. Version: bump
    3. Update README: release notes, assign version to tickets
    4. Merge develop into master — release:
      $ go master; git merge develop
    5. Tag commit with version
  33. Topics

  34. Editable (WYSIWYG)

  35. i18n/L10n

  36. Data Modeling and I/O

  37. Auth²

  38. Styleguide



Comments are closed.