Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recoil, PostHog, Sentry Integrations #101

Merged
merged 45 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
0379ff4
feat: cd-dev-ios, - cd-prod-ios added
neerajk9141 Apr 12, 2023
bdbabde
feat: CD setup with EAS
neerajk9141 Apr 26, 2023
87467a5
fix: fix complexity in eslint
rohankeskarwednesday Aug 21, 2024
c9bd7c9
fix: fix complexity
rohankeskarwednesday Aug 21, 2024
2855013
feat: add env support
rohankeskarwednesday Aug 21, 2024
985bee2
fix: dependencies issues and webpack config for web app to compile
Aug 21, 2024
ae0df53
feat: adding the dependencies for expo-crypto and recoil
Aug 22, 2024
7e69942
feat: adding the dependencies for expo-crypto and recoil
Aug 22, 2024
6dfd2bf
feat: adding the dependencies for react-i18next and i18next
Aug 22, 2024
ca2ba1d
feat: merge master to develop
Aug 23, 2024
7cd4e35
feat: test cases updation
Aug 23, 2024
e451c07
feat: add sentry
rohankeskarwednesday Aug 26, 2024
ec00ffb
feat: sentry integration
rohankeskarwednesday Aug 26, 2024
4ec5e95
WIP
Aug 26, 2024
2e90e48
Language Provider and redux store
Aug 26, 2024
a48c212
pr comments
Aug 27, 2024
8c11040
pr comments
Aug 27, 2024
fd68baf
Merge pull request #95 from wednesday-solutions/feat/eslint-and-growt…
shamoilattaar-wednesday Aug 27, 2024
58c890c
merge develop
Aug 27, 2024
4b79b67
eslintignore updates
Aug 27, 2024
5e0bae0
pr comments
Aug 28, 2024
9c4aa4d
Merge pull request #96 from wednesday-solutions/feat/i18next-languarg…
shamoilattaar-wednesday Aug 28, 2024
ec198a5
recoil Integration and redux removal
Aug 28, 2024
0dad05b
feat: recoil support and implementation
Sep 2, 2024
2262b33
feat: apisauce removal and testcase updations
Sep 3, 2024
24a9601
feat: test case updations
Sep 3, 2024
543f599
chore: removal of redundant redux files
Sep 3, 2024
3fa1c6c
fix: lint issues fixes
Sep 3, 2024
5d92faa
fix: eslint issues and updated wednesday logo
Sep 4, 2024
e776e91
feat: CI changes
Sep 4, 2024
d0f982c
feat: pr comments
Sep 4, 2024
a11c80d
feat: pr comments
Sep 4, 2024
08e4909
feat: pr comments
Sep 4, 2024
1db1f57
feat: pr comments
Sep 4, 2024
65113a4
feat: pr comments
Sep 4, 2024
a49059b
feat: CI changes
Sep 4, 2024
732b82a
feat: test updates
Sep 4, 2024
05d2991
Merge pull request #99 from wednesday-solutions/feat/recoil-integrations
shamoilattaar-wednesday Sep 5, 2024
e9f2eee
feat: posthog integration
Sep 5, 2024
83de9eb
feat: pr comments
Sep 9, 2024
0176663
Merge pull request #100 from wednesday-solutions/feat/posthog-integra…
shamoilattaar-wednesday Sep 9, 2024
d0b5cac
feat: env generalisation and readme updates
Sep 10, 2024
bb4b3c6
feat:readme updates
Sep 10, 2024
f764418
feat: pr comments
Sep 10, 2024
ca5affe
feat: CI Changes
Sep 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
JSON_PLACEHOLDER_API="https://jsonplaceholder.typicode.com"
SIMPSONS_API="https://thesimpsonsquoteapi.glitch.me/"
SENTRY_DSN= "YOU_SENTRY_DSN"
POSTHOG_KEY= 'YOUR_POSTHOG_PROJECT_KEY'
shamoilattaar-wednesday marked this conversation as resolved.
Show resolved Hide resolved
12 changes: 11 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,14 @@ android/**
ios/**
__tests__/**
**/tests/***
.eslintrc.js
web-build/**
.eslintrc.js
e2e/**/*.*
metrics/*
jest.setup.js
babel.config.js
reports
report.json
growthbook.js
**/tests/*.test.js
webpack.config.js
21 changes: 9 additions & 12 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
const fs = require('fs');
const path = require('path');


const prettierOptions = JSON.parse(
fs.readFileSync(path.resolve(__dirname, '.prettierrc'), 'utf8'),
fs.readFileSync(path.resolve(__dirname, '.prettierrc'), 'utf8')
);
module.exports = {
root: true,
parser: 'babel-eslint',
extends: [
'airbnb',
'prettier',
'prettier',
'prettier/react',
'plugin:prettier/recommended',
'plugin:sonarjs/recommended',
Expand All @@ -22,7 +21,6 @@ module.exports = {
'immutable',
'sonarjs',
'prettier',
'redux-saga',
'react-native',
'react',
'react-hooks',
Expand Down Expand Up @@ -54,13 +52,13 @@ module.exports = {
'import/no-unresolved': 0,
'import/prefer-default-export': 0,
'react/jsx-props-no-spreading': 0,
'camelcase': ['error', { 'properties': 'always', ignoreImports: false}],
camelcase: ['error', { properties: 'always', ignoreImports: false }],
indent: [
2,
2,
{
SwitchCase: 1,
},
SwitchCase: 1
}
],
'jsx-a11y/aria-props': 2,
'jsx-a11y/heading-has-content': 0,
Expand Down Expand Up @@ -96,8 +94,6 @@ module.exports = {
'react/require-extension': 0,
'react/self-closing-comp': 0,
'react/sort-comp': 0,
'redux-saga/no-yield-in-race': 2,
'redux-saga/yield-effects': 2,
'require-yield': 0,
'react/no-array-index-key': 0,
'react/jsx-curly-newline': 0,
Expand All @@ -120,7 +116,7 @@ module.exports = {
}
],
'no-shadow': 'error',
complexity: ['error', 10],
complexity: ['error', 4],
'no-empty': 'error',
'import/order': [
'error',
Expand All @@ -146,7 +142,8 @@ module.exports = {
}
],
'fp/no-nil': 0,
'fp/no-unused-expression': 0
'fp/no-unused-expression': 0,
'fp/no-throw': 0
},
settings: {
'import/resolver': {
Expand All @@ -171,4 +168,4 @@ module.exports = {
}
}
}
};
};
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: react-native-template
on:
push:
branches: [ master ]
branches: [master, dev]
pull_request:
branches: [ master ]
branches: [master, dev]
jobs:
install-and-test:
runs-on: ubuntu-latest
Expand All @@ -13,7 +13,7 @@ jobs:
run: yarn

- name: Lint
run: npm run lint
run: yarn lint

- name: Test and generate coverage report
uses: artiomtr/[email protected]
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/cd-dev-ios.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Deploy to Expo
on:
push:
branches:
- dev
jobs:
expo-build:
runs-on: ubuntu-latest
environment: development
steps:
- name: 🏗 Setup repo
uses: actions/checkout@v3

- name: 🏗 Setup Node
uses: actions/setup-node@v3
with:
node-version: 18.x
cache: yarn

- name: 🏗 Setup EAS
uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}

- name: 📦 Install dependencies
run: yarn install

- name: 🚀 Build app
run: eas build --platform ios --profile development --non-interactive
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ buck-out/
web-build/
dist/
reports
coverage
coverage
.env.local
6 changes: 6 additions & 0 deletions App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

import { registerRootComponent } from 'expo';
import App from '@app/app';
import { SENTRY_DSN } from '@env';
import * as Sentry from '@sentry/react-native';

Sentry.init({
dsn: SENTRY_DSN
});

if (!window.Intl) {
new Promise(resolve => {
Expand Down
92 changes: 48 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@
</p>

<p>
An enterprise React Native template application showcasing - Testing strategies, Global state management, middleware support, a network layer, component library integration, localization, navigation configuration, and Continuous integration.
An enterprise React Native template application showcasing - Testing strategies, Global state management, middleware support, a network layer, component library integration, localization, navigation configuration, Continuous integration, analytics, feature flagging, and error tracking.
</p>

___

---

<p>
<h4>
Expand All @@ -31,9 +30,10 @@ An enterprise React Native template application showcasing - Testing strategies,
</a>
</div>

___
---

<span>We’re always looking for people who value their work, so come and join us. <a href="https://www.wednesday.is/hiring">We are hiring!</a></span>

<span>We’re always looking for people who value their work, so come and join us. <a href="https://www.wednesday.is/hiring">We are hiring!</a></span>
</div>

## Architecture
Expand All @@ -42,51 +42,58 @@ The driving goal of the architecture of the template is separation of concerns.

- **Presentational components are separated from scenes** (aka "screens").

Presentational components are small components that are concerned with *how things look*. Scenes usually define whole application screens and are concerned with *how things work*: they include presentational components and wire everything together.
If you are interested you can [read more about it here](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0).
Presentational components are small components that are concerned with _how things look_. Scenes usually define whole application screens and are concerned with _how things work_: they include presentational components and wire everything together.

If you are interested you can [read more about it here](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0).

### Atomic Design for react native architecture
Atomic design further solidifies the idea of seperating screens into components and scenes (containers). The design primarily focuses on reusablity of code, which brings us to the differentiation of components into atoms, molecules and organisms. Analogous to the Atomic design of chemicals, components are seperated by their composition. The components require increasing context as their complexity increases, since each component is tested, this promotes a more granular test coverage.

- **Atoms**
Atoms are the smallest components that can be reused. Button, Text, and Icons are good example of Atoms. Atoms can be used without context and cannot be further divided.

- **Molecules**
Molecules are built from one or more atoms that are slightly complex presentational components.
Atomic design further solidifies the idea of separating screens into components and scenes (containers). The design primarily focuses on reusability of code, which brings us to the differentiation of components into atoms, molecules, and organisms. Analogous to the Atomic design of chemicals, components are separated by their composition. The components require increasing context as their complexity increases, since each component is tested, this promotes a more granular test coverage.

- **Atoms**
Atoms are the smallest components that can be reused. Button, Text, and Icons are good examples of Atoms. Atoms can be used without context and cannot be further divided.

- **Molecules**
Molecules are built from one or more atoms that are slightly complex presentational components.

- **Organisms**
Organisms contain multiple molecules, atoms, and perform a specific purpose. In the example screen, an organism is used that displays the fetched character and quote.

- **State is managed using [Recoil](https://recoiljs.org/)**.

Recoil provides a set of utilities to manage global state in React Native. It allows for atoms (the smallest units of state) and selectors (to transform or combine state) to handle the app's state efficiently. This eliminates the need for Redux, actions, and reducers, simplifying the process for managing state across components.

- **Organisms**
Organisms contain multiple molecules, atoms and perform a specific purpose. In the example screen, an organism is used that displays the fetched character and quote.
Atoms are the core units of state, and selectors are derived state values computed from one or more atoms. Recoil's state management is highly reactive and more efficient for handling state at a granular level.

- **State is managed using global [Redux](https://redux.js.org/) stores**.
If you are interested you can [read more about it here](https://recoiljs.org/docs/introduction/getting-started).

When applications grow, sharing state and its changes can become very hard. Questions like "How can I access this data?" or "When did this change?" are common, just like passing data around components just to be able to use it in nested components.

With Redux, state is shared using global *stores*, and changes are predictable: *actions* are applied by *reducers* to the state. While the pattern can be a bit much for small projects, the clear separation of responsibilities and predictability helps with bigger applications.

If you are interested you can [read more about it here](https://redux.js.org/introduction/motivation).

- **Application side-effects (API calls, etc.) are separated from UI and state manipulation using [Redux Saga](https://redux-saga.js.org/)**.
- **Side Effects (API calls, etc.) are managed within components or with Recoil selectors**.

Using Redux Saga has two benefits: keeping application side-effects and related business logic out of UI components, as well as executing that logic in an asynchronous way without ending in callback hell.

Sagas are triggered by Redux actions and can also trigger Redux actions to alter state. By using JavaScript generators (`yield`), sagas are written in a synchronous-like manner while still executing asynchronously.
Recoil allows for managing side effects within the components themselves or through asynchronous selectors. This keeps your side effects closer to where they are needed.

## Analytics, Feature Flagging, and Error Tracking

- **[PostHog](https://posthog.com/)** is integrated to provide analytics and event tracking across the application. PostHog captures user interactions and events, which helps in analyzing user behavior and improving the app based on data-driven insights.

- **[GrowthBook](https://www.growthbook.io/)** is used for feature flagging. With GrowthBook, you can easily manage the rollout of features to users, enabling A/B testing, and controlling which features are visible to which segments of your user base without redeploying the app.

- **[Sentry](https://sentry.io/)** is used for error tracking and reporting. Sentry captures errors and exceptions from the app in real time, providing detailed insights into the errors that occur, enabling faster bug fixing and better app stability.

## Content

The React Native Template contains:

- a [React Native](https://facebook.github.io/react-native/) (v**0.60.6**) application (in "[ejected](https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md)" mode to allow using dependencies that rely on native code)
- a [React Native](https://facebook.github.io/react-native/) (v**0.73.6**) application (in "[ejected](https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md)" mode to allow using dependencies that rely on native code)
- a [clear directory layout](#directory-layout) to provide a base architecture for your application
- [Redux](https://redux.js.org/) (v4.0.1) to help manage state
- [Redux Persist](https://github.com/rt2zz/redux-persist) (v5.10.0) to persist the Redux state
- [Redux Sagas](https://redux-saga.js.org) (v1.0.2) to separate side-effects and logic from state and UI logic
- [React Navigation](https://reactnavigation.org/) (v3.11.2) with a [`NavigationService`](app/services/navigationService.js) to handle routing and navigation in the app, with a splash screen setup by default
- [reduxsauce](https://github.com/infinitered/reduxsauce) (v1.0.1) to facilitate using Redux
- [apisauce](https://github.com/infinitered/apisauce/) to make API calls (v0.19.0)
- [Recoil](https://recoiljs.org/) to manage global state
- [React Navigation](https://reactnavigation.org/) (v5.3.15) with a [`NavigationService`](app/services/navigationService.js) to handle routing and navigation in the app, with a splash screen setup by default
- [axios](https://github.com/axios/axios/) to make API calls (v0.27.2)
- [PostHog](https://posthog.com/) for analytics
- [GrowthBook](https://www.growthbook.io/) for feature flagging
- [Sentry](https://sentry.io/) for error tracking
- [prettier](https://prettier.io/) and [eslint](https://eslint.org/) preconfigured for React Native

The template includes an example (displaying fake user data) from UI components to the saga. The example is easy to remove so that it doesn't get in the way.
The template includes an example (displaying fake user data) from UI components to state management using Recoil. The example is easy to remove so that it doesn't get in the way.

## Directory layout

Expand All @@ -97,12 +104,10 @@ The template includes an example (displaying fake user data) from UI components
- [`app/scenes`](app/components/scenes): scenes are screens that can be navigated to
- [`app/config`](app/config): configuration of the application
- [`app/assets`](app/assets): assets (image, audio files, ...) used by the application
- [`app/navigators`](app/navigators): react navigation navigators
- [`app/navigators`](app/navigators): react navigation navigators
- [`app/services`](app/services): application services, e.g. API clients
- [`app/utils`](app/utils): Util methods and constants
- [`app/themes`](app/themes): base styles for the application
- [`app/rootSaga`](app/rootSaga): all the individual sagas need to be added here.
- [`app/rootReducer`](app/rootReducer): all the individual reducers need to be added here.

For more information on each directory, click the link and read the directory's README.

Expand All @@ -115,7 +120,6 @@ You also need to install the dependencies required by React Native:
- for [Android development](https://facebook.github.io/react-native/docs/getting-started.html#installing-dependencies-3)
- for [iOS development](https://facebook.github.io/react-native/docs/getting-started.html#installing-dependencies)


## Using the template

To create a new project using the template:
Expand All @@ -126,16 +130,16 @@ To create a new project using the template:
- rename the React Native project to your own project name: `yarn run rename -- <YourProjectName>` (the default name is `ReactNativeApplication`)
- remove the LICENSE file and the "License" section from the README if your project is not open source


### Running expo project

### Android
- `yarn run android`

- `yarn run android`

### iOS

- `yarn run ios`


## Useful documentation

### Deployment
Expand All @@ -145,5 +149,5 @@ To create a new project using the template:

### Package dependencies

- You may want to use [CocoaPods](https://cocoapods.org/) to manage your dependencies (iOS only)
- You may want to use [CocoaPods](https://cocoapods.org/) to manage your dependencies (iOS only)
- [Using CocoaPods to manage your package dependencies](docs/setup%20cocoapods.md)
3 changes: 2 additions & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def enableProguardInReleaseBuilds = (findProperty('android.enableProguardInRelea
*/
def jscFlavor = 'org.webkit:android-jsc:+'

apply from: new File(["node", "--print", "require.resolve('@sentry/react-native/package.json')"].execute().text.trim(), "../sentry.gradle")
android {
ndkVersion rootProject.ext.ndkVersion

Expand Down Expand Up @@ -173,4 +174,4 @@ dependencies {
}

apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
applyNativeModulesAppBuildGradle(project)
applyNativeModulesAppBuildGradle(project)
7 changes: 7 additions & 0 deletions android/sentry.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

auth.token=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

defaults.org=wednesday-solutions-5p
defaults.project=react-native

defaults.url=https://sentry.io/
14 changes: 12 additions & 2 deletions app.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"expo": {
"name": "react-native-template-ws",
"slug": "rnt-ws",
"slug": "react-native-template-cd",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
Expand All @@ -22,6 +22,16 @@
},
"ios": {
"bundleIdentifier": "com.wednesdaysolutions.rntws"
}
},
"plugins": [
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"project": "react-native",
"organization": "wednesday-solutions-5p"
}
]
]
}
}
Loading
Loading