TyesScriptへの段階的な動き.JavaScriptとPHPスクリプトのサイドバイサイドの実行


もともと投稿my personal blog .
タイプスクリプトには多くの利点があります.しかし、あなたが真新しいプロジェクトを始めていることは、しばしばありません.多くの場合、既存のコードベースで作業しているだけで、すべてからの書き換えの贅沢を持っていない.結局のところ、我々は新しい機能を提供し、迷惑なバグを修正する必要があります.
しかし、私たちは絶望するべきではありません-それは徐々にスクリプトを一度に1つのモジュールにプロジェクトを移動することが可能です-とTypeScriptとJavascriptのサイドバイサイドを実行します.

プロジェクト例


例として、単純な反応& Webpackプロジェクトを使用します.最初は、図の左側のように見えます.モジュールは2つだけです.App and JsComponent ). そして徐々に、我々は右側にJavaScriptとTypescriptコンポーネントが並んでいるでしょう画像に移動します.

タイプスクリプトへの段階的移行


そして、これらの言語を並んでおくためには、以下のようにする必要があります.
  • JavaScriptからインポートタイプスクリプトモジュール
  • JavaScriptモジュールをタイプスクリプトコードにインポート
  • 我々がそうすることができるならば、機能とバグ修正に取り組んでいる間、我々はプロジェクトをタイプスクリプトに動かすことができます.
    たとえば、新しい反応コンポーネントを追加する必要がある場合は、TypesScriptで直接書くことができます.そして、JavaScriptで書かれた他のコンポーネントの内部でも使えるようになります.

    初期のwebpackセットアップ


    モジュールバンドルとしてWebpackを使用するので、純粋なJavaScriptプロジェクトの設定を表示します.これは、我々が何を始めたか、そして、私たちがtypescript支持を可能にするために加えたものを見るのを許します.
    webpack設定.js
    const HtmlWebPackPlugin = require('html-webpack-plugin');
    const path = require('path');
    
    module.exports = (env) => ({
      entry: {
        index: ['./src/index.jsx'],
      },
      output: {
        path: path.resolve('./dist/'),
      },
      devtool: env === 'production' ? false : 'source-map',
      module: {
        rules: [
          { enforce: 'pre', test: /\.js$/, loader: 'source-map-loader' },
          {
            test: /\.(js|jsx)$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader',
            },
          },
          { test: /\.(ts|tsx)$/, loader: 'awesome-typescript-loader' },
        ],
      },
      resolve: {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
      plugins: [
        new HtmlWebPackPlugin({ template: './src/index.html' }),
      ],
    });
    
    あなたが見ることができるように、それは非常に簡単なセットアップです.主なものはbabel-loader JSXを使ったESモジュールのローディングについて.

    タイプスクリプトモジュールをJavaScript


    さて、我々は新しい反応コンポーネントを追加している機会をTypeScriptに既存のものを変換する必要があります.これは、JavaScriptのものにtypescriptモジュールをインポートする完璧な例です.
    プロジェクトに対してTypeScriptとタイプを追加することでこれを始めましょう.
    npm install --save-dev typescript @types/react
    
    次のステップはtsconfig.json プロジェクトのルートフォルダに、TypeScriptコンパイラを設定します.設定の重要な部分は以下の通りです.
  • esModuleInterop: true - 我々はそれなしで反応モジュールをインポートすることができなくなります
  • sourceMap: true - デバッグ用のソースマップを有効にする
  • TSconfigJSON
    {
      "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "es6",
        "jsx": "react",
        "esModuleInterop": true,
        "strictNullChecks": true
      },
      "include": [
        "./src/**/*"
      ],
      "rules": {
        "quotemark": [
          true,
          "single"
        ]
      }
    }
    
    このあとで、私たちのタイプスクリプトコンポーネントを書くことができます
    src/jsコンポーネント/TSコンポーネント/TSコンポーネント.TSX
    import React from 'react';
    
    interface Props {
      myProp: number;
    }
    
    const TsComponent: React.FC<Props> = ({ myProp }) => (
      <div>
        Hi, I am a TypeScript component and I accept a number prop which is {myProp}
      </div>
    );
    
    export default TsComponent;
    
    JavaScriptコンポーネントからインポートしようとすると、
    src/jsコンポーネント/jsコンポーネント.TSX
    import React from 'react';
    import TsComponent from './ts-component/ts-component';
    
    const JsComponent = () => (
      <>
        <div>Hi, I am a JavaScript component and I am calling a TypeScript component</div>
        <TsComponent myProp={123} />
      </>
    );
    
    export default JsComponent;
    
    Webpackはモジュールを解決できませんts-component/ts-component . 確かに、上記のWebPackの設定を見れば、解決するよう指示するだけです.js and *.jsx ファイル.追加.tsx そのリストに問題は解決しないbabel-loader タイプスクリプト構文を解析できません.
    幸いにも、我々はこの問題を解決することができますawesome-typescript-loader
    だから私たちは
    npm install --save-dev awesome-typescript-loader
    
    端末で次の設定を追加しますwebpack.config.js :
    webpack設定.js
      module: {
        rules: [
        // existing rules...
    
        // new TypeScript configuration
        { test: /\.(ts|tsx)$/, loader: 'awesome-typescript-loader' },
        ]
      },
      resolve: {
        // we also need to add *.tsx here
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      }
    
    今、我々はコードを実行する場合-それは完璧に動作します!
    おめでとう!我々は、既存のJavaScriptプロジェクトに最初のtypescriptモジュールを追加しました!さらに重要なことに、プロジェクト全体を書き換える必要はなかった.

    どのように、その仕事をしましたか?


    つの言語で書かれたモジュールを別のものにインポートする方法を不思議に思うかもしれませんか?特に、言語- typescript -私たちがJavaScriptにそれをインポートした言語より多くの特徴があることを考える.
    インポートされたモジュールをオンザフライでJavaScriptに変換するWebpackのローダに感謝しました.それらについてもっと読むことができますhere .
    しかし、Webpackを使用する必要がありますか?だめ!Browserifyを含むどんなモジュールバンドルも使用できます.主なものはJavaScriptにインポートされたモジュールのオンザフライの変換を可能にすることです.

    デバッグはどうですか。


    あなたはまだクロムデバッガをすることはできますか?はい、あなたはまだできます!まず第一にtsconfig.json 我々は作成したソースマップを生成するためにtypescript compilierを指示します.その後、初期webpack.config.js 既にソースマップが含まれています.クロムデバッガでは、Typescriptコードにまっすぐにステップ!

    JavaScriptモジュールのインポート


    逆の例を見てみましょう- Javascriptモジュールをタイプスクリプトにインポートします.この場合、私はサードパーティのライブラリとは対照的に独自のモジュールをインポートすることについて話していますが、いくつかのテクニックは同じです.
    また、私たちがタイプスクリプトに自身のJavaScriptモジュールを輸入することについて話しているならば、なぜ、あなたは最初にそれをしますか?あなたが大規模なJavaScriptコードベースを持っていて、あなたがtypescriptモジュールに取り組んでいるならば、あなたはJavaScriptであなたの既存の仕事を再利用しないでください.
    簡単なJavaScriptコンポーネントを追加します.
    src/tsコンポーネント/別のJSコンポーネント/別のJSコンポーネント.日本学術振興会
    import React from 'react';
    import PropTypes from 'prop-types';
    
    const AnotherJsComponent = ({ a, b }) => (
      <div>
        Hi, I am another JavaScript components. And these are my properties:
        a: {a} & b: {b}
      </div>
    );
    
    AnotherJsComponent.propTypes = {
      a: PropTypes.number.isRequired,
      b: PropTypes.string.isRequired
    };
    
    export default AnotherJsComponent;
    
    そして、それを単に私たちのtypescriptコンポーネントにインポートできます.
    src/tsコンポーネント/tsコンポーネント.TSX
    import React from 'react';
    import AnotherJsComponent from './another-js-component/another-js-component';
    
    interface Props {
      myProp: number;
    }
    
    const TsComponent: React.FC<Props> = ({ myProp }) => (
      <>
        <div>
          Hi, I amm a TypeScript component and I accept a number prop which is {myProp}
        </div>
        <AnotherJsComponent a={1} b='foo' />
      </>
    );
    
    export default TsComponent;
    
    それはすべての良いと簡単です、我々はWebPackの設定で何かを変更する必要はありません.単にJavaScriptモジュールをタイプスクリプトコードにインポートできます.
    しかし、我々は何も逃していますか?
    はい、我々はミスの安全性を行う!我々は、通過する必要があるコンポーネントのプロパティの種類を知りません.
    それを解決する方法はありますかAnotherJsComponent タイプスクリプトで?JavaScriptモジュールの実装をそのまま残しながら、独自の型定義を提供できます.
    これは、サードパーティ製のライブラリを扱うときに使用される正確なアプローチです.彼らは、それぞれ独自の型定義ファイルを持ってきます.実際、我々はすでに、我々が呼ばれるとき、反応のためにそれをしましたnpm install --save-dev @types/react .
    独自の型定義を作成するには何が必要ですか?
    まず、インポートされたモジュールと同じフォルダーにファイルを作成する必要があります.another-js-component.d.ts 次のコンテンツを配置します.
    src/tsコンポーネント/別のJSコンポーネント/別のJSコンポーネント.D . TS
    import React from 'react';
    
    interface Props {
      a: number;
      b: string;
    }
    
    declare const AnotherJsComponent: React.FC<Props>;
    
    export default AnotherJsComponent;
    

    名前変更を開始しないでください。jsファイルを.TS


    一部の移行ガイドを使用すると、名前を変更することを開始することをお勧め.js ファイル.ts . これは、JavaScriptのスーパーセットではないのですか?また、既存のJavaScriptコードは、同様のスクリプトコードであるべきではありませんか?
    まあ、それほど速くない.次のモジュールを想像してください.
    const add = (a, b) => a + b;
    
    export default add;
    
    ファイル拡張子を.ts , 私たちは、typescriptエラーを得ます.入力引数がa and b の暗黙の型any . そして、それは完全に合理的です.結局のところ、それは静的な入力を提供するためにtypescriptの主な目的です.
    今、あなたがCodeBase全体でそれをしているならば、想像してください.もちろん、設定することができます"noImplicitAny": false あなたのtsconfig.json . しかし、それはあなたが合法的なtypescriptファイルのエラーを防ぐのを助けません.

    コード


    すべてのコードが利用可能ですGitHub .

    結論

  • プロジェクトを1つのビッグバンでタイプスクリプトに動かす必要はありません
  • 代わりに、一度に1つのモジュールを移動することができます
  • それはJavaScriptとその逆のタイプスクリプトコードをインポートするのは簡単です
  • JavaScriptモジュールの周りに静的な種類を提供することができます
  • 型定義ファイルのおかげで
  • また、Webpackを使用する必要はありません.あなたが必要とするすべては、インポートされたtypescriptモジュールをjavascriptに変えることができることです