diff options
Diffstat (limited to 'guides')
-rw-r--r-- | guides/css.md | 11 | ||||
-rw-r--r-- | guides/git.md | 29 | ||||
-rw-r--r-- | guides/html.md | 14 | ||||
-rw-r--r-- | guides/index.md | 0 | ||||
-rw-r--r-- | guides/javascript.md | 95 | ||||
-rw-r--r-- | guides/scala.md | 81 | ||||
-rw-r--r-- | guides/shell-script.md | 63 |
7 files changed, 293 insertions, 0 deletions
diff --git a/guides/css.md b/guides/css.md new file mode 100644 index 0000000..94555f8 --- /dev/null +++ b/guides/css.md @@ -0,0 +1,11 @@ +## CSS + +- Prefer Flexbox + +- Classes should describe elements and not be generic (`Bigbox` -> `FAQContainer`) + +- Mobile: <= 620px + +- Tablet: 620px - 1024px + +- Desktop: > 1024px diff --git a/guides/git.md b/guides/git.md new file mode 100644 index 0000000..c03e447 --- /dev/null +++ b/guides/git.md @@ -0,0 +1,29 @@ +## Git + +- Use a simple branching model with one master development branch, and + create feature and backport branches as required. + + - The master branch should represent the latest development version. + + - Tag all released versions. + + - Backport branches may be spun off tags when they become necessary. + +- Proposed changes require at least one sign-off to be accepted into + master. + +- Large feature branches with multiple collaborators should be + *merged* into master. + + Rationale: rewriting history in public branches can break other + people's work and should not be done lightly. + +- Private feature branches should be *rebased* onto master, prior to + merging. *Squashing* is optional, but all intermediate commits + should contain meaningful changes and must pass continuous + integration tests. + + Rationale: private branches should be considered backups of work on + local developer machines and hence should not be relied upon by + others. Furthermore, a linear history is easier to reason about than + a branched one. diff --git a/guides/html.md b/guides/html.md new file mode 100644 index 0000000..e0581ef --- /dev/null +++ b/guides/html.md @@ -0,0 +1,14 @@ +## HTML + +- Use svg's over all other image formats when possible. + +- All `<img>` tags should have `“alt”` text. + +- Only use tables for tabular data (not for layout) + +- Make use of html5 elements like `<header>`, `<footer>`, `<nav>`, `<section>`, etc. + +### Browsers + +- Avoid supporting versions of Internet Explorer before IE11. + diff --git a/guides/index.md b/guides/index.md new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/guides/index.md diff --git a/guides/javascript.md b/guides/javascript.md new file mode 100644 index 0000000..bb363ac --- /dev/null +++ b/guides/javascript.md @@ -0,0 +1,95 @@ +## JavaScript + +- Type with flow + +- Style with [prettier](https://prettier.io/) ([see section below](#prettier)) + +- Lint with eslint and use `eslint:recommended` at a minimum + +- Test with [jest](https://facebook.github.io/jest/) and enzyme + + +- 2 spaces (instead of tabs) + +- Promises (not callbacks) + +- No [decorators](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841) + +- No [mobx](https://mobx.js.org/) + +- Place tests alongside the file(s) it tests (not in a separate directory) + +- End test files with `.test.js` + +### React/Redux + +- Lint with [`tslint-react`](https://github.com/palantir/tslint-react) or eslint's [`plugin:react/recommended`](https://github.com/yannickcr/eslint-plugin-react) at a minimum. + +- No unnecessary and empty `<div>`’s + +- If `this.props.<variable name>` is used more than once, dereference it at the top of `render`. + +- Extract variables used in `render()` to the top of `render()` + +- API calls should lie in a testable file outside of components. + + +- Components should not wait for promises to resolve, instead listen on props via redux’ `mapStateToProps()`. + +- Declare and export components in separate places (otherwise the web inspector cannot name components properly) + +### Flowtype + +- Any types used in more than one file should be placed in `src/types.js` + +- Add flow linting via [eslint-plugin-flowtype](https://github.com/gajus/eslint-plugin-flowtype) + +- Disallow "`any`" with [eslint no-weak-types](https://github.com/gajus/eslint-plugin-flowtype#no-weak-types) (use "`Obect`" and "`Function`" to cover complicated use-cases) + + +- In components which use `mapStateToProps`, separate `OwnProps` from `ConnectedProps` into separate types. Join them with `type Props = OwnProps & ConnectedProps`. In addition, if using `mapDispatchToProps`, create a type `DispatchProps` and join that with `Props`. + +### 𝓣𝓢 TypeScript 𝓣𝓢 + +- Lint with [`tslint:recommended`](https://github.com/palantir/tslint) at a minimum. + +- No implicit any (type everything that’s not inferable) + +- Any variable declared without an initial value should be typed + +### Prettier + +Add the following to `package.json`: + +```json + "prettier": { + "overrides": [ + { + "files": ["*.js", "*.scss", "*.css", "*.pcss"], + "options": { + "singleQuote": true, + "trailingComma": "all" + } + } + ] + } +``` + +The following information about prettier is better described on the prettier documentation [here](https://prettier.io/docs/en/precommit.html#option-1-lint-staged-https-githubcom-okonet-lint-staged). +Use `lint-staged` to auto-call prettier in a `precommit` "`script`": + +```json + "lint-staged": { + "src/**/*.scss": ["prettier --parser scss --write", "git add"], + "src/**/*.{js,css}": ["prettier --parser flow --write", "git add"], + "nightwatch/**/*.js": ["prettier --write", "git add"] + } +``` + +### Npm + +* Support the following `script`'s in your root `package.json`: + +1. `“watch”`: Starts the dev server +2. `“build”`: Builds static assets (if they exist) "`/src`" -> "`/build`" +3. `“test”`: Runs all tests (linting first, then unit tests) diff --git a/guides/scala.md b/guides/scala.md new file mode 100644 index 0000000..a2009e7 --- /dev/null +++ b/guides/scala.md @@ -0,0 +1,81 @@ +## Scala + +- First and foremost, follow [the Principle of Least + Power](http://www.lihaoyi.com/post/StrategicScalaStylePrincipleofLeastPower.html#philosophy-principle-of-least-power). + + In a nutshell: + + - Keep your code simple and at a level of abstraction dictated by + the actual circumstances. + + + - Don't design an API that will fit all future requirements. Start + simple and refactor when the time comes. A good rule of thumb is + to assume that you will completely rewrite your code at least once + before finding a satisfactory solution. + + Rationale: the article justifies its points thoroughly. In general, + Scala makes it easy to design advanced abstractions which can make + it harder for an outsider to grasp a codebase. As a codebase grows, + sometimes these abstractions become necessary, however they usually + aren't in the beginning. Since Scala is a statically typed language, + you should not fear refactoring when they do become necessary. + + *Scala's name comes from "scalable language". That refers to large, + as well as small!* + +- Avoid building libraries in such a way that they require wildcard + imports to function. + + I.e. avoid building libraries that use this common pattern: `import + foo.bar._` + + Rationale: a developer using a library doesn't want to know how it + works, but wants to get his or her job done. Wildcard imports + (especially if they bring into scope implicits) obfuscate the origin + of types and methods to a reader who is not familiar with the + library, and hence make it harder for the reader to edit. + +- Choose dependencies on external libraries judiciously, and keep them + to a minimum. Avoid depending on multiple libraries that offer + similar functionality. + + Prefer reimplementing *small* features in your own code rather than + relying on a library. + + For example, assume a web service has a REST API and also offers a + Java library that wraps said API. In the case where only a couple of + endpoints from the external REST service are required in some code, + prefer calling the endpoints with an HTTP client directly, rather + than relying on the entire library. This allows you to forego an + additional layer of indirection and keeps you in control of which + HTTP client to use. + +- In public interfaces, expose only types from the Scala standard + library. In particular, avoid exposing scalaz or cats types. + +- Make use of comments liberally. Describe interesting parts of code, + how to use it and why it's there. Don't comment *everything*. + +- Organise code in a functionally cohesive manner. Use one parent + package to namespace a library, and use nested packages according to + functionality. + +- Do not use runtime reflection. + + Rationale: runtime reflection circumvents type checking and strongly + ties applications to the JVM. + +- Use + [scalafmt](https://scalameta.org/scalafmt/docs/introduction.html) to + format code. + + Rationale: formatting is material for holy wars. If it is enforced + by an automatic tool then there is no room for such discussions. + +## Other Resources + +[Simple Made +Easy](https://www.infoq.com/presentations/Simple-Made-Easy), by Rich +Hickey. A great talk about the differences between "Simple", +"Complex", "Easy" and "Hard", and how to write simple programs. diff --git a/guides/shell-script.md b/guides/shell-script.md new file mode 100644 index 0000000..a5770ae --- /dev/null +++ b/guides/shell-script.md @@ -0,0 +1,63 @@ +## Shell Script + +- Run the [ShellCheck](https://github.com/koalaman/shellcheck) linter + on all scripts. + +- Follow Google's [Shell Style + Guide](https://google.github.io/styleguide/shell.xml); most notably, + the below points. + +- Use only Bourne Again SHell (Bash). + + It's acceptable to use features available only in Bash 4 and + later. As of this writing, that version was released almost 10 years + ago, and developers on any platforms which do not ship the latest + version out-of-the box are expected to upgrade. + +- Prefer no file name extension for executables, and ".sh" extensions + for libraries (scripts that are meant to be "sourced" in other + scripts). + + Rationale: an OS can run any executable file, regardless of its + content, and as such, it isn't helpful to know that an executable is + in fact a shell script. However, it is essential to know that an + included library is indeed a shell script. + +- Use long names for command-line options rather than short + ones. E.g. use `ls --all` instead of `ls -a`. + + Rationale: long names trade off clarity at the expense of + brevity. They make it easier for an unfamiliar reader to grasp the + meaning of an argument, but require the author to write more + characters. Hence they are recommended in all places that are read + more often than written. + +- Use lower_snake_case for all local environment variables, and + UPPER_SNAKE_CASE for exported variables. + +- Prefer parsing command line options rather than relying on + environment variables for configuration. + +- Print status messages to stderr, not stdout. + + Rationale: stdout is often parsed by other utilities (for example in + a pipeline) and should hence only contain a program's output, if + any. + +- Don't make any assumptions about the working directory from which a + script is invoked. Specifically, don't require that the script be + invoked within the same directory it is located. + + Rationale: scripts should be treated like any other executable and + should support indirection via symlinks. Requiring a specific + working directory for a program to function is a needless + restriction. + + Note that this guide specifically applies to the *working directory* + of the caller. The script itself may make assumptions about *its + location* and the location of resources. The following snippet is an + example mechanism to determine the directory of a script. + ```bash + # Base directory that this script is located at. + dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" + ``` |