GettiNG started with Angular

Best practices when starting a new project

@seangwright
seangwright

2018/02/06

At a high level

  1. Conventions, formatting and tooling
     
  2. Project architecture
     
  3. Application infrastructure

Conventions, formatting and tooling

or

How I

learned to

stop worrying

about

tabs vs spaces

and

love programming

again

From this▲to this▼

  • Develop the Angular application outside of your backend project
    • Put it in its own repository
    • Can be versioned / deployed separately
    • Doesn't confuse the tooling
    • Treats it as a real application
      • Javascript developers are people too!
         
  • Use VS Code for the best experience
    • Both as a team and a developer
    • Workspace settings live in the repo
      • \.vscode\.settings.json
    • Strong support for extensions used in Angular projects, well regarded by the front-end dev community
  • Use tooling to kill disagreements!
    • VS Code extensions: TSLint, Prettier, Editorconfig, SCSS IntelliSense
      • \.vscode\.extensions.json
    • 'Strict' Typescript settings in tsconfig.json
      • Editor and compilation checks
    • 'Format on Save' + Prettier = no need to reformat someone else's code
      • Let Prettier be the bad guy!
         
  • Naming and syntax conventions
    • Singular for features/modules, singular or plural for components/services/directives (plural can be tricky)
    • Component and directive prefix of 2 or 3 characters (keeps templates readable)
  • Use Angular style commit messages
    • Examples
      • 'feat(notification.service): add display param'
      • 'refactor(order models): rename couponId to couponCodeId'
        
        
  • Consistent component/directive/service/module file creation
    • See: Project Architecture - Use Angular CLI
       
  • Absolute paths for ES Modules
    • Helps in refactoring (moving files around or renaming)
    • Easier to organize alphabetically
    • See: Project Architecture - Keep a flat file structure
      • * caveats
  • Do not use null!
    • Javascript already has undefined
    • 1 option is better than 2 used randomly
    • Explicitly type a field/method/variable as undefined if it can be
      • See: below
         
  • Assign default values everywhere you can
    • Helps prevent annoying errors
      • "Cannot read property 'name' of undefined"
      • Null is the 'billion dollar mistake'
    • Choose intelligent defaults and be consistent with them
      • '' for string
      • 0 for number
      • [] for arrays
        • Predicatable and work well in expressions
          • if (user.id || user.name) { // do something }

Questions,

thoughts,

concerns?

Links

Links

Links

Project Architecture

Planning and consistency!

 

... because building things is hard enough already

or

  • Follow the Angular Style Guide
    • It's not the final word but it's a great place to start
      • Take what works for your team and skip what doesn't but learn from other's mistakes
        • Same goes for this talk! (meta!)
    • Feature modules, Core/Application module and Shared module
       
  • Keep a flat file structure as long as possible
    • Don't add hierarchy with less than 20 files
    • You can always move files as the app grows
      • See: Conventions, formatting and tooling - Absolute paths for ES Modules
        • * caveats
  • Remove floating semver in package.json
    • Use package management tooling to guarantee reproducible dev environment and builds
      • package-lock.json
      • yarn.lock
        
        
  • Use yarn?
    • Faster installs (+) but extra toolchain piece (-)
    • Decide before starting your project and run
      • ng set --global packageManager=yarn
        
        
  • Maintain your application version
    • 1 source of truth (package.json is a nice place)
    • Use to deploy the version with and embed in your app
      • See below: Enhance the CLI build process
  • Enhance the CLI build process
    • Use pre/post hooks in npm scripts to simplify commands
    • Create a folder to contain all your build infrastructure
    • You don't need Gulp/Grunt, just Node
      • Assuming NodeJS v8.x for dev environment
      • Typescript
      • Async/await for file system access
      • Helpful packages
        • fs-extra, colors, pjson, ts-node, dateformat, tar
    • Generate pre-build
      • version.ts, version.json
    • Generate post-build
      • v.<version>.txt, .tar.gz
    • Can be used to build more complex pre/post assets
      • i18n build process support
  • Set custom host for your app
    • http://localhost:4200 is ok for a demo
    • But http://client-app-accounting.company.io is better
      • Helps when logging request Origin / Referrer
         
  • Use proxies if integrating with an API
    • No need to change API Uri base on environment
    • Can re-write set-cookie headers

Questions,

thoughts,

concerns?

Links

Application Infrastructure

Let's get into some code

(the weeds)

or

  • Lazy load everything
    • The CLI makes this easy
    • Helps break up your app into logical bundles
      • Both architecturally and on the filesystem when deployed
    • Users only pay for what they want
    • Sensitive (admin only) code isn't downloaded for users that don't have access
       
  • Add a debug.service.ts
    • Replaces calls to console.<X>()
    • Track calls in codebase with CodeLens
    • Toggle on/off at runtime with localStorage
      • Off by default with production builds
  • Type unions can replace Enums and magic strings
    • Great for common messages displayed in UI
    • Helpful for content managers (BA / Product owner) to centralize messaging for review
    • Becomes a resource string dictionary
      • Extends to i18n integration
    • Still gives type support! Typescript FTW!
  • RxJS Lettable operators
    • Import only what you need
      • Combined with tsconfig noUnusedLocals
        • See: Conventions, formatting and tooling - 'Strict' Typescript settings
           
  • Use ES Modules for helper functions
    • Don't need formality of DI if they don't have state
    • Easy to import, only available where needed
    • See: parameterize, serialize, buildDefaultForm
       
  • Keep hardcoded environment values in environment files
    • Use XHR request, pre-app init, for config values deployed out of band from Angular build process
      • Can be helpful to manage ENV values in CI/CD
  • Avoid base classes / inheritance
    • If necessary, then keep the API thin otherwise you restrict flexibility as your app grows and use-cases change
    • Create a utility.service.ts to contain all base helper services
      • Examples
        • debug.service.ts
        • notification.service.ts
        • session.service.ts (auth / user state)
      • Helps prevent app-wide changes to base constructor
         
  • Use Observable management patterns
    • ngUnsubscribe for complex Observable management in Components
    • Use shareReplay operator and/or async pipe for simpler cases
  • Client-side application updates
    • Consider browser caching
    • How to force client app updates when the backend API changes?
    • Figure out user experience and implementation architecture for updating
      • Modals vs buttons? Can user delay updates?
      • Process transparent to user?
      • How often to check for updates on server?
      • Test the update process, experience across browsers!
    • Take steps on server side
      • Cache headers on index.html
    • Embed version in app
      • See: Application architecture - Maintain your application version
  • Use global error handler to store/report errors to API
     
  • Don't access global Document or Window objects
    • Angular API probably provides a way around this
    • If you need too, create wrapper WindowRef/DocumentRef services
      • Can be swapped out during SSR
         
  • Create IEnvironment interface to keep environment files in sync
     
  • Use feature module 'root' components
    • Easy to apply styling / UI for all components / routes in a feature
    • Helps handle Angular router caching components when route changes

Questions,

thoughts,

concerns?

Links

Links

Thanks!

Now, let's look at code (if there's still time)

Made with Slides.com