- Typescript docs
- TypeBox docs (All the types that work for
Type.<type>()
) - Fastify docs
- Node.js v20 docs
- React v18 docs
- Shopify GraphQL API Docs
To develop this project, you must have the following installed on your computer:
- Node.js v20
- We recommend using
nvm
ornvm-windows
(Node Version Manager) to install this version of Node.js:- To see if you have nvm installed, run:
nvm --version
- If you don't have it installed, use these links to install it:
- Windows: https://github.com/coreybutler/nvm-windows
- Mac/Linux: https://github.com/nvm-sh/nvm
- Once you have nvm working, run the following to install and switch to Node.js v20:
nvm install 20 && nvm use 20
- To see if you have nvm installed, run:
- We recommend using
- In the top-level of the repo, run
npm i
to install dependencies for the project. This will also install the dependencies for the frontend, backend, and shared modules.npm i
- Build the shared module. Anytime you change the types, you will have to re-run this command.
npm run build:shared
After running this, if you get IDE errors about the
'shared'
module not being found, you'll have to restart your Typescript service: - Create a
.env
file in the/server
directory and populate it as follows, replacing<the real token>
with the token that was given to you by a team member:ACCESS_TOKEN=<the real token> STORE_URL=quickstart-cae44a88.myshopify.com
- Start the backend. We use nodemon to auto-reload when you make changes to the backend, you might just have to
click into the backend terminal to trigger the reload.
npm run backend
- In a new terminal, start the frontend. Vite should auto-detect most changes and do a hot-reload for you so you don't
need to manually re-run this command when you make changes, but on occasion it may fail and you'll need to manually
re-run this.
npm run frontend
When making changes that you want to save and share with the team, use the following steps:
- Make a branch, if you haven't already (We don't want to push straight to main because that can get confusing and mess up peoples git history.)
git checkout -b <your branch name>
- Validate your code
- Lint your code:
npm run lint:fix
(from the project root) - Build your code:
npm run build
(from the project root) - (If we create any tests:) Test your code:
npm run test
(from the project root)
If anything fails, fix the errors. Feel free to ask for help on fixing things.
- Lint your code:
- Commit your code
- Use
git status
to see changes and usegit add <file/folder>
to selectively stage changes you want to commit. Don't stage files you don't want to commit. - Use
git commit -m <commit message>
to commit your changes. More, smaller commits is better than one large one, but it's not that big of a deal.
- Use
- Push your code
git push
to create your branch in GitHub and send up your changesConsider running
git config push.autoSetupRemote true
and then trying again if you get an error about needing to set your remote- Git should print a link to the console, click on that. It will open in your browser and prompt you to create a PR! Send the Pr to a teammate or the team discord for a review and then merge it to main.
- On your local machine, make sure to
git checkout main && git pull
after your branch has been merged. You can also rungit branch -D <your old branch name>
to delete it locally to clean up.
My least-favorite part about using npm workspaces is that installing dependencies is slightly more annoying than usual if you want to maintain the integrity of the lockfile and project structure.
Normally you would just run npm i <package_name>
and you can still do that if you want
to install a dependency for the top-level of the project, meaning that all three modules will have access to it.
If you just want to install a dependency for one of the modules (i.e. just the backend), this is how you do it. Run a command like this from the top-level of the repository:
npm i --workspace=<workspace_name> <package_name>
e.g. npm i --workspace=server axios
if I wanted to install axios in the backend module. The workspace names are just
the names of the directories.
To facilitate calling our backend routes while doing frontend development, there are two ways to view a
Swagger-style OpenAPI v3 spec document for our backend routes. To do either of
these, you must be able to run the project locally, including having dependencies installed and with a .env
file.
- Option 1: (Recommended) Via a web interface:
- Run
npm run backend
- Navigate to http://localhost:8080/spec in your browser, and voila! The backend routes.
- Run
- Option 2: Generate a
spec.yml
file:- Run
npm run spec
- Copy/open the generated
server/spec.yml
file in your preferred Swagger editor (For example, the official Swagger Editor)
- Run
This app uses a CS340-Tweeter-esque monorepo architecture with a backend module, a frontend module, and a third module for shared code, especially type definitions.
The backend (server/
) is written in Typescript, uses the Node.js v20
javascript runtime, and relies on the Fastify web server framework (the industry-standard replacement for Express).
This combination results in a speedy, modern, and type-safe backend.
For the frontend (web/
), we're using the same frontend setup that is used in CS340, which uses Vite as
the development framework (building, hot-reload, etc.), React as the web framework library,
and Typescript again as the JS flavor.
Compile-time and development type safety will be enforced by Typescript. We also want run-time type-safety in the backend API calls, and this will be enforced by Fastify. Fastify uses JSON Schema for defining the type definitions of requests and responses, which is standard for RESTful APIs.
Since we don't want to have to write our types in both Typescript and JSON Schema, we will use TypeBox
which will export definitions in both formats so that we only have to write them once. We define these models in the 'shared'
directory (shared/
), which the backend and frontend both import to access the type definitions.
For an example of a what a route will look like with its backend implementation, shared types, and its frontend usage,
look at the /add
example route:
- For the types, look at
/shared/src/model/add.model.ts
. Note how we export all of the needed exports in/shared/src/index.ts
. - For the backend implementation, look at
/server/src/routes/add/root.ts
.- Here you can see an example of how to mock a route while its still in development (using
Value.Create()
), but also a simple example of how to implement the route once we are done mocking that route.
- Here you can see an example of how to mock a route while its still in development (using
- For the frontend implementation, look at
/web/src/client/add.ts
and the bottom of/web/src/components/main.tsx
.
For now, we have no plans to deploy this anywhere. It can be run on a local computer for testing and presentation.