├── .circleci
└── config.yml
├── .github
└── ISSUE_TEMPLATE
│ └── feature_request.md
├── .gitignore
├── .vscode
├── launch.json
└── settings.json
├── LICENSE
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── _server
├── __tests__
│ ├── hello-world.test.ts
│ └── server.test.ts
├── api
│ └── hello-world.ts
├── index.ts
└── server.ts
├── client
├── __tests__
│ ├── __snapshots__
│ │ └── subapp.spec.tsx.snap
│ └── subapp.spec.tsx
├── app
│ ├── app.tsx
│ ├── components
│ │ ├── TestComponent.tsx
│ │ ├── about.tsx
│ │ ├── error-page.tsx
│ │ ├── header.tsx
│ │ ├── home.tsx
│ │ ├── index.ts
│ │ └── subapp.tsx
│ ├── index.tsx
│ └── router.tsx
├── public
│ ├── img
│ │ ├── icon-128.png
│ │ ├── icon-256.png
│ │ ├── icon-48.png
│ │ ├── icon-512.png
│ │ ├── icon-72.png
│ │ └── icon-96.png
│ ├── index.html
│ └── manifest.json
├── setupTests.ts
├── tsconfig.json
└── webpack.config.js
├── docs
├── how-to-add-routes.md
├── index_README.md
└── pwa
│ └── resources.md
├── jest.config.js
├── package-lock.json
├── package.json
├── server
└── index.js
├── tsconfig.json
└── yarn.lock
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | docker:
5 | - image: circleci/node:7.10
6 |
7 | working_directory: ~/repo
8 |
9 | steps:
10 | - checkout
11 |
12 | - restore_cache:
13 | keys:
14 | - v1-dependencies-{{ checksum "package.json" }}
15 | - v1-dependencies-
16 |
17 | - run: yarn install
18 |
19 | - save_cache:
20 | paths:
21 | - node_modules
22 | key: v1-dependencies-{{ checksum "package.json" }}
23 |
24 | - run: yarn test
25 |
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea/enhancement for this project
4 |
5 | ---
6 |
7 | **Requirement**
8 | Clear and concise description of what the requirement is. What problem it is going to solve.
9 |
10 | **Tasks**
11 | Breakdown of feature in small chunks of work. Chunks which could be taken as one or separate PRs.
12 |
13 | **Additional context**
14 | Add any other context or screenshots about the feature request here.
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
3 | yarn-error.log
4 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "node",
9 | "request": "launch",
10 | "name": "Run Unit Tests In Current File",
11 | "program": "${workspaceFolder}/node_modules/jest/bin/jest.js",
12 | "cwd": "${workspaceFolder}",
13 | "args": [
14 | "--config",
15 | "jest.config.js",
16 | "${relativeFile}"
17 | ],
18 | "outFiles": ["${workspaceFolder}/**/*.js", "!**/node_modules/**"]
19 | }
20 | ]
21 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "git.ignoreLimitWarning": true
3 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Tanay Pratap
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Please provide enough information so that others can review your pull request:
2 |
3 | ## Motivation
4 |
5 | Explain the **motivation** for making this change. What existing problem does the pull request solve? Mention issue number if any.
6 |
7 | ## Test plan
8 |
9 | Demonstrate the code is solid. Example: the exact commands you ran and their output, screenshots / videos if the pull request changes UI.
10 |
11 | Make sure you test on Chrome and Firefox if your change affects UI.
12 |
13 | The code must pass tests. Also, add tests for your code.
14 |
15 | ## Code formatting
16 |
17 | Look around. Match the style of the rest of the codebase. Run `yarn format` before committing.
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Polaris 2018
2 | =============
3 | Creating a scaffolding for full stack React with TypeScript (striving to put everything in TS), Apollo, GraphQL, Jest, Express, React Router and make them all work cohesively
4 |
5 | ### Vision
6 | This is a work in progress. Idea is to treat this as scaffolding for future projects.
7 | It will also be a learning of all these technologies in React Ecosystem.
8 |
9 | ### Technologies to be incorporated
10 | * [React 16.3](https://reactjs.org/)
11 | * [TypeScript (Both on client and server side)](https://www.typescriptlang.org/)
12 | * [React Router 4](https://reacttraining.com/react-router/)
13 | * [PostCSS for CSS](https://postcss.org/)
14 | * [Webpack 4](https://webpack.js.org/)
15 | * [Jest (React Testing)](https://jestjs.io/en/)
16 | * [Apollo](https://www.apollographql.com/)
17 | * [GraphQL](https://graphql.org/)
18 | * [Express](https://expressjs.com/)
19 | * [MongoDB](https://www.mongodb.com/)
20 |
21 |
22 | ### Running the client and server
23 | Currently client and server are two disjointed pieces. However, soon server will be serving the client in dev as well as in prod mode.
24 | For now, if you want to run server (which has no useful code), use `npm run start:server` at project root.
25 | The client is setup only for development currently, if you want to run it to see the output use `npm run start` at project root.
26 |
27 | ### Testing setup for Polaris
28 |
29 | Polaris uses Jest for server side testing and Jest & Enzyme to test the React components. To enable Jest with typescript, a jest config file is included in the root directory, where various options are set to suit the needs of the project. Besides, Enzyme is being used as it is an exclusive testing utility for React which makes it easier to assert and manipulate component's output, thereby making testing client side code less cumbersome.
30 |
31 | ### How to run tests
32 |
33 | `npm run test` - To run all the unit tests in client & server both.
34 | `npm run test:server` - To run only server unit tests
35 | `npm run test:client` - To run only client unit tests
36 | `npm run test:watch` - To run jest in watch mode
37 |
38 | To debug the individual tests, run the vscode debugger with `Run Unit Tests In Current File` configuration.
39 |
40 | ### How to add tests
41 |
42 | Add your test file in the following format [filename].spec.ts/tsx or [filename].test.ts/tsx in the __tests__ folder in **./client** for client side & in **./_server** for server side tests. A sample test file has been written in the corresponding folders.
43 |
44 | ### Documentation
45 | Separate folder is created for docs and all documentation related to a functionality/library/tech should go into proper folder.
46 | A link should be added here, for example:
47 | #### PWA
48 |
49 | * [Resources for making a React App PWA](./docs/pwa/resources.md)
--------------------------------------------------------------------------------
/_server/__tests__/hello-world.test.ts:
--------------------------------------------------------------------------------
1 | import hello from "../api/hello-world";
2 |
3 | const send = jest.fn();
4 | const res = {
5 | send,
6 | };
7 |
8 | test('Should call res.send() with Hello World!', () => {
9 | hello({} as any, res as any);
10 | expect(send.mock.calls).toHaveLength(1);
11 | expect(send.mock.calls[0][0]).toBe('Hello World!');
12 | });
--------------------------------------------------------------------------------
/_server/__tests__/server.test.ts:
--------------------------------------------------------------------------------
1 | import express from "express";
2 | import { bootstrap } from "../server";
3 |
4 | jest.mock("express", () => {
5 | return jest.fn().mockImplementation(() => {
6 | return {
7 | set: jest.fn(),
8 | get: jest.fn(),
9 | listen: jest.fn((_options, callback) => callback())
10 | };
11 | });
12 | });
13 |
14 | describe("Bootstraping server", () => {
15 | beforeEach(() => {
16 | (express as any).mockClear();
17 | })
18 | test("bootstrap through express", () => {
19 | bootstrap();
20 | expect(express).toHaveBeenCalledTimes(1);
21 | })
22 | })
--------------------------------------------------------------------------------
/_server/api/hello-world.ts:
--------------------------------------------------------------------------------
1 | import { Response, Request } from "express"
2 |
3 | export default (req: Request, res: Response) => res.send('Hello World!');
--------------------------------------------------------------------------------
/_server/index.ts:
--------------------------------------------------------------------------------
1 | import { bootstrap } from "./server";
2 |
3 | bootstrap();
--------------------------------------------------------------------------------
/_server/server.ts:
--------------------------------------------------------------------------------
1 | import express from "express"
2 | import hello from "./api/hello-world";
3 |
4 | export async function bootstrap () {
5 | const server = express()
6 |
7 | server.set('port', 6789)
8 |
9 | server.get('/hello', hello);
10 |
11 | server.listen(server.get('port'), () => {
12 | console.log(`Server is running at http://localhost:${server.get('port')} in ${server.get('env')} mode`)
13 | })
14 | }
--------------------------------------------------------------------------------
/client/__tests__/__snapshots__/subapp.spec.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`matches snapshot test with no props supplied 1`] = `
4 |
5 | Hello
6 |
7 | `;
8 |
--------------------------------------------------------------------------------
/client/__tests__/subapp.spec.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { SubApp } from "../app/components/subapp";
3 | import { shallow } from "enzyme";
4 |
5 | test("renders the heading with props supplied", () => {
6 | const result = shallow().contains(
7 |