Patch.com
Get Started
Requirements
Generate a GitHub access token
Why do we need a GitHub access token? We have a lot of internal packages which are setup in github package registry. This token allows access for all those packages.
- Get a personal access token with a
read:packages
permission to access@patch-engineering
packages. - Export it to
.bashrc
/.bash_profile
/.zshrc
/.zsh_profile
etc asGITHUB_SECRET_TOKEN
export GITHUB_SECRET_TOKEN="<your token here>"
- Run
source <your file name>
. Replace<your file name>
with.bashrc
/.bash_profile
/.zshrc
/.zsh_profile
etc -
Important note about
nvm
: If you usenvm
to manage Node.js installations (as you should), add this access token before the .nvm shell is loaded in your bashrc/bash_profile. Look at this SO answer for more information.
nvm
, Node & npm
- Install nvm.
- Run
nvm use
at the root of the repo — it should install the right version of Node.js. - Install the correct version of
npm
—
npm install npm@8.1.2 -g
- Finally, run
npm install
to install all the dependencies.
caddy
https setup & Why do we need caddy? Some features in patch.com need https — this service reverse proxies the Next.js server through a local domain that has a valid cert.
- Install
caddy
using homebrew. - Update your
hosts
file.
printf "\n127.0.0.1 patch.local\n" | sudo tee -a /etc/hosts
- Once done, run
npm run proxy
from the root of the repo and follow instructions. This is only for the first time. -
For Firefox 🦊 users — you may have to go to the
about:config
page and switchsecurity.enterprise_roots.enabled
totrue
- https://support.mozilla.org/en-US/questions/1175296
Run local dev server
- Run
npm run dev
. This command starts up the application and the caddy reverse proxy. There is no need to runnpm run proxy
separately! - Visit
https://patch.local
.
Environment Variables
- By default environment variables are setup to point to the QA environment in the
.env.development
file. - To override any of these variables, create an
.env.local
file in the root of this project and add the overrides there.- You can adjust any values in your
.env.local
file such as pointing yourPATCH_FE_API_URL
to your local patch.com rather than the qa environment
- You can adjust any values in your
Creating new environment variables
- If you're adding any new env variable make sure to add it to
.env-development
and.env.test
. If the key is not sensitive you can please include a default value pointing to QA.- Once you've added the environment variable, make sure to add it under the appropriate section of the
publicRuntimeConfig
object innext.config.js
.- We also need to update our
next/config
mock intest/config.ts
for the config to be found when running tests. - We use
publicRuntimeConfig
config and not plainprocess.env.NEXT_PUBLIC_MY_VAR
because environment variables are added to the code at build time, and we don't build when going fromstaging
toprod
, to get around this we usepublicRuntimeConfig
as they run at runtime.
- We also need to update our
- Make sure to type whatever environment variable you add to the appropriate section in
_context/ConfigContext.ts
- Add the variables to the patch.com heroku config located in the settings tab for patch-com-qa (qa), patch-com-staging (test), and patch-com prod (prod). prepod env vars are autotomatically copied from prod.
- Once you've added the environment variable, make sure to add it under the appropriate section of the
Linting
Before pushing up code it's a good idea to check for any lint errors. You can run:
npm run lint
Compiling
Compile and Minify Project
To make sure project will compile correctly you can run:
npm run build
Run Production Build
You can test out your app as if it was in production by running:
npm run prod
Analyze Project Dependencies
For analyzing browser and or server code bundles you can run:
npm run analyze
# Browser only
npm run analyze:browser
# Server only
npm run analyze:server
Releasing
QA
When a merge is done to the qa
branch of this repository, a build is triggered to release this app to our heroku instance, patch-com-qa. Thus we use https://celeste.patch.com as our QA environment.
Staging
When a merge is done to the master
branch of this repository, a build is triggered to release this app to our heroku instance, patch-com-staging. Thus we use https://test.patch.com as our staging environment.
Production
To release code to production, we must use the heroku pipeline to promote the changes in patch-com-preprod
to patch-com-prod
in patch-com
.
Important note about environment variables
getServeSideProps
or getIntialProps
to ensure SSR.
For static pages to use production config, you must set the config in the patch-com-prod instance before the build in patch-com-preprod happens, so the environment is copied over and is available when promoting preprod to prod.
Project Structure
Current structural issues
It’s hard to find my way around the patch.com codebase due to related and dependent functionality being spread throughout the codebase. Working on a specific feature could result in us adding a new file in 2-4 different directories.
It’s also confusing to see which team owns what given that everything is mixed together. There are also several directories that seem duplicative and creates confusion when adding writing code, what’s lib? should _hooks be utils? can utils go inside _hooks?.
How we're structuring
Going forward, we are reorganizing the repo by having features and their components, hooks, types, helper methods, tests, etc in the same directory.
Say we have feature called myFeature, we can find a myFeature directory inside a src with the following structure:
- 📂myFeature
- 📂 components- Holds any component for the feature
- 📄 Button.tsx - This file component means we don’t have any styles
- 📂 Title - if component has styles we can make Title a folder
- 📄 index.tsx
- 📄 styles.module.scss
- 📂 lib - holds business logic! Any apis, codecs, constants, helper methods, hooks, types, would go here. These are always good contenders to port over to patch-common
- 📄 api.ts - any api methods go here
- 📄 types.ts - any types go here
- 📂 pages - Holds pages for the feature, they get imported in the root feature pages file
- 📄 MyFeaturePage.tsx
- 📂 OtherFeaturePage
- 📂
__snapshots__
- 📄 index.test.tsx.snap
- 📄 index.tsx
- 📄 index.test.tsx
- 📄 styles.module.scss
- 📂
- 📂 components- Holds any component for the feature
All features should exist under a new src directory. There will also be a common feature directory with similar structure for common things that are reused throughout the repo like the <Link />
or <Image />
component.
The pages directory will remain in the root for now, but we should be adding the actual page component (and the getServerProps if needed) in the src/feature/pages directory.
The root directories: _contants, _hooks, _types, features, libs, services, styles, and utils will be considered deprecated and we shouldn’t be adding more files to any of them. Our goal will be to port them to this new model when we next have to interact with that code. This will be a long process but we’ll get there.
Ideal Project Structure
Our repo should end up looking like this (plus any root config file like next.config or eslint etc..):
- 📂.circleci
- 📂pages
- 📂public
- 📂server
- 📂src
- 📂_common
- 📂tests
- 📂components
- 📄Link.tsx
- 📄Image.tsx
- 📂lib
- 📄api.ts
- 📄types.ts
- 📂article
- 📂components
- 📄ArticleCard.tsx
- 📄ArticleCardDetail.tsx
- 📂lib
- 📄api.ts
- 📄types.ts
- 📂pages
- 📄ArticleTopicPage.tsx
- 📂ArticleDetailPage
- 📂
__snapshots__
- 📄 index.test.tsx.snap
- 📄 index.tsx
- 📄 index.test.tsx
- 📄 styles.module.scss
- 📂
- 📂components
- 📂_common