タイプスクリプト物語-タイプスクリプトでNPMの上でカスタムフックを発表する方法

15336 ワード

目次:
  • NPMとは?go to canonical section
  • なぜカスタムフックを反応?go to canonical section
  • TypeScriptはどこで方程式に適合するかgo to canonical section
  • 動機づけgo to canonical section
  • TSDXと一緒に置くgo to canonical section
  • それでは試してみましょう!go to canonical section
  • フックを建てる.go to canonical section
  • アプリケーションの例go to canonical section
  • readmeファイルを追加します.go to canonical section
  • パッケージの公開go to canonical section
  • 結論go to canonical section
  • NPMとは


    NPM ノードパッケージマネージャの略で、世界最大のソフトウェアレジストリです.NPMは共有、借りるために使用され、あなたの組織にパブリックまたはプライベートできるパッケージを開発する.また、パッケージとの対話のためのコマンドラインユーティリティであり、それはNPMのない世界を想像するのは難しい.

    なぜカスタムフックを反応?


    シャープで意識的な開発者として、私たちは何度も自分自身を見つけます.我々が交差機能で同じ能力を共有する反応フックで深く潜っているならば、我々はカスタムフックを利用しなければなりません.フックは、本質的には、JavaScriptの関数です.
    独自のフックを構築すると、再利用可能な関数にコンポーネントロジックを抽出できます反応ドキュメント.

    TypeScriptはどこで方程式に適合するか


    TypeScript JavaScriptのスーパーセットであり、それはマイクロソフトによって作成され、維持されます.独自の言語として、それはJavaScriptを提供するように設計されているタイピングシステムが不足していた.これは、コンパイル時の種類の検証を提供し、任意の入力エラーがある場合、コンパイルするコードを許可しません.これは巨大なコミュニティのサポートだけではなく、“ハウツー”sとドキュメントの形式でも宣言ファイルをサポートしています.

    動機づけ


    最近では、仕事では、検証を使用してフォームを構築しました.私が働いている会社から、何十もの他の反応プロジェクトがあります、我々のチームは他のチームが同様にそれを利用することができたように、NPMパッケージとしてカスタムフックを発表するのに役に立つことができると思いました.パッケージが完全にテストされて、私たちによって維持されるので、他のチームはメンテナンスについて心配することなくパッケージの利益を楽しむことができます.プラスとして、開発者は、プル要求と貢献の形で値を生成することができます.

    TSDXと一緒に置く


    私は、バックボーンを構築することによって開始された、きれいな、eslint、typescript、rollup、冗談とカスタムフックを使用する例のアプリ.それは私が考えたほど単純でありませんでした、そして、私がどんなコードでもタイピングさえする前に、私は多くの岩を踏みました.私の目標は、構成に時間や日を費やすことではなかった.私は信頼できるが、速く動くことができたかったです.
    それから見つけたTSDX , 「あなたが簡単に最新の典型的なパッケージを開発して、テストして、公表するのを助けるゼロConfig CLI-あなたが素晴らしい新しい図書館に集中することができて、構成に関して別の午後を無駄にすることができないように」.それは、よりよく聞こえませんでした.
    TSDXはチームからの別の製品であり、Formickを構築し、多数の貢献者を持っています.輝く特徴のいくつかは、
  • あなたのコードをバンドルしますRollup また、複数のモジュール形式(CJSとESMをデフォルトで出力し、必要に応じてUMD)を加えて、開発と生産をビルドします
  • ライブリロード/ウォッチモード
  • 反応する作品
  • TSDXテストを介して賢明なデフォルトでジェストテストランナーセットアップ
  • ゼロ設定
  • それでは試してみましょう!


    ノードとNPM


    あなたのマシンにインストールされているノードとNPMの最新バージョンを持っていることを確認してください.

    パッケージ名を選択


    特に、それがカスタムフックに来るとき、名前を選ぶことは重荷でありえます.カスタムフックは名前が「use」から始まるJavaScript関数であり、他のフックを呼ぶかもしれません.あなたが「usecounter」のような何かを造りたいならば、あなたはおそらく彼らの1ダースをすでに見つけましたhttps://www.npmjs.com/ . 私は“@/usecounter”のようなものを提案します.
    しかし、我々はusecounterを構築するつもりはない.この世界にはあまりにも多くの方法があり、十分な注意を得ていない他のものがあります.
    我々は、使用するつもりですChuck Norris API ので、いくつかのチャックノリスの事実を知っている生活が良いです.
    このチュートリアルの目的はカスタムフックのビルド方法を理解することではありません.あなたがそれについて確かでないならば、見てくださいofficial documentation .

    TSDXを実行する


    次のコマンドを入力します.
    
    npx tsdx create use-norris
    
    
    端末は質問を促すでしょう、そして、我々は「反応する」を選びます

    依存関係が生成され、ボイラープレートが作成されます.

    開発を開始する
    
    cd use-norris
    
    yarn
    
    
    プロジェクトファイルツリーは次のようになります.

    注意事項


    パッケージ。JSON


    この動画はお気に入りから削除されていますpackage.json 今のところ私はname 私のパッケージ名となる値@franciscomcg/use-norris . 以下のように:
    “name”: “@franciscomcg/use-norris”
    
    NPM上での公開とGitリポジトリの作成は分離されたタスクであり、1つは別のこととは何の関係もない.我々は完全にGitを公開し、ジャンプすることができますが、私たちが知っているように、素晴らしいアイデアではありません.したがって、私は私のgitリポジトリを追加しますpackage.json :
    "repository": {
       "type": "git",
       "url": "https://github.com/FranciscoMCG/use-norris"
     },
    

    TSconfigJSON


    私にとってすべて良いです、しかし、私はあなたに”declaration”: “true” フィールド.このフィールドは対応する宣言を生成することを可能にします*.d.ts ) あなたのコードのためのファイルと我々のパッケージで彼らを出荷してください.これは私たちのユーザーがタイプ定義にアクセスするために使用されます.

    エスプリとプリティ


    パッケージはエスペルトで実行され、箱からきれいになります.両方を追加することによってカスタマイズすることができますeslintConfig and prettier ブロックpackage.json または.eslintrc.js and .prettierrc.js 設定ファイル.

    ビルフック


    私たちのフックは非常にまっすぐになると、それだけで機能をランダムにチャックノリスの事実を取得できるようにすることです.
    我々のsrc/index.tsx 次のコードに置き換えます.
    初期設定
    import { useEffect, useReducer } from 'react';
    
    interface InitialState {
     response: any;
     isLoading: boolean;
     isError: boolean;
     errorMessage: string | null;
    }
    
    enum ActionType {
     FETCH_INIT = 'FETCH_INIT',
     FETCH_SUCCESS = 'FETCH_SUCCESS',
     FETCH_FAILURE = 'FETCH_FAILURE',
     DATA_NOT_FOUND = 'DATA_NOT_FOUND',
    }
    
    const { FETCH_FAILURE, FETCH_INIT, FETCH_SUCCESS, DATA_NOT_FOUND } = ActionType;
    
    アクションの型と初期状態:
    type UseNorrisAction =
     | { type: ActionType.FETCH_SUCCESS; payload: string }
     | {
         type: ActionType.FETCH_FAILURE;
         payload: { isError: boolean; errorMessage: string | null };
       }
     | { type: ActionType.FETCH_INIT }
     | { type: ActionType.DATA_NOT_FOUND; payload: string };
    
    const initialState: InitialState = {
     response: '',
     errorMessage: null,
     isLoading: false,
     isError: false,
    };
    
    還元剤
    const useNorrisReducer = (
     state: InitialState = initialState,
     action: UseNorrisAction
    ) => {
     switch (action.type) {
       case FETCH_INIT:
         return {
           ...state,
           isLoading: true,
           isError: false,
         };
       case FETCH_SUCCESS:
         return {
           ...state,
           response: action.payload,
           isLoading: false,
           isError: false,
         };
       case FETCH_FAILURE:
         return {
           ...state,
           isLoading: false,
           isError: action.payload.isError,
           errorMessage: action.payload.errorMessage,
         };
       case DATA_NOT_FOUND:
         return {
           ...state,
           isLoading: false,
           isError: true,
           errorMessage: action.payload,
         };
       default:
         return { ...state };
     }
    };
    
    フック
    const useNorris = (initialState: InitialState) => {
     const [state, dispatch] = useReducer(useNorrisReducer, initialState);
     const { response, errorMessage, isError, isLoading } = state;
    
     useEffect(() => {
       const fetchNorris = async () => {
         dispatch({ type: FETCH_INIT });
         try {
           const res = await fetch('https://api.chucknorris.io/jokes/random');
           const json = await res.json();
    
           if (json.error) {
             dispatch({ type: DATA_NOT_FOUND, payload: json.error });
           }
           if (json.value) {
             dispatch({ type: FETCH_SUCCESS, payload: json });
           }
         } catch (error) {
           dispatch({
             type: FETCH_FAILURE,
             payload: { isError: true, errorMessage: error },
           });
         }
       };
       fetchNorris();
     }, []);
    
     return { response, errorMessage, isLoading, isError };
    };
    
    export default useNorris;
    

    フックのテスト


    カスタムフックのテストは困難な作業することができます.通常、我々はフックの様々な機能を引き起こすために反応成分を使用するでしょう.しかし、我々はコンポーネントを持っていないことが起こる.では、どうやってこの問題に取り組むのでしょうか?使いましょうreact-hooks-testing-library .
    「入力を更新して、驚くべきカスタムフックの出力を検索するためにいろいろな役に立つユーティリティ機能を提供するだけでなく、機能部品の本体の中で彼らを実行している反応フックのために単純なテストハーネスを作成することができます」
    このライブラリを使用することで、我々のフックをテストするために反応コンポーネントをレンダリングすることを避けます.

    dev依存性としてインストールします。


    (同輩の依存関係やライブラリの型であるので、レンダラをテストする必要があります).
    yarn add -D @testing-library/react-hooks react-test-renderer @types/jest @testing-library/react-hooks @testing-library/jest-dom
    
    我々がフックテストライブラリをインストールしたので、我々はファイルをtest フォルダuseNorris.test.ts を返します.
    import { renderHook } from '@testing-library/react-hooks';
    
    import useNorris from '../';
    
    const mockedValue = {
     value: 'this is a very good joke',
    };
    
    const initialState = {
     response: { value: '' },
     isLoading: false,
     errorMessage: '',
     isError: false,
    };
    
    (global.fetch as jest.Mock) = jest.fn(() =>
     Promise.resolve({
       json: () => Promise.resolve(mockedValue),
     })
    );
    
    describe('useNorris', () => {
     beforeEach(() => {
       (fetch as jest.Mock).mockClear();
     });
    
     it('should resolve', async () => {
       const { result, waitForNextUpdate } = renderHook(() =>
         useNorris(initialState)
       );
       await waitForNextUpdate();
       expect(fetch).toHaveBeenCalled();
       expect(result.current).toEqual({
         response: mockedValue,
         errorMessage: '',
         isLoading: false,
         isError: false,
       });
     });
    
     it('should return an error', async () => {
       (fetch as jest.Mock).mockImplementationOnce(() =>
         Promise.reject('There is an error')
       );
       const { result, waitForNextUpdate } = renderHook(() =>
         useNorris({
           response: { value: '' },
           isLoading: false,
           errorMessage: '',
           isError: false,
         })
       );
       await waitForNextUpdate();
       expect(fetch).toHaveBeenCalled();
       expect(result.current).toEqual({
         errorMessage: 'There is an error',
         isLoading: false,
         response: { value: '' },
         isError: true,
       });
     });
    });
    

    例アプリ


    私たちは基本的なテストを書いて、ユーザーがよりよくそれを理解することができるように、使用例を構築しなければなりません.
    フォルダの例で./index.ts 次のようになります.
    import * as React from 'react';
    
    import useNorris from '../../src';
    
    const App = () => {
     const initialState = {
       response: '',
       isLoading: false,
       isError: false,
       errorMessage: null,
     };
     const { response, isLoading, isError, errorMessage } = useNorris(
       initialState
     );
    
     if (errorMessage) {
       return <p>{errorMessage}</p>;
     }
    
     if (isError) {
       return <p>Something went wrong</p>;
     }
    
     if (isLoading) {
       return <p>Loading...</p>;
     }
    
     if (response) {
       return <p>{response.value}</p>;
     }
     return <p>Something went wrong</p>;
    };
    
    export default App;
    
    に移動example フォルダとタイプ:
    yarn start
    
    これはサーバーを起動し、我々が行くならlocalhost:1234 我々は我々のアプリを実行している!

    READMEファイルを追加する


    良い、簡潔で有意義なREADMEファイルを書くことは、非常に重要です.我々は、ユーザーが私たちが提供している機能の全体のセットを楽しむために、行ごとに、それは自分の時間の最高の使用ではないコードを検討したい.

    パッケージの発行


    TSDXでは、出版は簡単で迅速なプロセスです.
  • 登録するNPM
  • 走るyarn publish --access public 我々のパッケージをdistフォルダに束ねて、我々のフックを発表するためにNPMレジストリにアクセスしようとします.プライベートパッケージはNPMに支払われた機能であり、我々は我々のフックは誰もが利用できるようにしたい--access public フラグ.
  • CLIの指示に従って、NPMにログインし、使用するバージョンを入力する必要があります.
  • そして、それは、我々は確認メールを受け取り、私たちの驚くべきUSENORISは誰もが利用可能になりました.

    バージョン管理


    バージョン管理がパッケージの更新方法に重要な役割を果たしていることに注目してください.正しい意味のバージョン管理の後で、他の開発者がバージョン間の変化の範囲を知っていて、必要ならば調整するのを確実にするでしょう.NPM semantic versioning あなたはこのトピックについての良いアイデアを与える.

    結論


    このチュートリアルでは、我々はランダムチャックノリスジョークを取得するtypescriptとカスタムフックを構築しました.私たちはNPMの上でそれを公開しました、そして、現在、他の開発者は同様にそれを使う機会を持ちます.

    資源

  • ファイナルリポhttps://github.com/FranciscoMCG/use-norris
  • NPMパッケージhttps://www.npmjs.com/package/@franciscomcg/use-norris
  • TSDX -https://github.com/formium/tsdx
  • チャックノリスAPIhttps://api.chucknorris.io
  • フックのテストライブラリを反応させるhttps://github.com/testing-library/react-hooks-testing-library