Best practices and code standards in the Mobile code
License
This boilerplate is to be used on every file written by Totara Learning Solutions.
/**  * This file is part of Totara Enterprise.  *  * Copyright (C) {{year}} onwards Totara Learning Solutions LTD  *  * Totara Enterprise is provided only to Totara Learning Solutions  * LTD’s customers and partners, pursuant to the terms and  * conditions of a separate agreement with Totara Learning  * Solutions LTD or its affiliate.  *  * If you do not have an agreement with Totara Learning Solutions  * LTD, you may not access, use, modify, or distribute this software.  * Please contact [sales@totaralearning.com] for more information.  */
Code style and best practices
We will be adapting the default Javascript and Typescript code style of the Jetbrains with some adjustments:
- Changing the spacing of tab size, indents, and continuation indents from 4 to 2 - most current style guides now use 2 spaces, mainly because there are more closures and lambdas now (e.g. https://github.com/airbnb/javascript#whitespace)
- Add spaces within "Object literals braces" and "ES6 import/export braces", consistent with most 3rd party code as well as VS Code's default
- Organise imports in the following order; 3rd party import, @totara/package, and relative path import
- Export modules at the bottom of the file when practical
- Use as much of ES6 features as possible, especially deconstruction for function params and react props
We will be adopting some of MS Typescript guidelines (https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines), specifically; Names, Components, Types, null and undefined, and General Assumptions.
Name conventions
In general, for Javascript/Typescript:
- Variable names: Camel case
- Function/methods names: Camel case
- Module/packages names: Camel case
- React components: Pascal caseÂ
- Typescript interfaces and types: Pascal case
- Index file name: Camel case
For Assets(images/icons):
- general file name: Snake case
- json file names: Snake case
Directory structure and file names in general:
- Folders: Camel case
- Filename (not from react components): Camel case (includes utilities and theme files)
- For folders and non react components: Camel case
Just a reminder, please ensure that React components are pascal case.
Case | Description | Example |
---|---|---|
Camel case | The first letter is lower case, there are no spaces between words and instead, new words are indicated through the use of capitals. | camelCase |
Pascal case | There are no spaces between words and the first letter of each word is capitalised. | PascalCase |
Snake case | All words are written in lower case and underscores are used to replace spaces | snake_case |
JavaScript (TypeScript) and Node
JavaScript should be readable, modular, and splittable. Take advantage of functional programming and if you find business logic that can be shared, generally put inside a utility file.
Project structure (for JS/Typescript/React Native)
We accept directories named with widgets group, for instance, buttons.ts
should be added to components
 folder, whenever possible.
We discourage name files "_feature_.component.js" or "_feature_.container.js".
Formatting
We delegate that to [Prettier](https://prettier.io/).
Make sure your text editor has [that extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode), and that it's configured to auto-format on save.
Here is the exact settings.json file that we use and we strongly suggest you use it in setup for VSCode or some equivalent settings for your favourite IDE:
{  "editor.tabSize": 2,  "editor.formatOnSave": false,  "[typescriptreact]": {    "editor.defaultFormatter": "esbenp.prettier-vscode",    "editor.formatOnSave": true  },  "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode"    "editor.formatOnSave": true  },  "[javascriptreact]": {    "editor.formatOnSave": true  },  "[javascript]": {    "editor.defaultFormatter": "esbenp.prettier-vscode",    "editor.formatOnSave": true  } }
Pro hints
React components
Each component should have its own file preferably. Try to avoid lots of components in the same file. For instance:
//Button.tsx const Button () => ( Â <View><Icon name={iconName}/></View> ) //This icon should be extracted so you promote reusability const Icon = () => (<View />); //nice default export //we dont normally export two components export default Button;
Undefined and null check
Javascript already has the `undefined` type to indicate the absence of value, so there is no need to have a second type that represents the same concept. Said that, avoid the use of null. Yet sometimes the server returns it, therefore you still have to check.
//if the parameter is not a number, then this should be good if ( param ) then ... //if the parameter is a number, then we need to do this if ( param !== null && param !== undefined ) then ...
Function parameters
Multiple arguments vs. options object:
// bad function example(nodeList, callback, thisObject, fromIndex, toIndex){ Â //... } // good. That is better because it more readable when you call the function function example({ nodeList, callback, thisObject, fromIndex, toIndex }){ Â //... }
Modules
Use a single component export default per file.
Troubleshooting
When switching branches and suspecting that there were native code changes(e.g: dependencies additions or upgrades), this sequence should help you:
- Kill RN packager server (the little window that opens when you run the app).
- Run clean script (
npm run clear:all
).
This will clean all the builds and caches on both Android and iOS, and reinstall all the dependencies. Then run your platform script again.
Other useful commands
Device listing
- Both platforms:
yarn devices:ios   Â
- For iOS only:
yarn devices:iosÂ
orÂxcrun xctrace list devices
- For Android only:
yarn devices:android
 orÂadb devices