gloriaJun / til

Lessoned Learned
3 stars 0 forks source link

history of migrate to typescript #101

Open gloriaJun opened 3 years ago

gloriaJun commented 3 years ago

TypeScript 점진적 도입하는 방법

Installation

yarn install -D  typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser 

tsconfig.json

{
  // https://gist.github.com/SeonHyungJo/f93fd203f7dc5bb3657437a1cad29c48
  "compilerOptions": {
    "baseUrl": ".",
    "outDir": "./dist",
    "paths": {
      "@*": ["./src/*"]
    },
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "commonjs",
    "sourceMap": true,
    "allowJs": true,
    "skipLibCheck": true,
    "jsx": "react",
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "strict": true,
    "noEmit": false,
    "moduleResolution": "node"
  },
  "include": ["src"],
  "exclude": ["node_modules", ".git", "dist", ".storybook/**/*.js"]
}

.eslintrc.js

module.exports = {
  env: {
    es6: true,
    browser: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:import/recommended',
    'prettier/react',
    'plugin:prettier/recommended',
  ],
  plugins: ['react', 'react-hooks', 'import', 'prettier'],
  parser: 'babel-eslint',
  parserOptions: {
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
    },
  },
  rules: {
    'prettier/prettier': 'error',

    // EsLint Rules
    'linebreak-style': ['error', 'unix'],
    'prefer-const': 'error',
    'no-var': 'error',
    'no-console': 'off',
    'no-prototype-builtins': 'off',
    'prefer-promise-reject-errors': 'off',
    camelcase: ['error', { properties: 'always' }],

    // React Rules
    'react/prop-types': 'off',
    'react/jsx-no-duplicate-props': ['error', { ignoreCase: true }],
    'react/jsx-pascal-case': [
      'error',
      {
        allowAllCaps: true,
        ignore: [],
      },
    ],
    'react/jsx-tag-spacing': ['error', { beforeSelfClosing: 'always' }],
    'react/jsx-indent-props': ['error', 2],
    'react/sort-comp': [
      2,
      {
        order: ['static-methods', 'lifecycle', '/^(on|handle).+$/', 'everything-else', 'rendering'],
        groups: {
          rendering: ['/^render.+$/', 'render'],
        },
      },
    ],
    'react-hooks/rules-of-hooks': 'error',

    'react/display-name': [0],
    // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-handler-names.md
    // 'react/jsx-handler-names': 1,

    // import Rules
    'import/first': 'error',
    'import/exports-last': 'error',
    'import/extensions': [
      'error',
      'ignorePackages',
      {
        js: 'never',
        jsx: 'never',
        ts: 'never',
        tsx: 'never',
      },
    ],
    'import/no-duplicates': 'error',
    'import/order': [
      'error',
      {
        groups: [['builtin', 'external'], 'internal', 'parent', ['sibling', 'index']],
        // comment temparary
        // 'newlines-between': 'always',
      },
    ],
    'import/newline-after-import': 'error',
    'import/group-exports': 'off',
    'import/no-self-import': 'error',
    // after fixing modify to 'error'
    'import/no-cycle': 'warn',
    'import/no-absolute-path': 'error',
    // comment temparary
    // 'import/no-internal-modules': 'error',
    'import/no-mutable-exports': 'error',
    'import/no-named-as-default-member': 'error',
    // after fixing modify to 'error'
    'import/no-named-as-default': 'warn',
    // after fixing modify to 'error'
    'import/no-named-default': 'warn',
    'import/no-named-export': 'off',
    'import/no-unresolved': ['error', { commonjs: true, caseSensitive: true }],
    'import/no-webpack-loader-syntax': 'error',
    // 'import/no-extraneous-dependencies': [
    //   'error',
    //   {
    //     devDependencies: true,
    //     optionalDependencies: true,
    //     peerDependencies: true,
    //     bundledDependencies: true,
    //   },
    // ],
  },
  settings: {
    react: {
      createClass: 'createReactClass',
      pragma: 'React', // Pragma to use, default to "React"
      version: '16.8.6', // React version, default to the latest React stable release
    },
    'import/ignore': ['node_modules'],
    'import/resolver': {
      webpack: {
        config: // webpack path,
      },
    },
  },
  overrides: [
    {
      files: ['**/*.ts', '**/*.tsx'],
      parser: '@typescript-eslint/parser',
      parserOptions: {
        tsconfigRootDir: __dirname,
        project: './tsconfig.json',
        ecmaFeatures: {
          jsx: true,
        },
        ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
        sourceType: 'module', // Allows for the use of imports
      },
      plugins: ['@typescript-eslint'],
      extends: [
        'plugin:@typescript-eslint/eslint-recommended',
        'plugin:@typescript-eslint/recommended-requiring-type-checking',
        'prettier/@typescript-eslint',
      ],
      rules: {
        '@typescript-eslint/no-unused-vars': ['error'],
        // '@typescript-eslint/explicit-module-boundary-types': 'off',
        // '@typescript-eslint/no-use-before-define': 'warn',
      },
    },
    {
      files: ['**/*.spec.js', '**/*.spec.ts', '**/.test.js', '**/.test.ts'],
      env: {
        jest: true,
        'cypress/globals': true,
      },
      extends: ['plugin:jest/recommended', 'plugin:cypress/recommended'],
      plugins: ['jest', 'cypress'],
      rules: {},
    },
    {
      files: ['*.stories.js', '*.stories.ts', '*.stories.tsx'],
      rules: {
        'import/exports-last': 'off',
        'import/no-unresolved': ['warn', { commonjs: true, caseSensitive: true }],
      },
    },
  ],
};

babelrc

{
  "presets": [
    "@babel/preset-typescript",
  ]
}

webpack

   resolve: {
    // ...SKIP...
    extensions: ['.js', '.jsx', '.json', 'css', '.ts', '.tsx'],
    // ...SKIP...
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: ['babel-loader', 'eslint-loader'],
        include: [resolve('src')],
      },
      {
        test: /\.(ts|tsx)$/,
        loader: 'ts-loader',
        include: [resolve('src')],
      },
// ...SKIP...

package.json

    "lint": "tsc --noEmit && eslint . --ext .js,.jsx,.ts,.tsx",

Trouble Shooting

Reference

gloriaJun commented 3 years ago