From 7afdb6b20ad136919fdfaaf8bb9b97810440db8c Mon Sep 17 00:00:00 2001 From: Gilevich Petr Date: Tue, 4 Aug 2020 16:12:40 +0300 Subject: [PATCH] Typescript and eslint settings and transpilled AddingButton component (#327) * AddingButton converted, added ts supporting to webpack added ts supporting to eslint * Updated less-module import --- .babelrc | 1 + .creevey/SCREENSHOT_TESTS.md | 2 +- .eslintrc.json | 36 ++++------ package.json | 49 +++++++------ .../{AddingButton.jsx => AddingButton.tsx} | 9 ++- src/types/less-modules.d.ts | 6 ++ tsconfig.json | 70 +++++++++++++++++++ webpack.config.js | 8 +-- 8 files changed, 127 insertions(+), 54 deletions(-) rename src/Components/AddingButton/{AddingButton.jsx => AddingButton.tsx} (65%) create mode 100644 src/types/less-modules.d.ts create mode 100644 tsconfig.json diff --git a/.babelrc b/.babelrc index a9d31debf..8c73c0bea 100644 --- a/.babelrc +++ b/.babelrc @@ -13,6 +13,7 @@ "modules": false } ], + "@babel/typescript", "@babel/preset-react" ], "env": { diff --git a/.creevey/SCREENSHOT_TESTS.md b/.creevey/SCREENSHOT_TESTS.md index 8f03545eb..7a5f14001 100644 --- a/.creevey/SCREENSHOT_TESTS.md +++ b/.creevey/SCREENSHOT_TESTS.md @@ -5,7 +5,7 @@ 1) Register on `https://www.browserstack.com/`. 2) Go to instruction page `https://www.browserstack.com/automate/node`, where you find user, key and other configs. 3) Download BrowserStackLocal. -4) Create file authConfig.json into `web2.0/.creevey` directory and with content: +4) Create file auth.config.json into `web2.0/.creevey` directory and with content: ```json { diff --git a/.eslintrc.json b/.eslintrc.json index 508d708d5..274746477 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,24 +1,26 @@ { - "parser": "babel-eslint", + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "./tsconfig.json", + "ecmaFeatures": { + "jsx": true + } + }, "env": { "browser": true, "node": true, "es6": true, "jest": true }, - "parserOptions": { - "ecmaFeatures": { - "jsx": true - } - }, "extends": [ - "airbnb", - "plugin:flowtype/recommended", + "eslint:recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", "prettier", "prettier/react", - "prettier/flowtype" + "prettier/@typescript-eslint" ], - "plugins": ["babel", "flowtype", "prettier", "react-hooks"], + "plugins": ["@typescript-eslint", "prettier", "react-hooks"], "rules": { "prettier/prettier": "error", "react/sort-comp": [ @@ -39,18 +41,6 @@ "react/require-default-props": "off", "react/prop-types": "off", "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks - "react-hooks/exhaustive-deps": "warn", // Checks effect dependencies - "react/state-in-constructor": "off", - "react/jsx-props-no-spreading": "off", - "react/static-property-placement": "off", - "camelcase": "off", - "max-classes-per-file": "off", - "react/no-unescaped-entities": "off", - "eqeqeq": [2, "allow-null"] - }, - "settings": { - "flowtype": { - "onlyFilesWithFlowAnnotation": true - } + "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies } } diff --git a/package.json b/package.json index 71596bd4e..6c4cdd3c2 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "storybook": "cross-env NODE_ENV=development start-storybook -p 9001 -c .storybook --ci", "fakeapi": "json-server --watch fakeapi/db.json --routes fakeapi/routes.json --port 9002", "start": "npm-run-all --parallel serve fakeapi", - "lint": "eslint --ext .jsx --ext .js src/", + "lint": "eslint --ext .tsx --ext .ts src/", "test": "cross-env NODE_ENV=testing jest \"./src\"", "prettier": "prettier \"./src/**/*.js\"", "creevey": "wait-on http://localhost:9001 -t 60000 && node ./.creevey/start.js -c ./.creevey/creevey.config.js", @@ -53,48 +53,55 @@ "@babel/preset-env": "7.9.5", "@babel/preset-flow": "7.9.0", "@babel/preset-react": "7.9.4", + "@babel/preset-typescript": "^7.10.4", "@babel/register": "7.9.0", "@hot-loader/react-dom": "16.13.0", "@storybook/addon-actions": "^5.3.17", "@storybook/addons": "^5.3.17", "@storybook/react": "^5.3.17", + "@types/classnames": "^2.2.10", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", + "@types/react-router-dom": "^5.1.5", + "@typescript-eslint/eslint-plugin": "^3.7.0", + "@typescript-eslint/parser": "^3.7.0", "aws-sdk": "^2.649.0", "babel-eslint": "10.1.0", "babel-loader": "8.0.5", "babel-plugin-module-resolver": "^4.0.0", - "classnames": "2.2.6", - "classnames-loader": "2.1.0", + "classnames": "^2.2.6", + "classnames-loader": "^2.1.0", "creevey": "0.5.7", "cross-env": "5.2.0", - "css-loader": "2.1.1", - "eslint": "7.2.0", - "eslint-config-airbnb": "18.1.0", - "eslint-config-prettier": "6.11.0", + "css-loader": "^4.0.0", + "eslint": "^7.5.0", + "eslint-config-prettier": "4.1.0", "eslint-plugin-babel": "5.3.0", "eslint-plugin-flowtype": "3.4.2", - "eslint-plugin-import": "2.21.1", - "eslint-plugin-jsx-a11y": "6.2.3", - "eslint-plugin-prettier": "3.1.3", - "eslint-plugin-react": "7.20.0", - "eslint-plugin-react-hooks": "4.0.4", - "file-loader": "3.0.1", + "eslint-plugin-import": "^2.22.0", + "eslint-plugin-jsx-a11y": "6.2.1", + "eslint-plugin-prettier": "3.0.1", + "eslint-plugin-react": "^7.20.3", + "eslint-plugin-react-hooks": "^2.5.0", + "file-loader": "^6.0.0", "flow-bin": "0.95.1", "flow-coverage-report": "0.6.1", "html-webpack-plugin": "3.2.0", "json-server": "0.14.2", - "less": "3.9.0", - "less-loader": "4.1.0", - "mini-css-extract-plugin": "0.5.0", + "less": "^3.12.2", + "less-loader": "^6.2.0", + "mini-css-extract-plugin": "^0.9.0", "mockdate": "3.0.2", "prettier": "1.16.4", "regenerator-runtime": "^0.13.5", "selenium-webdriver": "^4.0.0-alpha.7", "storybook-react-router": "1.0.3", - "style-loader": "0.23.1", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", "wait-on": "^4.0.1", - "webpack": "4.29.6", - "webpack-bundle-analyzer": "3.6.1", - "webpack-cli": "3.3.0", - "webpack-dev-server": "3.2.1" + "webpack": "^4.44.0", + "webpack-bundle-analyzer": "^3.8.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" } } diff --git a/src/Components/AddingButton/AddingButton.jsx b/src/Components/AddingButton/AddingButton.tsx similarity index 65% rename from src/Components/AddingButton/AddingButton.jsx rename to src/Components/AddingButton/AddingButton.tsx index 4dbf0f01f..3594561ad 100644 --- a/src/Components/AddingButton/AddingButton.jsx +++ b/src/Components/AddingButton/AddingButton.tsx @@ -1,13 +1,12 @@ -// @flow import * as React from "react"; import { Link } from "react-router-dom"; import cn from "./AddingButton.less"; -type Props = {| - to: string, -|}; +interface IAddingButtonProps { + to: string; +} -export default function AddingButton(props: Props): React.Node { +export default function AddingButton(props: IAddingButtonProps): React.ReactNode { const { to } = props; return ( diff --git a/src/types/less-modules.d.ts b/src/types/less-modules.d.ts new file mode 100644 index 000000000..92d67e0ba --- /dev/null +++ b/src/types/less-modules.d.ts @@ -0,0 +1,6 @@ +declare module "*.less" { + // eslint-disable-next-line prettier/prettier + type CssModules = classNames | ((name: string) => string); + declare const less = CssModules; + export default less; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..49465b185 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,70 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + "noUnusedLocals": true, /* Report errors on unused locals. */ + "noUnusedParameters": true, /* Report errors on unused parameters. */ + "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + // "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "skipLibCheck": true, /* Skip type checking of declaration files. */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + }, + "includes": ["./src/types/less-modules.d.ts"] +} diff --git a/webpack.config.js b/webpack.config.js index d721485ab..c93d59144 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,7 +3,7 @@ const webpack = require("webpack"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const ContextReplacementPlugin = webpack.ContextReplacementPlugin; -const supportedLocales = ['en'] +const supportedLocales = ['en']; module.exports = { entry: { @@ -28,7 +28,7 @@ module.exports = { }, }, { - test: /\.jsx?$/, + test: [/\.jsx?$/, /\.tsx?$/], use: ["babel-loader"], exclude: /node_modules/, include: [ @@ -65,7 +65,7 @@ module.exports = { }, resolve: { modules: ["node_modules", "local_modules"], - extensions: [".js", ".jsx"], + extensions: [".js", ".jsx", ".ts", ".tsx"], alias: process.argv.includes("--mode=development") ? {"react-dom": "@hot-loader/react-dom" } : undefined @@ -73,7 +73,7 @@ module.exports = { devtool: "cheap-source-map", plugins: [ new ContextReplacementPlugin( - /date\-fns[\/\\]/, + /date-fns[\/\\]/, new RegExp(`[/\\\\\](${supportedLocales.join("|")})[/\\\\\]`) ), new HtmlWebpackPlugin({