|
1 | 1 | # csss-site-frontend
|
2 | 2 |
|
3 |
| -The frontend of the [CSSS website](https://sfucsss.org) (pending deployment). |
| 3 | +The frontend of the CSSS website, currently deployed at [new.sfucsss.org](https://new.sfucsss.org). |
4 | 4 |
|
5 |
| -## Important Repos |
| 5 | +Please check out [csss-site-backend](https://github.com/csss/csss-site-backend/) for the backend API used by this repo. |
6 | 6 |
|
7 |
| -- [csss-raspberry](https://github.com/csss/csss-raspberry/) - React component library. |
8 |
| -- [csss-site-backend](https://github.com/csss/csss-site-backend/) - Backend API for csss-site-frontend. |
| 7 | +## Development |
9 | 8 |
|
10 |
| -## Prerequisites |
| 9 | +### Prereqs |
11 | 10 |
|
12 |
| -To work on the CSSS frontend, you will need the following: |
| 11 | +You need to be in a UNIX-like environment to work on csss-site-frontend - so MacOS, Linux, or WSL. |
| 12 | +Make sure you have `git` installed and are familiar with how to use it. |
| 13 | +Install the following versions of `node` and `npm`: |
13 | 14 |
|
14 |
| -- `bash` (or an alternative shell) - for running scripts. |
15 |
| -- `npm` - for working with the React application. |
16 |
| - - Please use version 9.9.2! |
17 |
| -- (deploying) `nginx` - for serving the files after deployment from `build/`. |
| 15 | +`node`: v18.16.X |
18 | 16 |
|
19 |
| -## Local Development |
| 17 | +`npm`: 9.9.X |
20 | 18 |
|
21 |
| -The following steps should be followed to develop the frontend on your local machine: |
| 19 | +### Set-up |
22 | 20 |
|
23 |
| -- `npm ci` - install dependencies |
24 |
| -- `npm run start` - run frontend on localhost |
| 21 | +To set-up the csss-site-frontend repo, `git clone` it somewhere you can access, and |
| 22 | +Run `npm ci` from within the csss-site-frontend (same directory as the `package.json` file). |
| 23 | + |
| 24 | +### Local Deployment |
| 25 | + |
| 26 | +Run `npm run start` to deploy the site locally at [localhost:3000](http://localhost:3000). |
| 27 | + |
| 28 | +The `npm run start` script runs `npm run build` and then `npm run serve`. |
| 29 | +Please see the section on the site architecture for information about what these scripts do. |
| 30 | + |
| 31 | +## Documentation |
| 32 | + |
| 33 | +The documentation for this repo is lacking at the moment, aside from the architecture section. |
| 34 | +Please read the source code for the `main` and `test` entry-points in the `src` folder for creating a new React app. |
| 35 | + |
| 36 | +### Creating a new React App |
| 37 | + |
| 38 | +To create a new React app, simply create a new folder under `src` and code away as if it is it's own package. |
| 39 | +Any additional packages you might need for your app should be installed at the root of `csss-site-frontend`. |
| 40 | + |
| 41 | +When ready to build, add a line to the `webpack.config.js` file under "entry". |
| 42 | +You should reference the `index.js` file that is the root of your React app. |
| 43 | + |
| 44 | +### Serving Local Changes |
| 45 | + |
| 46 | +For serving local changes during development, I recommend running `npm run serve` in a separate terminal, |
| 47 | +and running `npm run build` whenever you've modified enough files to view your changes. |
| 48 | +Refreshing your browser will load the newly built files. |
| 49 | + |
| 50 | +Alternatively, you can just run `npm run start` whenever you want to see your changes, and enter CTRL+C to stop serving. |
| 51 | + |
| 52 | +## Architecture |
| 53 | + |
| 54 | +The site is served as static files. |
| 55 | + |
| 56 | +So, how do we get from several React apps to static files that can be served? |
| 57 | +And what about plain, static pages, that should be served alongside the React apps? |
| 58 | + |
| 59 | +### Building |
| 60 | + |
| 61 | +React apps are built to static files with [webpack](https://webpack.js.org/), |
| 62 | +which "packs" JavaScript starting at a given entry-point into a standalone "bundle". |
| 63 | +This bundle can then be used in an HTML file with the `<script>` tag. |
| 64 | + |
| 65 | +There are several entry-points in this repo, each being a standalone React app. |
| 66 | +The entry-points are folders in the `src` folder, except the `_shared` folder. |
| 67 | +The `_shared` folder contains components and helper functions that can be used by any of the React apps in this site. |
| 68 | + |
| 69 | +During the build process (`npm run build`), the `build` folder is emptied, |
| 70 | +and Webpack compiles each entry-point into the `js` folder inside of the `build` folder. |
| 71 | +E.g., `src/main/**/*.js` is bundled into a single `build/js/main.js` file, |
| 72 | +which contains all necessary React code, and other `npm` packages' code used. |
| 73 | + |
| 74 | +Then, the contents of the `public` folder are copied into the `build` folder. |
| 75 | +HTML files in `public` use the files compiled by webpack to serve the React apps; |
| 76 | +e.g., `public/index.html` imports the `build/js/main.js` file like so: |
| 77 | + |
| 78 | +```html |
| 79 | +<script defer="defer" src="/js/main.js"></script> |
| 80 | +``` |
| 81 | + |
| 82 | +Notice that the `build` folder is treated as the root of the application (hence the leading slash). |
| 83 | +Thus, the `build` folder is the root of whatever host is serving the site. |
| 84 | + |
| 85 | +### Impacts |
| 86 | + |
| 87 | +There are some impacts this has on developing a React app. |
| 88 | + |
| 89 | +React, under the hood, is a library for creating "single-page applications". |
| 90 | +This is typically mitigated to create multi-page applications with something like [React Router](https://reactrouter.com/). |
| 91 | + |
| 92 | +However, the typical use of React Router leans on browser APIs to change the URL without refreshing the page. |
| 93 | +This breaks the continuity of the URL - it no longer uniquely identifies the actual file that React is served from. |
| 94 | +So, there is some server-side magic used to make this work, typically with something like Express. |
| 95 | + |
| 96 | +But for the purposes of this site, where we want to serve static files in addition to React apps, we cannot use this server-side magic. |
| 97 | +Remember: it breaks the continuity of the URl, making the path no longer uniquely identify an actual file. |
| 98 | + |
| 99 | +_So,_ the solution is to use Hash Routing instead of the typical Browser Routing. |
| 100 | +That is, all React apps should route their pages not like `http://localhost:3000/this/page/is/handled/by/react/router`, |
| 101 | +but instead like `http://localhost:3000#this/page/is/handled/by/react/router`. |
| 102 | + |
| 103 | +This is built on the fact that the anchor of a URL (everything that follows a hashtag) is purely client-side. |
| 104 | +That is, it doesn't trigger a page refresh, nor breaks the file continuity of a URL. |
| 105 | + |
| 106 | +Luckily, Hash Routing is handled by React Router too, check out [this page](https://reactrouter.com/en/main/routers/create-hash-router). |
| 107 | +Ignore the warning that "using hash URLs is not recommended" - our use case is exactly the use case for hash routing. |
| 108 | +So yay - everything you're used to with React Router can be used with this site - just keep in mind that the URLs will look different. |
0 commit comments