├── .gitignore
├── .eslintignore
├── .prettierignore
├── .prettierrc
├── husky.config.js
├── typings
└── png.d.ts
├── cypress.json
├── cypress
├── integration
│ └── example.spec.ts
├── videos
│ └── example.spec.ts.mp4
├── tsconfig.json
├── plugins
│ └── index.js
├── fixtures
│ └── example.json
└── support
│ ├── index.ts
│ └── commands.ts
├── lint-staged.config.js
├── storybook
├── preview.js
├── main.js
└── stories
│ ├── example2.stories.tsx
│ └── example.stories.mdx
├── __tests__
└── example.spec.ts
├── .editorconfig
├── src
├── index.tsx
└── App.tsx
├── .babelrc.js
├── public
└── index.html
├── tsconfig.json
├── webpack.config.prod.js
├── webpack.config.dev.js
├── package.json
├── README.md
├── .eslintrc
└── jest.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | cypress/videos
4 | cypress/screenshots
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | cypress/videos
4 | cypress/screenshots
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "semi": false,
4 | "trailingComma": "none"
5 | }
6 |
--------------------------------------------------------------------------------
/husky.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | hooks: {
3 | 'pre-commit': 'lint-staged'
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/typings/png.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.png' {
2 | const content: string
3 |
4 | export default content
5 | }
6 |
--------------------------------------------------------------------------------
/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "http://localhost:3000",
3 | "viewportWidth": 1366,
4 | "viewportHeight": 768
5 | }
6 |
--------------------------------------------------------------------------------
/cypress/integration/example.spec.ts:
--------------------------------------------------------------------------------
1 | describe('testing example', () => {
2 | it('visit url', () => {
3 | cy.visit('/')
4 | })
5 | })
6 |
--------------------------------------------------------------------------------
/cypress/videos/example.spec.ts.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dannielss/react-typescript-boilerplate/HEAD/cypress/videos/example.spec.ts.mp4
--------------------------------------------------------------------------------
/lint-staged.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | '**/*.+(js|jsx|json|ts|tsx|md|mdx|html|eslintrc|prettierrc)': [
3 | 'prettier --write'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/storybook/preview.js:
--------------------------------------------------------------------------------
1 | export const parameters = {
2 | controls: { expanded: true },
3 | viewport: {
4 | defaultViewport: 'responsive'
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/__tests__/example.spec.ts:
--------------------------------------------------------------------------------
1 | describe('testing', () => {
2 | it('example of test', () => {
3 | const a = 1
4 | expect(a + 1).toEqual(2)
5 | })
6 | })
7 |
--------------------------------------------------------------------------------
/cypress/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "types": ["cypress"]
5 | },
6 | "include": [".", "../typings"]
7 | }
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 |
--------------------------------------------------------------------------------
/cypress/plugins/index.js:
--------------------------------------------------------------------------------
1 | module.exports = (on, config) => {
2 | // `on` is used to hook into various events Cypress emits
3 | // `config` is the resolved Cypress config
4 | }
5 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import * as ReactDOM from 'react-dom'
3 | import App from './App'
4 |
5 | ReactDOM.render(
    
3 |  
4 |
5 |
6 | 10 | Technologies | 11 | Configuration | 12 | Tests | 13 | Others | 14 |
15 | 16 | ## :rocket: Technologies 17 | 18 | - [React](https://reactjs.org) 19 | - [Typescript](https://www.typescriptlang.org/) 20 | - [Webpack](https://webpack.js.org/) 21 | - [Babel](https://babeljs.io/) 22 | - [Storybook](https://storybook.js.org/) 23 | - [Jest](https://jestjs.io/) 24 | - [Cypress](https://www.cypress.io/) 25 | - [Eslint](https://eslint.org/) 26 | - [Prettier](https://prettier.io/) 27 | - [Commitizen](https://github.com/commitizen/cz-cli) 28 | - [Husky](https://github.com/typicode/husky) 29 | - [Serve](https://www.npmjs.com/package/serve) 30 | 31 | ## :wrench: Configuration 32 | 33 | #### 1. Install all dependencies with 34 | 35 | ```sh 36 | $ npm install 37 | ``` 38 | 39 | or using yarn 40 | 41 | ```sh 42 | $ yarn 43 | ``` 44 | 45 | #### 2. Start the webpack-dev-server 46 | 47 | ```sh 48 | $ npm run dev 49 | ``` 50 | 51 | or using yarn 52 | 53 | ```sh 54 | $ yarn dev 55 | ``` 56 | 57 | ## :mag: Tests 58 | 59 | #### 1. Run e2e tests with 60 | 61 | ```sh 62 | $ npm run test:e2e 63 | ``` 64 | 65 | or using yarn 66 | 67 | ```sh 68 | $ yarn test:e2e 69 | ``` 70 | 71 | #### 2. Run e2e tests in terminal with 72 | 73 | ``` 74 | $ npm run test:e2e:run 75 | ``` 76 | 77 | or using yarn 78 | 79 | ``` 80 | $ yarn test:e2e:run 81 | ``` 82 | 83 | #### :exclamation: If Cypress (yarn test:e2e) is still not installed after yarn. Install cypress with: 84 | ```sh 85 | $ npx cypress install 86 | ``` 87 | 88 | 89 | #### 3. Run unit tests with 90 | 91 | ``` 92 | $ npm run test 93 | ``` 94 | 95 | or using yarn 96 | 97 | ``` 98 | $ yarn test 99 | ``` 100 | 101 | ## :gift: Others commands 102 | 103 | ```sh 104 | # Build for web (compiled to build/) 105 | $ npm run build 106 | 107 | # Run for web production (needs npm run build first) 108 | $ npm run start 109 | 110 | # Open storybook 111 | $ npm run storybook 112 | 113 | # Check Eslint errors 114 | $ npm run lint 115 | 116 | # Format all files with prettier 117 | $ npm run format 118 | 119 | # Commit using commitizen 120 | $ npm run commit 121 | ``` 122 | 123 | or using yarn 124 | 125 | ```sh 126 | # Build for web (compiled to build/) 127 | $ yarn build 128 | 129 | # Run for web production (needs yarn build first) 130 | $ yarn start 131 | 132 | # Open storybook 133 | $ yarn storybook 134 | 135 | # Check Eslint errors 136 | $ yarn lint 137 | 138 | # Format all files with prettier 139 | $ yarn format 140 | 141 | # Commit using commitizen 142 | $ yarn commit 143 | ``` 144 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "parserOptions": { 4 | "ecmaFeatures": { 5 | "jsx": true 6 | } 7 | }, 8 | "plugins": ["jest"], 9 | "env": { 10 | "browser": true, 11 | "jest": true 12 | }, 13 | "extends": [ 14 | "airbnb", 15 | "airbnb/hooks", 16 | "plugin:jest/recommended", 17 | "prettier", 18 | "prettier/react" 19 | ], 20 | "rules": { 21 | "react/jsx-filename-extension": [ 22 | 1, 23 | { 24 | "extensions": [".js", ".jsx", ".mdx"] 25 | } 26 | ], 27 | "import/extensions": [ 28 | 1, 29 | { 30 | "js": "never", 31 | "jsx": "never", 32 | "svg": "always", 33 | "json": "always" 34 | } 35 | ], 36 | "no-console": "off", 37 | "react/jsx-props-no-spreading": "off", 38 | "global-require": "off", 39 | "import/no-extraneous-dependencies": [ 40 | "error", 41 | { 42 | "devDependencies": [ 43 | "__tests__/*.*", 44 | "storybook/*.*", 45 | "typings/*.*", 46 | "/*.*" 47 | ] 48 | } 49 | ], 50 | "react-hooks/exhaustive-deps": "off", 51 | "jsx-a11y/anchor-is-valid": "off", 52 | "react/no-array-index-key": "off", 53 | "no-irregular-whitespace": "off", 54 | "prefer-promise-reject-errors": "off", 55 | "eqeqeq": "off", 56 | "no-restricted-syntax": "off", 57 | "no-await-in-loop": "off", 58 | "no-new-func": "off", 59 | "consistent-return": "off" 60 | }, 61 | "settings": { 62 | "import/resolver": { 63 | "node": {}, 64 | "webpack": { 65 | "config": "webpack.config.dev.js" 66 | } 67 | } 68 | }, 69 | "overrides": [ 70 | { 71 | "files": "**/*.+(md|mdx)", 72 | "extends": ["plugin:mdx/recommended"] 73 | }, 74 | { 75 | "files": "**/*.+(ts|tsx)", 76 | "parser": "@typescript-eslint/parser", 77 | "parserOptions": { 78 | "project": "./tsconfig.json", 79 | "ecmaFeatures": { 80 | "jsx": true 81 | } 82 | }, 83 | "plugins": ["jest", "@typescript-eslint"], 84 | "extends": [ 85 | "airbnb-typescript", 86 | "airbnb/hooks", 87 | "plugin:@typescript-eslint/eslint-recommended", 88 | "plugin:@typescript-eslint/recommended", 89 | "plugin:jest/recommended", 90 | "prettier", 91 | "prettier/react", 92 | "prettier/@typescript-eslint" 93 | ], 94 | "rules": { 95 | "import/extensions": [ 96 | 1, 97 | { 98 | "js": "never", 99 | "jsx": "never", 100 | "ts": "never", 101 | "tsx": "never", 102 | "svg": "always", 103 | "json": "always" 104 | } 105 | ], 106 | "no-console": "off", 107 | "react/jsx-props-no-spreading": "off", 108 | "react/prop-types": "off", 109 | "global-require": "off", 110 | "import/no-extraneous-dependencies": [ 111 | "error", 112 | { 113 | "devDependencies": [ 114 | "storybook/*.*", 115 | "__test__/*.*", 116 | "typings/*.*", 117 | "/*.*" 118 | ] 119 | } 120 | ], 121 | "react-hooks/exhaustive-deps": "off", 122 | "jsx-a11y/anchor-is-valid": "off", 123 | "react/no-array-index-key": "off", 124 | "no-irregular-whitespace": "off", 125 | "prefer-promise-reject-errors": "off", 126 | "spaced-comment": "off", 127 | "eqeqeq": "off", 128 | "no-restricted-syntax": "off", 129 | "no-await-in-loop": "off", 130 | "@typescript-eslint/no-implied-eval": "off", 131 | "no-new-func": "off", 132 | "consistent-return": "off", 133 | "@typescript-eslint/naming-convention": ["off"] 134 | } 135 | } 136 | ] 137 | } 138 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | 4 | module.exports = { 5 | // All imported modules in your tests should be mocked automatically 6 | // automock: false, 7 | 8 | // Stop running tests after `n` failures 9 | // bail: 0, 10 | 11 | // The directory where Jest should store its cached dependency information 12 | // cacheDirectory: "/tmp/jest_rs", 13 | 14 | // Automatically clear mock calls and instances between every test 15 | clearMocks: true, 16 | 17 | // Indicates whether the coverage information should be collected while executing the test 18 | // collectCoverage: false, 19 | 20 | // An array of glob patterns indicating a set of files for which coverage information should be collected 21 | // collectCoverageFrom: undefined, 22 | 23 | // The directory where Jest should output its coverage files 24 | // coverageDirectory: "coverage", 25 | 26 | // An array of regexp pattern strings used to skip coverage collection 27 | // coveragePathIgnorePatterns: [ 28 | // "/node_modules/" 29 | // ], 30 | 31 | // Indicates which provider should be used to instrument code for coverage 32 | // coverageProvider: "babel", 33 | 34 | // A list of reporter names that Jest uses when writing coverage reports 35 | // coverageReporters: [ 36 | // "json", 37 | // "text", 38 | // "lcov", 39 | // "clover" 40 | // ], 41 | 42 | // An object that configures minimum threshold enforcement for coverage results 43 | // coverageThreshold: undefined, 44 | 45 | // A path to a custom dependency extractor 46 | // dependencyExtractor: undefined, 47 | 48 | // Make calling deprecated APIs throw helpful error messages 49 | // errorOnDeprecated: false, 50 | 51 | // Force coverage collection from ignored files using an array of glob patterns 52 | // forceCoverageMatch: [], 53 | 54 | // A path to a module which exports an async function that is triggered once before all test suites 55 | // globalSetup: undefined, 56 | 57 | // A path to a module which exports an async function that is triggered once after all test suites 58 | // globalTeardown: undefined, 59 | 60 | // A set of global variables that need to be available in all test environments 61 | // globals: {}, 62 | 63 | // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. 64 | // maxWorkers: "50%", 65 | 66 | // An array of directory names to be searched recursively up from the requiring module's location 67 | // moduleDirectories: [ 68 | // "node_modules" 69 | // ], 70 | 71 | // An array of file extensions your modules use 72 | moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx'], 73 | 74 | // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module 75 | // moduleNameMapper: {}, 76 | 77 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader 78 | // modulePathIgnorePatterns: [], 79 | 80 | // Activates notifications for test results 81 | // notify: false, 82 | 83 | // An enum that specifies notification mode. Requires { notify: true } 84 | // notifyMode: "failure-change", 85 | 86 | // A preset that is used as a base for Jest's configuration 87 | // preset: undefined, 88 | 89 | // Run tests from one or more projects 90 | // projects: undefined, 91 | 92 | // Use this configuration option to add custom reporters to Jest 93 | // reporters: undefined, 94 | 95 | // Automatically reset mock state between every test 96 | // resetMocks: false, 97 | 98 | // Reset the module registry before running each individual test 99 | // resetModules: false, 100 | 101 | // A path to a custom resolver 102 | // resolver: undefined, 103 | 104 | // Automatically restore mock state between every test 105 | // restoreMocks: false, 106 | 107 | // The root directory that Jest should scan for tests and modules within 108 | // rootDir: undefined, 109 | 110 | // A list of paths to directories that Jest should use to search for files in 111 | // roots: [ 112 | // "