大規模な反応コードベースを徐々にスクリプトに移行する方法


私と私のチームが私たちが開発している大きな反応コードベースの移行について議論してきた数週間後、私たちは、その採用がプロジェクトにもたらす数々の利点のために、JavaScriptを使って書かれています.新しい機能の配達に影響を与えることなく一度にすべてを移行することは不可能であるので、徐々にそれをする戦略を見つける必要がありました.
場合は、このような状況で自分自身を見つけるとどのように私はあなたと私のチームによって採択された戦略が表示されますを続行する方法についてわからない場合は、解決策は、超簡単です!

当社のプロジェクトで使用されるツール
過去数ヶ月間、私たちはクライアントのための大きなダッシュボードを構築しています.
  • エスプリ+プリティ :  私は、どんなJavaScriptプロジェクトででも印象的なリンターを使用して、あなたがプロジェクトの完全な結婚式であると考えます.我々はairbnb いくつかのルールを持つパターンは、我々が使用するいくつかの慣例に適応.
  • プラグインのインポート   あなたが若干の点を持っているならば、このような輸入からすでに苦しみましたimport Button from ".. /.. /.. /.. /.. /components/Button;" Realogアプリケーションでは、インポートの出発点を設定することでインポートを開始することで、この問題を解決するのに役立つライブラリがすでにいくつかあります.import Button from "~/components/Button" ;
  • プラグインのインポート : この素晴らしいlibは、ユーザー定義の構成に従って、アプリケーションのすべてのインポートを整理します.アルファベット順に自分のフォルダから名前でファイルを分離することができ、自動的にカテゴリ間の行をスキップ、プロジェクト全体の一貫性を維持すること.

  • プロジェクトを移行する方法
    TypeScriptコンパイラのおかげで、維持することが可能です.js and .ts 必要に応じてプロジェクトにファイルを同時に設定しますが、上記のツールの設定はJS固有のものですので、.ts ファイルが、古いファイルのサポートを失いたくなかった.
    これを解決するために、新しいプロジェクトを作成しましたcreate-react-app TypeScriptテンプレートを使用して、この新しいプロジェクトですべてのこれらのツールを構成して、TypeScriptファイルに合うようにしました(これを行う方法をインターネットに教えるいくつかのチュートリアルがあります).
    それが完了したら、オリジナルのプロジェクトに1つずつ存在しないタイプスクリプト関連ライブラリをインストールし、TypeScriptプロジェクトのために作られたすべてのeslint構成をコピーし、タグ内に追加しましたoverrides.eslintrc.js プロジェクトファイル.下のファイルでは、完全な設定がどのようになったかを見ることができます.
    module.exports = {
      env: {
        es6: true,
        jest: true,
        browser: true,
      },
      extends: ['airbnb', 'prettier', 'prettier/react'],
      globals: {
        Atomics: 'readonly',
        SharedArrayBuffer: 'readonly',
        __DEV__: true,
      },
      parser: 'babel-eslint',
      parserOptions: {
        ecmaFeatures: {
          jsx: true,
        },
        ecmaVersion: 2018,
        sourceType: 'module',
      },
      plugins: [
        'react',
        'jsx-a11y',
        'import',
        'import-helpers',
        'react-hooks',
        'prettier',
      ],
      rules: {
        'prettier/prettier': 'error',
        'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx'] }],
        'import/prefer-default-export': 'off',
        'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
        'react/jsx-one-expression-per-line': 'off',
        'global-require': 'off',
        'react-native/no-raw-text': 'off',
        'no-param-reassign': 'off',
        'no-underscore-dangle': 'off',
        camelcase: 'off',
        'no-console': 'off',
        'react/jsx-props-no-spreading': 'off',
        'react-hooks/rules-of-hooks': 'error',
        'react-hooks/exhaustive-deps': 'error',
        'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
        'react/forbid-prop-types': 0,
        'import-helpers/order-imports': [
          'warn',
          {
            newlinesBetween: 'always', // new line between groups
            groups: [
              '/^react$/',
              'module',
              '/^@material-ui/core/',
              '/^@material-ui/icons/',
              '/^@material-ui/pickers/',
              '/^@devexpress/',
              '/^~/contexts/',
              '/^~/hooks/',
              '/^~/components/',
              '/^~/',
              ['parent', 'sibling', 'index'],
              '/styles/',
            ],
            alphabetize: { order: 'asc', ignoreCase: true },
          },
        ],
      },
      settings: {
        'import/resolver': {
          'babel-plugin-root-import': {
            rootPathSuffix: 'src',
          },
        },
      },
      //Configurations for TSX files
      overrides: [
        {
          files: ['**/*.ts', '**/*.tsx'],
          extends: [
            'plugin:react/recommended',
            'airbnb',
            'plugin:@typescript-eslint/recommended',
            'prettier/@typescript-eslint',
            'plugin:prettier/recommended',
          ],
          globals: {
            Atomics: 'readonly',
            SharedArrayBuffer: 'readonly',
          },
          parser: '@typescript-eslint/parser',
          parserOptions: {
            ecmaFeatures: {
              jsx: true,
            },
            ecmaVersion: 2018,
            sourceType: 'module',
          },
          plugins: [
            'react',
            'react-hooks',
            'import-helpers',
            '@typescript-eslint',
            'prettier',
          ],
          rules: {
            'prettier/prettier': 'error',
            'react-hooks/rules-of-hooks': 'error',
            'react-hooks/exhaustive-deps': 'warn',
            'react/jsx-filename-extension': [1, { extensions: ['.tsx'] }],
            'react/jsx-one-expression-per-line': 'off',
            'react/jsx-props-no-spreading': 'off',
            'react/jsx-curly-newline': 'off',
            'react/prop-types': 'off',
            'react/jsx-wrap-multilines': 'off',
            'import/prefer-default-export': 'off',
            'import/extensions': [
              'error',
              'ignorePackages',
              {
                ts: 'never',
                tsx: 'never',
              },
            ],
            '@typescript-eslint/explicit-function-return-type': [
              'error',
              {
                allowExpressions: true,
              },
            ],
            'import-helpers/order-imports': [
              'warn',
              {
                newlinesBetween: 'always', // new line between groups
                groups: [
                  '/^react$/',
                  'module',
                  '/^@material-ui/',
                  '/^@devexpress/',
                  '/^components/',
                  '/^routes/',
                  '/^services/',
                  '/^utils/',
                  '/^page/',
                  '/^contexts/',
                  '/^hooks/',
                  '/^layouts/',
                  ['parent', 'sibling', 'index'],
                  '/styles/',
                ],
                alphabetize: { order: 'asc', ignoreCase: true },
              },
            ],
          },
          settings: {
            'import/resolver': {
              typescript: {},
            },
          },
        },
      ],
    };
    
    上記のファイルでは、overrides タグとは、それらにのみ適用されます.ts また、.tsx ファイル!
    一旦これをするならば、あなたがそれを移行する準備ができているとき、ファイル拡張を変えることは、する必要があるすべてです.Eslintいくつかのエラーをポイントし、それらを1つずつ修正することができます.あなたが今すぐに恐れていないTypeScriptで起動している場合は、最初の日にパフォーマンスの少しを失う可能性がありますが、私はあなたがそれに慣れると、あなたの生産性は、多くが増加することを保証します!

    注目に値する点
  • デフォルトでのtypescriptは、tconfigにこれを加えるだけで、すでにファイルをインポートすることができます.JSON :"baseUrl": "./src" コンパイラのオプションの中で( jsファイルとtsファイルに対して異なるimportメソッドを使用していることを参照してください).
  • VSコードがJavaScriptファイルのルートインポートを使用する際にファイルを取得する場所を理解するためにはjsconfig.json ファイルは、TypeScriptプロジェクトでは、tsconfig.json しかし、VSコードは2つのファイルのうちの1つを受け入れるだけです.このため、私たちはそれらをクリックしてファイルにまっすぐにジャンプする可能性を失った.JSファイルですが、これは私たちの意見で非常に有効な交換でした.

  • 結論
    これは、この問題を解決するために私と私のチームによって採用された戦略であり、我々は新しい配達に影響を与えることなく、我々のアプリケーションを移行することができたので、非常にうまく働いている.
    この記事を書いている時点で、私たちのコードの約50 %が移行し、プロセスは非常に満足しています.なぜなら、私たちは、TypesScriptで直接新しい機能を実装しており、いつでも.js ファイルを入力する機会を入力します.
    私はこの話は、あなたのチームを説得するのを助けることができることを願って、はい、それは大きなCodeBaseを移動することが可能です!
    プロジェクトの成功をお祈りします.読んでくれてありがとう!
    私がこのポストであなたを手伝ったならば、Ko Fiで私にコーヒーを買うことを考えてください🙂