Skip to content

andrewt3000/web_development

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Software Development

This document contains opinions about tools and methods of building web apps.

Dev tools
Front End
Server Side
Database
Dev Ops
Project management

Dev Tools

There are 2 common web architectures:

For web projects, I prefer javascript for fast prototypes with a small number of contributors. I prefer typescript for long term projects with multiple contributors.

I prefer using javascript on the front end because it's native to the browser (this is changing due to web assembly). I prefer Node on the backend because as full stack dev I prefer to work in the same lanuage as it increases javascript fluency.

Another consideration for choosing a backend is integration with the database. It's important that the database api is well supported, stays up to date and has good support for database features and types. Well supported ORMs are another key feature. Here are some well supported backend languages and database combinations:

  • nodejs / mongodb
  • ruby on rails / postgres
  • .net / sql server
  • java / oracle, ibm db2

IDE

Preferred: Visual Studio Code
VS Code has support for productivity features such as emmet and code snippets

  • Configure emmet to work in jsx. (Code > Preferences > Settings: Emmet: Include Languages -> javascript / javascriptreact ).
  • Create custom code snippets (Code > Preferences > Configure User Snippets / Javascript)
	"Print to JSON console": {
		"prefix": "logj",
		"body": [
			"console.log(JSON.stringify($1));",
			"$2"
		],
		"description": "Log json output to console"
	},

Learn useful VS Code shortcuts. Mac / Windows

Alternative: vi

Coding standards

eslint code linter
prettier code formatter.

  • Install VS Code eslint extension.
  • Install VS code Prettier extension and make prettier the default formatter.
  • Install husky pre-commit hook to format code before commit. It's important all code is formatted the same, otherwise it makes diffs and merging conflicts difficult to understand.

variables are in camelCase.

Source Control

Preferred: git (command ref ) - open source, distributed version control

Alternative: Mercurial. git obsoletes many other open source vcs such as rcs, cvs, and subversion.
Best Practice: commit files with github issue number (eg. #151), if you forget leave a comment on the commit with the issue number.

Source control hosting

Preferred: github
Alternatives: gitlab, bitbucket

If you're hosting at AWS you might want to consider Code Commit due to integration features.

Version control workflow

Version control work flow is a function of the size and organization of your team as well as the stage of your project.

As an example, this is a reasonable work flow with multiple developers and an architects where the project is live.

  • Devs work on feature branches.
  • When the feature is complete, devs do a PR (pull requests) to merge their branch to a test branch.
  • Architect approves the PR, inspects and tests the code.
  • Architect merges the test branch to main/master branch which automatically deploys to production through continous deployment process.

App Versioning

Preferred: semantic verisioning
I also plan to track an app version number in the package.json file and reflect that number to users to make sure they have the latest version.

Package manager

Preferred: npm - npm is a cli package manager and task runner. npm hosts a public package repository.
Alternatives: yarn

Updating packages

Best practice: Periodically (weekly?) update javascript packages on front and back end. This is important for security reasons, but can challenging when libraries change and break your project. After upgrading run tests.

# install ncu
npm install -g npm-check-updates  

#command show what needs to be updated
ncu 

#updates the package.json file. 
ncu -u 

SSRs

The current thinking is to use a framework such as remix, next.js, or expo when starting a react project.

Front End

React

Reactjs (docs) - A JavaScript/typescript library for building user interfaces.
chrome extension

I typically use Vite to create react apps. (create react app no longer maintained)

Preference: I generally prefer to use functional rather than class components and to use state hooks and effect hooks rather than state and lifecyle I also would consider using hooks in place of higher order components and render props. It's recommended to not use unneccesary effects and consider server side rendering for event handling.

Alternatives: Angular, Vue (vuex nuxt)
I prefer react because of it's one-way binding rather than two-way binding which is supported in angular and vue. I also prefer using javascript inline rather than directives for control such as ngFor, ngIf (angular) or v-for, v-if (vue). Using javascript inline increase javascript fluency.

Custom styling

By default, I try to make apps responsive.

Preferred: tailwind css - utility first css framework. see also tailwind ui and headless ui The advantage of tailwinds over css is that it avoids css conflicts. The advantage over component libraries is that they all look the same and tailwinds is more customizeable.

For small projects and prototypes, I typically use standard css. I prefer using an atomic css style. I prefer using css grid for layout such as holy grail layout. I prefer flexbox for laying out items in rows or columns. I often use media queries to make responsive styles. I typically avoid css preprocessors such as sass and less. I rarely use float, clear, etc. anymore.

Alternatives:
styled components - CSS-in-JS css framework that uses tagged templates

React component libraries:

In some cases a react component library is the easiest way to go.

Prefered:

antd - Desktop oriented react ui components.

  • Pro: Antd is used by several chinese companies including alibaba, tencent and Baidu.
  • Pro: Antd has a desktop oriented Table component that has scrolling features, based on rc-table
  • Con: I don't like the typography (probably due to Chinese influence and their different character set). There is not as much emphasis on responsive design as other packages.

Alternatives:

State Management

I typically use a state store for non-trivial projects. One reason is to avoid excessive lifting of state and prop drilling. Another reason to use a state store is middleware can simplify some tasks such as logging or undo functinality.
State stores typically have reducers that accept an action and the state and return the new state. Change to the state store is initiated by dispatching an action.
Preferred: mobx - simple, scalable, state management.

Alternatives:

React Router

prefered: react router is a declarative react routing framework. React router supports nested routing.
React router supports a DOM history which enables the browser back button even though it's used in single page applications.

Data fetching

fetch is a web api (natively supported in more recent browsers).
best practice: If supporting older browsers use a polyfill such as isomorphic-fetch or fetch.

TanStack query formerly react query is a popular way to fetch data in react apps.

alternative: axios

Front end unit testing

Jest - (docs) test runner, assertion library, and mocking library.
snapshot testing is a feature that I use.
Jest expects tests to be in a folder named __tests__ or to be named file_name.test.js
react testing library, a ui testing library, replacing enzyme.

#to run tests
npm test

Dom and assertion libraries

  • react testing library is an alternative to enzyme for dom manipulation and traversal. Written by Kent C. Dodds.

End to End Testing

Server Side

Node

node - javascript runtime built on chrome v8 javascript engine. Node is frequently run as an http server.
n - tool to switch versions of node.

Express node library for routing http requests.
Express application generator - tool to generate node express
Guide: Routing Using Middleware Middleware, in the context of express, is code between receiving a request and producing a response.
4.X API
Node contains objects: express, request, response and router.
Commonly used: app.use(), router.route(), req.params, req.body

Alternatives node rest APIs:

  • hapi - node rest api that doesn't use middleware. Express was originally designed for server side rendering, not rest apis.
  • loopback - node rest api framework that uses express.

Alternatives:

  • graphql - is an alternative to rest apis. GraphQL is a specification for a typed query language similar to sql and runtime which incluces a client (eg. relay, apollo) and server. Apollo is a popular graphql implementation. Relay is a popular graphql client.
  • serverless is a framework that can route to serverless cloud functions such as AWS lambda. Serverless cloud functions can be implemented in a variety of languages.

Utilities

For date time libraries I use Luxon.

Databases

There are 2 classes of databases: relational (which typically use SQL) and NoSql which include Wide column stores, document stores, key-value stores, and graph databases.

Best practice for relational databases: database normalization

Naming convention: table or document names are singular.

MS Sql Server

I use MS Sql Server on several projects are suited to relational databases.
tediousjs MS Sql node driver.

Mongo DB

I am using mongo db on some project due to large number of records stored.
Mongo node driver
I am considering using mongoose for an ORM. One advantage is versioning system that helps resolve update conflicts.
Mongo Compass - gui for mongo

Logins and 3rd party service

I typically implment a [jwt login].

Projects may benefit from outsourcing their authentication security because the 3rd party can dedicate more resource to making sure the process is secure. For instance, if a vulnerability is discovered, presumably they would patch it very quickly. There is less code to write and maintain by not storing and protecting sensitive information including user's passwords, and jwt secret key. They also typically handle, change password, forgot password, social logins, and user management functions. The con is dependence on a 3rd party has risks. Their service can go down and you are powerless to resolve the problem perhaps before an important demo. They can go out of business, get bought out, or change their pricing. They can change their api and force you to change your code on their time schedule. They still run the risk of being compromised.

Rest API best practices

When writing a rest API use standard http repsonses.
Return response code 200 for success if server completed request as expected.
Return response code 400 if client sends an invalid request such as missing parameters.
Return response code 401 if client isn't authenticated.
Return response code 403 is client is authenticated but doesn't have permission.
Return response code 404 is client request a route that doesn't exist.
Return response code 500 if there is a server error.
Return response code 503 if a service is unavaialble such as a database.

Error handling

I make a distinction between two types of errors: user errors and system errors. System errors are typically unexpected errors, they need to be logged with the stack trace, and notify a programming manager. They often require code to be modified to handle the errors more gracefully. User error needs to notify the user how to correct the problem or prevented from making it in the first place. Typically, this type of error doesn't require a change to code but if it's gotten consistently it may represent a UX problem.

I typically return system errors as 500 errors to the client, and return user errors as 200 with an error message. http is an application level protocol, so it may also be appropriate to return 500 for user errors. More importantly, is to be consistent on a project so you can distinguish the system errors from user errors.

Error logging and notification

Using a browser error logging service such as sentry helps alert to production problems on the client side.
On the server side, you can search (grep) system logs. There are also many server side error logging and notification services.

splunk
data dog

Transactional email services

Dev Ops

Hosting on a server

This is the old school way to set up an app.
Manage node using pm2
nginx web server to serve front end, and reverse proxy to node.
You can rack your own servers or deploy on virtual instances such as Amazon aws ec2.
Typially use ssh for setup and use crontab for background jobs.

One simple option is to serve the front end through node. This avoids cors setup because everything is served from the same domain. You can also put a catch all route in node to serve the root of the spa.

Pro:

  • Control of the environment. For instance, you can run any version of node you want (an older version for a legacy app or a cutting edge version to take advantage of new features).
  • No proprietary lock in

CDN / application container

service MS Azure Amazon AWS Other
Front end file hosting Azure blob storage, Azure cdn S3, CloudFront vercel, cloudflare
Node hosting Azure App Services elastic beanstalk vercel serverless functions, cloudflare workers
Database hosting Azure Sql RDS mongo db atlas
Continuous deployment Azure Devops Pipelines CodePipeline Jenkins, Circle CI, github actions

Many cdns such as vercel will default sensibly for react apps. For example it will publish when you push to master, redirecting to https and rewriting urls to create deep links. Where as using azure or amazon they will require you to specify each step. Using azure yaml pipelines (part of azure devops) specify each step for continuous deployment (specify the push to master trigger to build deployment, specify the build command etc.). Azure cdn needs to be purged after changes. Deploying a spa will require Azure cdn rules such as redirecting http to https requests and add a URL rewrite to deep links in the single page app.

Serverless functions

Serverless function execute independently. That has pros and cons.
Pros:

  • fine grain, horizontal scalability
  • pay only for what you use which is typically measured in function executions and execution time
  • serverless can be easier for an architect to manage a large team and application.

Cons:

  • Cold Starts - if the service hasn't been used recently there can be a delay starting the service.
  • There are varying levels of support for cross-cutting concerns for serverless functions. For instance, all platfroms have proprietary routing apis. Examples also include functionality typically implemented in middleware such as authentication, cors, error logging etc.
  • There are varying levels of support for maintaining shared state such as database connection pooling. For instance, AWS has RDS proxy which allows serverless apps to do connection pooling.
MS Azure Amazon AWS Vercel
Azure functions Lambda functions Serverless functions
http triggers and binding API Gateway / Lambda authorizers

An early problem for adoption of serverless was running the environment locally for development. Most providers have a local dev environment now. Azure function development is now integrated into VS Code through a plugin.

One solution to vendor lockin is to use another 3rd party.
serverless - cli (serverless) + yaml config file w/ routes (serverless.yml). supports aws, azure, google cloud etc.

Containers

Another deployment option is to create and deploy docker containers. One advantage of docker containers is you can replicate your environment in development, testing, production etc. You also avoid vendor lock-in between cloud providers. Docker is similar to a VM, but more lightweight.
To deploy you build an image using a Dockerfile and push it to a container repository such as Amazon ECR or Docker Hub and then deploy it on a service such as Amazon ECS.

Amazon AWS MS Azure Other
container registry ECR Azure container registry Docker Hub
container service ECS EKS ACI AKS

Kubernetes can be used to scale containers to multiple nodes.

Immutable Infrastructure

Terraform - teraform configuration language enables infrastructure as code. Cloud agnostic (aws/azure/google etc.) Terraform is used for creating an environment on demand rather than for simply deploying web apps.

AWS Cloud Formation - infrastucture as code. Has AWS lock in.

Project management

Agile manifesto

Project management software

Asana
Atlassian Jira
basecamp
pivotal tracker
trello - kanban style list making

About

Guidelines for building modern web apps

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published