├── .env.template ├── .prettierignore ├── cypress ├── support │ ├── index.js │ └── commands.ts ├── integration │ └── main.spec.ts ├── fixtures │ └── auth.json ├── tsconfig.json ├── plugins │ └── index.js └── webpack.config.js ├── src ├── setupTests.ts ├── react-app-env.d.ts ├── index.tsx ├── App.css ├── App.spec.tsx ├── App.tsx └── commons │ └── style │ ├── globalstyle.ts │ └── themes │ └── default.ts ├── .commitlintrc.json ├── public ├── robots.txt ├── manifest.json └── index.html ├── .eslintignore ├── cypress.json ├── .storybook ├── BeautifyStory │ ├── style.ts │ └── index.tsx ├── addons.ts ├── router-decorator.tsx ├── theme-decorator.tsx ├── webpack.config.js └── config.ts ├── .editorconfig ├── .stylelintrc.json ├── .prettierrc ├── .gitignore ├── tsconfig.json ├── LICENSE ├── .eslintrc.json ├── README.md └── package.json /.env.template: -------------------------------------------------------------------------------- 1 | REACT_APP_SERVER_URL= 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .vscode/* 2 | dist/* 3 | -------------------------------------------------------------------------------- /cypress/support/index.js: -------------------------------------------------------------------------------- 1 | import './commands'; 2 | -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom/extend-expect'; 2 | -------------------------------------------------------------------------------- /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-conventional"] 3 | } 4 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package.json 3 | .vscode/ 4 | dist/ 5 | build/ 6 | coverage/ -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | // / 2 | // / 3 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | ReactDOM.render(, document.getElementById('root')); 6 | -------------------------------------------------------------------------------- /cypress/integration/main.spec.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Main page', () => { 4 | it('visit successfully', () => { 5 | cy.visit('/'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectId": "wauqe2", 3 | "baseUrl": "http://localhost:3000", 4 | "video": true, 5 | "viewportWidth": 1280, 6 | "viewportHeight": 1024, 7 | "requestTimeout": 15000 8 | } 9 | -------------------------------------------------------------------------------- /.storybook/BeautifyStory/style.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const Label = styled.h1` 4 | font-size: 2.5rem; 5 | `; 6 | 7 | export const Content = styled.div` 8 | font-size: 1.5rem; 9 | `; 10 | -------------------------------------------------------------------------------- /cypress/fixtures/auth.json: -------------------------------------------------------------------------------- 1 | { 2 | "userId": 1, 3 | "firstName": "firstname", 4 | "lastName": "lastname", 5 | "phoneNumber": "01012341234", 6 | "email": "test@gmail.com", 7 | "googleId": 12345, 8 | "message": "Success" 9 | } 10 | -------------------------------------------------------------------------------- /.storybook/addons.ts: -------------------------------------------------------------------------------- 1 | import '@storybook/addon-links/register'; 2 | import '@storybook/addon-viewport/register'; 3 | import '@storybook/addon-knobs/register'; 4 | import '@storybook/addon-actions/register'; 5 | import '@storybook/addon-a11y/register'; 6 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | @import-normalize; 2 | 3 | /** 4 | * Add the correct display in IE 9-. 5 | */ 6 | audio, 7 | video { 8 | display: inline-block; 9 | } 10 | 11 | /** 12 | * Remove the border on images inside links in IE 10-. 13 | */ 14 | img { 15 | border-style: none; 16 | } 17 | -------------------------------------------------------------------------------- /cypress/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "baseUrl": "../node_modules", 5 | "target": "es6", 6 | "lib": ["es6", "dom"], 7 | "types": ["cypress"], 8 | "allowJs": true 9 | }, 10 | "include": ["**/*.ts", "plugins/index.js"] 11 | } 12 | -------------------------------------------------------------------------------- /.storybook/router-decorator.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; 3 | 4 | export default story => ( 5 | 6 | 7 | {story()} 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.{json,yml,md,babelrc,remarkrc}] 13 | indent_style = space 14 | indent_size = 2 15 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-recommended", 3 | "rules": { 4 | "at-rule-no-unknown": [ 5 | true, 6 | { 7 | "ignoreAtRules": ["extends"] 8 | } 9 | ], 10 | "block-no-empty": null, 11 | "unit-whitelist": ["px", "rem", "%", "s"] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "overrides": [ 7 | { 8 | "files": "*.md", 9 | "options": { 10 | "printWidth": 70, 11 | "useTabs": false, 12 | "trailingComma": "none", 13 | "proseWrap": "never" 14 | } 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/App.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | describe('App', () => { 6 | it('renders without crashing', () => { 7 | const div = document.createElement('div'); 8 | ReactDOM.render(, div); 9 | ReactDOM.unmountComponentAtNode(div); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | coverage/ 4 | build/ 5 | .env 6 | .env.* 7 | !.env.template 8 | *.env.json 9 | secrets.tar 10 | !secrets.tar.enc 11 | cypress.env.json 12 | 13 | # Default 14 | .DS_Store 15 | Thumbs.db 16 | .idea/ 17 | .vscode/ 18 | *.sublime-project 19 | *.sublime-workspace 20 | *.log 21 | package-lock.json 22 | .eslintcache 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /cypress/support/commands.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-namespace */ 2 | declare namespace Cypress { 3 | interface Chainable { 4 | authLogin(): Chainable; 5 | } 6 | } 7 | 8 | Cypress.Commands.add('customCommand', () => { 9 | cy.setCookie('UID', Cypress.env('auth_token')); 10 | cy.server(); 11 | cy.route('POST', '/api/auth', 'fixture:auth.json'); 12 | }); 13 | -------------------------------------------------------------------------------- /cypress/plugins/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | const webpack = require('@cypress/webpack-preprocessor'); 3 | 4 | module.exports = on => { 5 | const options = { 6 | // send in the options from your webpack.config.js, so it works the same 7 | // as your app's code 8 | webpackOptions: require('../webpack.config'), 9 | watchOptions: {}, 10 | }; 11 | 12 | on('file:preprocessor', webpack(options)); 13 | }; 14 | -------------------------------------------------------------------------------- /.storybook/theme-decorator.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ThemeProvider } from 'styled-components'; 3 | import defaultTheme from '../src/commons/style/themes/default'; 4 | import Normalize from '../src/commons/style/normalize'; 5 | import GlobalStyles from '../src/commons/style/globalstyle'; 6 | 7 | export default story => ( 8 | 9 | 10 | 11 | {story()} 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /cypress/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | const path = require('path'); 3 | 4 | module.exports = { 5 | entry: './src/index.ts', 6 | module: { 7 | rules: [ 8 | { 9 | test: /\.tsx?/, 10 | use: 'ts-loader', 11 | exclude: /node_modules/, 12 | }, 13 | ], 14 | }, 15 | resolve: { 16 | extensions: ['.tsx', '.ts', '.js'], 17 | }, 18 | output: { 19 | filename: 'bundle.js', 20 | path: path.resolve(__dirname, 'dist'), 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ThemeProvider } from 'styled-components'; 3 | 4 | import 'App.css'; 5 | import GlobalStyles from './commons/style/globalstyle'; 6 | import defaultTheme from 'commons/style/themes/default'; 7 | 8 | const App: React.FC = () => { 9 | return ( 10 | 11 | 12 |
13 |

Welcome frontend boilerplate :)

14 |
15 |
16 | ); 17 | }; 18 | 19 | export default App; 20 | -------------------------------------------------------------------------------- /.storybook/webpack.config.js: -------------------------------------------------------------------------------- 1 | const Dotenv = require('dotenv-webpack'); 2 | 3 | module.exports = ({ config, mode }) => { 4 | config.plugins.push(new Dotenv()); 5 | 6 | config.module.rules.push({ 7 | test: /\.tsx?$/, 8 | use: [ 9 | { 10 | loader: require.resolve('babel-loader'), 11 | options: { 12 | presets: [require.resolve('babel-preset-react-app')], 13 | }, 14 | }, 15 | require.resolve('react-docgen-typescript-loader'), 16 | ], 17 | }); 18 | 19 | config.resolve.extensions.push('.ts', '.tsx'); 20 | 21 | return config; 22 | }; 23 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Frontend Workspace", 3 | "name": "Frontend Workspace", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "typeRoots": ["./node_modules/@types"], 3 | "compilerOptions": { 4 | "target": "es5", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "rootDirs": ["src"], 15 | "baseUrl": "src", 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "noEmit": true, 19 | "jsx": "preserve" 20 | }, 21 | "include": ["src"], 22 | "exclude": ["node_modules", "build", "scripts"] 23 | } 24 | -------------------------------------------------------------------------------- /.storybook/BeautifyStory/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styled from 'styled-components'; 3 | import * as S from './style'; 4 | 5 | const PrettyWrapper = styled.div` 6 | padding: 2rem 2rem 2rem 4rem; 7 | `; 8 | 9 | export const prettyWrapperDecorator = story => ( 10 | {story()} 11 | ); 12 | 13 | export const infoBody = { 14 | padding: '0', 15 | margin: '0', 16 | }; 17 | 18 | export const infoStory = { 19 | padding: '3rem', 20 | boxShadow: '#ccc 2px 2px 4px 2px', 21 | margin: '4rem 0rem', 22 | }; 23 | 24 | interface Props { 25 | content: string; 26 | } 27 | 28 | export function Note({ content }: Props): React.ReactElement { 29 | return ( 30 | <> 31 | Note : 32 | {content} 33 | 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | Frontend Workspace 16 | 17 | 18 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Sungdong Jo 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 | -------------------------------------------------------------------------------- /src/commons/style/globalstyle.ts: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from 'styled-components'; 2 | import { theme } from 'styled-tools'; 3 | 4 | const GlobalStyles = createGlobalStyle` 5 | @import url('https://fonts.googleapis.com/css?family=Gothic+A1|Noto+Sans+KR&display=swap'); 6 | * { 7 | margin: 0; 8 | font-family: 'Spoqa Han Sans', 'Noto Sans KR', 'Gothic A1', sans-serif; 9 | box-sizing: border-box; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | html { 14 | font-size: 10px; 15 | } 16 | body { 17 | height: 100%; 18 | padding: 0rem 5rem; 19 | } 20 | a, button { 21 | text-decoration: none; 22 | cursor: pointer; 23 | } 24 | 25 | h1 { 26 | ${theme('fontStyle.h1')} 27 | } 28 | 29 | h2 { 30 | ${theme('fontStyle.h2')} 31 | } 32 | 33 | h3 { 34 | ${theme('fontStyle.h3')} 35 | } 36 | 37 | h4 { 38 | ${theme('fontStyle.h4')} 39 | } 40 | 41 | h5 { 42 | ${theme('fontStyle.h5')} 43 | } 44 | 45 | h6 { 46 | ${theme('fontStyle.h6')} 47 | } 48 | 49 | p { 50 | ${theme('fontStyle.body1')} 51 | } 52 | `; 53 | 54 | export default GlobalStyles; 55 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "parserOptions": { 4 | "ecmaVersion": 2018, 5 | "sourceType": "module", 6 | "ecmaFeatures": { 7 | "impliedStrict": true 8 | } 9 | }, 10 | "extends": [ 11 | "react-app", 12 | "plugin:@typescript-eslint/recommended", 13 | "prettier/@typescript-eslint", 14 | "plugin:cypress/recommended" 15 | ], 16 | "plugins": ["react", "jest", "cypress"], 17 | "env": { 18 | "es6": true, 19 | "node": true, 20 | "browser": true, 21 | "jest/globals": true, 22 | "cypress/globals": true 23 | }, 24 | "globals": { 25 | "Atomics": "readonly", 26 | "SharedArrayBuffer": "readonly" 27 | }, 28 | "rules": { 29 | "react-hooks/rules-of-hooks": "error", 30 | "react-hooks/exhaustive-deps": "warn", 31 | "@typescript-eslint/no-unused-vars": "error", 32 | "jest/no-disabled-tests": "warn", 33 | "jest/no-focused-tests": "error", 34 | "jest/no-identical-title": "error", 35 | "jest/prefer-to-have-length": "warn", 36 | "jest/valid-expect": "off", 37 | "cypress/no-assigning-return-values": "error", 38 | "cypress/no-unnecessary-waiting": "off", 39 | "cypress/assertion-before-screenshot": "warn", 40 | "no-unused-expressions": 0 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /.storybook/config.ts: -------------------------------------------------------------------------------- 1 | import { configure, addParameters, addDecorator } from '@storybook/react'; 2 | import { withKnobs } from '@storybook/addon-knobs'; 3 | import { themes } from '@storybook/theming'; 4 | import { withInfo } from '@storybook/addon-info'; 5 | import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'; 6 | import { withA11y } from '@storybook/addon-a11y'; 7 | 8 | import themeDecorator from './theme-decorator'; 9 | import routerDecorator from './router-decorator'; 10 | import * as beautifyStory from './BeautifyStory'; 11 | 12 | addDecorator(withKnobs); 13 | addDecorator(withInfo); 14 | addDecorator(withA11y); 15 | addDecorator(themeDecorator); 16 | addDecorator(routerDecorator); 17 | addDecorator(beautifyStory.prettyWrapperDecorator); 18 | addParameters({ 19 | options: { 20 | theme: themes.light, 21 | panelPosition: 'bottom', 22 | sidebarAnimations: true, 23 | showPanel: true, 24 | hierarchySeparator: /\/|\./, 25 | hierarchyRootSeparator: '|', 26 | }, 27 | info: { 28 | styles: { 29 | infoBody: beautifyStory.infoBody, 30 | infoStory: beautifyStory.infoStory, 31 | }, 32 | inline: true, 33 | header: true, 34 | }, 35 | 36 | viewport: { 37 | viewports: INITIAL_VIEWPORTS, 38 | defaultViewport: 'someDefault', 39 | }, 40 | }); 41 | 42 | configure(require.context('../src', true, /\.stories\.tsx?$/), module); 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # frontend-boilerplate 2 | 3 |

4 | code style 5 | typescript 6 | Cypress.io tests 7 | Storybook 8 | Jest 9 | License: MIT 10 |

11 | 12 | This repository is my frontend boilerplate. Feel free to use this. 13 | 14 | ## Stack 15 | 16 | - Typescript 17 | - React (based CRA), styled-component 18 | - Storybook 19 | - Jest, react-testing-library, Cypress 20 | - Eslint, Stylelint, Commitlint, Prettier, Editorconfig 21 | 22 | ## Library 23 | - [http-status](https://www.npmjs.com/package/http-status) 24 | - [immer](https://www.npmjs.com/package/immer) 25 | - [react-icons](https://www.npmjs.com/package/react-icons) 26 | - [shortid](https://www.npmjs.com/package/shortid) 27 | - [styled-tools](https://www.npmjs.com/package/styled-tools) 28 | -------------------------------------------------------------------------------- /src/commons/style/themes/default.ts: -------------------------------------------------------------------------------- 1 | const theme = { 2 | palette: { 3 | primary: '#FF2D54', 4 | secondary: '#55A6FC', 5 | danger: '#d32f2f', 6 | alert: '#ffa000', 7 | success: '#388e3c', 8 | white: '#fff', 9 | black: '#212121', 10 | transparent: 'transparent', 11 | grayscale: [ 12 | '#212121', 13 | '#414141', 14 | '#616161', 15 | '#9e9e9e', 16 | '#bdbdbd', 17 | '#e0e0e0', 18 | '#eeeeee', 19 | '#ffffff', 20 | ], 21 | opacityscale: [0.9, 0.8, 0.7, 0.6, 0.5], 22 | }, 23 | 24 | fontStyle: { 25 | h1: ` 26 | font-size: 9.6rem; 27 | letter-spacing: -0.15rem; 28 | font-weight: 300; 29 | `, 30 | h2: ` 31 | font-size: 6rem; 32 | letter-spacing: -0.05rem; 33 | font-weight: 300; 34 | `, 35 | h3: ` 36 | font-size: 4.8rem; 37 | font-weight: 400; 38 | `, 39 | h4: ` 40 | font-size: 3.4rem; 41 | letter-spacing: -0.25rem; 42 | font-weight: 400; 43 | `, 44 | h5: ` 45 | font-size: 2.4rem; 46 | font-weight: 400; 47 | `, 48 | h6: ` 49 | font-size: 2rem; 50 | font-weight: 500; 51 | letter-spacing: 0.015rem; 52 | `, 53 | subtitle1: ` 54 | font-size: 1.6rem; 55 | font-weight: 400; 56 | letter-spacing: 0.015rem; 57 | `, 58 | subtitle2: ` 59 | font-size: 1.4rem; 60 | font-weight: 500; 61 | letter-spacing: 0.01rem; 62 | `, 63 | body1: ` 64 | font-size: 1.6rem; 65 | font-weight: 400; 66 | letter-spacing: 0.05rem; 67 | `, 68 | body2: ` 69 | font-size: 1.4rem; 70 | font-weight: 400; 71 | letter-spacing: 0.025rem; 72 | `, 73 | button: ` 74 | font-size: 1.4rem; 75 | font-weight: bold; 76 | letter-spacing: 0.0125rem; 77 | `, 78 | caption: ` 79 | font-size: 1.2rem; 80 | font-weight: 400; 81 | letter-spacing: 0.04rem; 82 | `, 83 | overline: ` 84 | font-size: 1rem; 85 | font-weight: 400; 86 | letter-spacing: 0.015rem; 87 | `, 88 | }, 89 | }; 90 | 91 | export default theme; 92 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend-workspace", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "react-scripts start", 7 | "build": "react-scripts build", 8 | "build-storybook": "build-storybook -s public", 9 | "storybook": "start-storybook -p 9009 -s public", 10 | "cypress": "cypress run", 11 | "cypress:open": "cypress open", 12 | "cypress:record": "cypress run --record --parallel", 13 | "test": "react-scripts test --coverage --verbose --env=jsdom --watchAll=false && yarn test:cypress", 14 | "test:jest": "react-scripts test --coverage --verbose --watchAll=false --env=jsdom", 15 | "test:watch": "react-scripts test --env=jsdom --coverage --verbose --watchAll=true", 16 | "test:cypress": "start-server-and-test start http://localhost:3000 cypress", 17 | "eject": "react-scripts eject", 18 | "lint:tsc": "tsc --noEmit", 19 | "lint:eslint": "eslint . --cache --ext .ts,.tsx", 20 | "lint:stylehint": "stylelint \"src/**/*.{ts,css,scss}\"", 21 | "lint": "npm-run-all --parallel -c lint:*", 22 | "fix:eslint": "eslint . --cache --fix --ext .ts,.tsx", 23 | "fix:stylehint": "stylelint \"**/*.{ts,css,scss}\" --fix", 24 | "fix": "npm-run-all --parallel -c fix:*", 25 | "precommit": "tsc --noEmit && lint-staged", 26 | "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,scss,css,md}\"" 27 | }, 28 | "dependencies": { 29 | "axios": "^0.19.0", 30 | "http-status": "^1.4.2", 31 | "immer": "^5.0.0", 32 | "react": "^16.11.0", 33 | "react-dom": "^16.11.0", 34 | "react-icons": "^3.8.0", 35 | "react-router-dom": "^5.1.2", 36 | "shortid": "^2.2.15", 37 | "styled-components": "^4.4.1", 38 | "styled-tools": "^1.7.1" 39 | }, 40 | "devDependencies": { 41 | "@babel/core": "^7.0.0-0", 42 | "@commitlint/cli": "^8.2.0", 43 | "@commitlint/config-conventional": "^8.2.0", 44 | "@cypress/webpack-preprocessor": "^4.1.1", 45 | "@storybook/addon-a11y": "^5.2.5", 46 | "@storybook/addon-actions": "^5.2.6", 47 | "@storybook/addon-info": "^5.2.6", 48 | "@storybook/addon-knobs": "^5.2.5", 49 | "@storybook/addon-links": "^5.2.6", 50 | "@storybook/addon-storysource": "^5.2.5", 51 | "@storybook/addon-viewport": "^5.2.5", 52 | "@storybook/addons": "^5.2.6", 53 | "@storybook/react": "^5.2.6", 54 | "@testing-library/jest-dom": "^5.0.0", 55 | "@testing-library/react": "^9.4.0", 56 | "@types/google-map-react": "^1.1.3", 57 | "@types/http-status": "^1.1.2", 58 | "@types/jest": "^24.0.23", 59 | "@types/node": "^12.12.14", 60 | "@types/react": "^16.9.13", 61 | "@types/react-dom": "^16.9.4", 62 | "@types/react-icons": "^3.0.0", 63 | "@types/react-router-dom": "^5.1.2", 64 | "@types/storybook__react": "^4.0.2", 65 | "@types/styled-components": "^4.4.0", 66 | "@typescript-eslint/eslint-plugin": "^2.6.1", 67 | "@typescript-eslint/parser": "^2.6.1", 68 | "babel-loader": "^8.0.6", 69 | "core-js": "^3.6.1", 70 | "cypress": "3.8.0", 71 | "dotenv-webpack": "^1.7.0", 72 | "eslint": "^6.6.0", 73 | "eslint-config-airbnb": "^18.0.1", 74 | "eslint-config-prettier": "^6.5.0", 75 | "eslint-plugin-cypress": "^2.7.0", 76 | "eslint-plugin-import": "^2.18.2", 77 | "eslint-plugin-jest": "^23.0.3", 78 | "eslint-plugin-prettier": "^3.1.1", 79 | "eslint-plugin-react": "^7.16.0", 80 | "eslint-plugin-react-hooks": "^1.7.0", 81 | "husky": "^3.1.0", 82 | "intersection-observer": "^0.7.0", 83 | "jest": "^24.9.0", 84 | "lint-staged": "^9.4.2", 85 | "npm-run-all": "^4.1.5", 86 | "prettier": "^1.19.1", 87 | "prop-types": "^15.0.0-0", 88 | "react-docgen-typescript-loader": "^3.4.0", 89 | "react-scripts": "^3.2.0", 90 | "start-server-and-test": "^1.10.7", 91 | "stylelint": "^12.0.1", 92 | "stylelint-config-recommended": "^3.0.0", 93 | "ts-jest": "^24.1.0", 94 | "ts-loader": "^6.2.1", 95 | "typescript": "^3.7.2" 96 | }, 97 | "jest": { 98 | "transform": { 99 | "^.+\\.ts(x)?$": "ts-jest" 100 | }, 101 | "collectCoverageFrom": [ 102 | "src/**/*.ts?(x)", 103 | "!src/**/style.ts", 104 | "!src/**/*.stories.tsx" 105 | ], 106 | "coverageReporters": [ 107 | "json", 108 | "lcov", 109 | "text" 110 | ] 111 | }, 112 | "browserslist": { 113 | "production": [ 114 | ">0.2%", 115 | "not dead", 116 | "not op_mini all" 117 | ], 118 | "development": [ 119 | "last 1 chrome version", 120 | "last 1 firefox version", 121 | "last 1 safari version" 122 | ] 123 | }, 124 | "lint-staged": { 125 | "*.{ts,tsx,js,jsx,json,scss,css,md}": [ 126 | "prettier --write", 127 | "git add" 128 | ], 129 | "*.{ts,tsx,js,jsx}": [ 130 | "eslint --fix", 131 | "stylelint --fix", 132 | "git add" 133 | ] 134 | }, 135 | "husky": { 136 | "hooks": { 137 | "pre-commit": "yarn precommit", 138 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 139 | } 140 | } 141 | } 142 | --------------------------------------------------------------------------------