JSDocを使ってコードの可読性を高める.

6933 ワード

四年以上働いていますが、基本的にはJavaScriptをめぐって仕事をしています.
書いたコードが多くなりました.見たコードも多くなりました.他の人が読めないコードを書くのは能力ではありません.すべての人が読めるコードを書くのが本当の牛Xです.
周知のように、JavaScriptは弱いタイプのスクリプト言語であり、これはエディタからこのコードの役割がどのようなものかを直観的に見ることができないことを意味しています.コードが本当に実行されるまでは確認できないことがあります.
したがって、大型プロジェクトのJavaScriptの維持コストが高い問題を解決するために、この間チームはType Scriptを使い始めましたが、数年前に蓄積されたコードはすぐに全部変えられるというわけではなく、この再構成は長い過程です.
再構成と同時に、元のJavaScriptプロジェクトを維持し続ける必要があります.JSDocはちょうど中間移行の方案です.注釈の形式でJavaScriptプロジェクトの維持の難しさを下げて、読み取り可能性を高めることができます.
作用
本人はvs codeエディタを使っています.jsdocに対する各種サポートを内蔵しています.また、一部の定数や文法から対応のタイプを推測しています.
簡単にエディタで効果が見られますので、以下のすべての例はvscodeに基づいています.
まず、JSDocはソースコードに対して何の影響もありません.すべての内容は注釈に書いてあります.JSDocがあなたのプログラムにどんなマイナス影響を与えるか心配する必要はありません.
まず普通のJavaScriptファイルのエディタでの展示効果を見てみてもいいです.
どのタイプの二つのパラメータが加算されてもいいので、エディタはこの関数の意味が分かりません.したがって、エディタは、Type Scriptにおいて、関数のパラメータおよび返却値を記述するために、任意のタイプのanyキーワードを識別するために使用されることが多い.
この場合、JSDocを使って、この関数の役割をマニュアルで説明するのは簡単です.
実際には手動で指定する関数があります.@return {TYPE}は関数の戻り値の種類を決定しますが、私たちの関数は2つのパラメータで加算して返しますので、エディタは関数の戻り値の種類を推定しました.
上と下の二つのコードを比べると、コードには違いがありません.コードが十分にはっきりしているという人がいるかもしれません.追加の注釈を付けて説明する必要がありません.このような盲目的な自信は普通他の人の更に悪いコードを引き継いだ後に打ち破られて、それから自分が一体何を間違えたかを反省して、このようなコードを維持しなければなりません.
あるいは、ちょっと複雑な例を出しましょう.
すっきりしていて、簡潔な例のようで、全く欠点が見えません.2つの非同期awaitを除いて、_に統合することができる.確かに、このコードがこのままプロジェクトの中に横になっても、需要を変えないなら、このコードは完璧な存在と言えます.このコードがずっとこのコードを書いている作者がメンテナンスしているのであれば、このコードはメンテナンス上もリスクがありません.
でも、いつかこのコードが引き継がれたら、他の仲間に変えてメンテナンスします.彼はいくつかの疑問があるかもしれません.
  • getUserInfoの戻り値はどんな構造ですか?
  • createOrderの戻り値は、どのような構造ですか?
  • notifyから入ってきた二つの変数はまた何をするための
  • です.
    私たちもnotify関数からいくつかのスレッドを見つけることができます.前の2つの関数が返したオブジェクトの一部の属性を確認します.これらの属性のタイプはまだ分かりません.このようなコードを維持するには、多くの脳の容量を使って記憶する必要があります.これは実際には非常に低い価格のものです.このコードを3人目に転送すると、3人目はまだ完全なプロセスを経験して、1つの関数、1つの行のコードを読んで、記憶してください.これをプログラムに対する深い理解度、業務に対する熟練度としてとらえたら、私もあなたを助けられないと思います.今スーパーで会計している時のように、N多商品の価格を覚えられるということを誇りに思います.チップガンでできることは、なぜあなたの脳を占有しますか?
    基本的な使い方
    前述のように、JSDocは注釈に書かれた特定のフォーマットの内容である.JavaScriptファイルのほとんどのマークはブロックレベル、つまり/** XXX */を使って定義されていますが、宜しければコードに記入してもいいです.
    JSDocは様々なシーンに使用される多くのマークを提供しています.しかし、すべてがよく使われているわけではありません.(また、vscodeを使ってからは、手動で指定されたマークが多く、エディタがあなたの代わりにできます.)常用するものは以下の通りです.
  • @type識別変数タイプ
  • @param識別関数パラメータタイプおよび記述
  • @return識別関数戻り値タイプおよび説明
  • 完全なリストはここでBlock tagsを見つけることができます.
    基本的に上の3つのマークを使うと、ほとんどの問題が解決できます.JSDocは書き方において特定の要求を持っています.例えば、行内でもこのような構造/** XXX */ならば、/* XXX */であれば無視されます.複数行の書き方は比較的によく使われていますが、vscodeでは直接関数の上に/**を入力してから車に戻ることができます.エディタはパラメータタイプ、パラメータ記述、関数記述の予備位置を含めて自動的に多くの内容を充填します.TABキーを使って素早く切り替えられます.
    実際には、@typeの使用周波数は他の2つよりも低い.これは、多くの場合、@typeが変数のタイプを識別するために用いられるからである.変数のソースは基本的に2つしかありません.基本タイプは2つの値を割り当てます.関数の戻り値はまず最初の基本タイプの割り当てです.これは基本的にvscodeで作ってくれます.自分で手動で指定する必要はありません.他の関数の戻り値は、関数に@returnを追加した場合、関数を呼び出して戻り値を求める変数タイプも@returnに対応するタイプに設定されます.
    タイプ
    他の二つのマークの中にはタイプに関する指定がありますので、@typeで説明してください.
    まず、JSDocでは、数字、文字列、ブール値など、すべての基本的なタイプをサポートします.
    /** @type {number} */
    /** @type {string} */
    /** @type {boolean} */
    /** @type {RegExp} */
    
    //        
    /** @type {function} */
    
    //          
    /** @type {function(number, string)} */
    
    // Object     
    /** @type {function({ arg1: number, arg2: string })} */
    
    //              
    /** @type {function(number, string): boolean} */
    上記のコメントをvscodeに入力すると、ダイナミックなヒントが得られます.
    もちろん、関数に関しては、@paramと@returnを使って実現するのがオススメです.効果はもっといいです.
    拡張複雑タイプ
    上の例は基本的なタイプの説明に基づいていますが、実際の開発過程ではこのような基本的なタイプだけがあなたのために使用されるとは言えません.大量の複雑な構造タイプの変数、パラメータ、または戻り値が必ず存在します.
    関数パラメータに関しては、JSDocの2つの方法で複雑なタイプを記述することができる.
    しかし、これは@paramにしか適用できません.また、多重性は高くないです.同じ構造の定義がいくつかあるなら、このような注釈を複数の部分にコピーする必要があります.明らかに優雅な書き方ではないです.または、他の2つのマークを使用してもいいです.@typedef@propertyは、上に述べたマークと同じフォーマットです.すべての種類を指定するところに適用できます.@typedefで定義されたタイプを使用すると、簡単に多重できます.必要なところで直接に定義されたタイプを指定すればいいです.同じように、このようなカスタムタイプは@returnに直接適用されてもよい.
    パラム
    この計算は関数パラメータの関連情報をマーキングするために重要なマークです.具体的なフォーマットはこうです.
    /**
     * @param {number} param   
     */
    function test (param) { }
    
    //         @type   (        )
    
    /**
     * @param param   
     */
    function test (/** @type number */ param) { }
    オプションのパラメータ
    パラメータがオプションのパラメータであることを表すなら、[]をパラメータ名に包んでもいいです.
    /**
     * @param {number} [param]   
     */
    function test (param) { }
    同僚は文書でもデフォルト値の書き方について言及していますが、実際にはオプションパラメータがパラメータビットでデフォルト値の処理をしている場合、追加の[]を追加して表示する必要がなくなります.
    //            
    /**
     * @param {number} [param=123]   
     */
    function test (param = 123) { }
    
    //        vscode         
    /**
     * @param param   
     */
    function test (param = 123) { }
    両者の効果は同じで、基本タイプの値を手動で指定したので、タイプの指定も省けます.パラメータの説明を簡単に定義すればいいです.
    return
    このマークは、関数の戻り値を指定するために用いられ、使用法は@paramタイプとほぼ同時に現れ、@paramとの違いは、@returnは一つしかないので、前者のようにパラメータ名を指定する必要がないということである.
    /**
     * @return {number}   
     */
    function test () { }
    Promiseタイプの戻り値処理
    この時代には、基本的にPromiseが普及していますので、多くの関数の戻り値は結果ではなく、Promiseであるかもしれません.したがって、vscodeでは、Promiseに基づいて@returnを使用して、2つの書き方が使用されてもよい.
    //      Promise              
    /**
     * @return {Promise}
     */
    function test () {
      return new Promise((res) => {
        res(1)
      })
    }
    
    //      async              @return    
    async function test () {
      return 1
    }
    
      //                    or   ,      
    async function test () {
      return returnVal()
    }
    
    /** @return {string} */
    function returnVal () {}
    結び目
    私たちの最初のコードのセグメントに戻り、JSDocバージョンを追加したように修正します.
    /**
     * @typedef   {Object} UserInfo
     * @property  {number} uid    UID
     * @property  {string} name   
     * 
     * @typedef   {Object} Order
     * @property  {number} orderId   ID
     * @property  {number} price       
     */
    async function main () {
      const uid = 1
    
      const orders = await createOrder(uid)
    
      const userInfo = await getUserInfo(uid)
    
      await notify(userInfo, orders)
    }
    
    /**
     *       
     * @param   {number} uid   UID
     * @return  {Promise}
     */
    async function getUserInfo (uid) { }
    
    /**
     *     
     * @param  {number} uid   UID
     * @return {Promise}
     */
    async function createOrder (uid) { }
    
    /**
     *     
     * @param {UserInfo} userInfo 
     * @param {Order}    orders 
     */
    async function notify (userInfo, orders) { }
    実際には何行かのテキストを追加していません.Type Scriptに切り替える前に、JSDocを使ってメンテナンスコストをある程度下げることができます.特にvscodeを使ってからマニュアルで作成する注釈は実際にはあまりありません.しかし、保護者は関数の働き、変数の種類をはっきりと見ているというメリットがあります.コードはドキュメントですまた、日常的な開発においては、エディタの自動補完、ダイナミックプロンプト機能を組み合わせることで、開発体験を高めることができると思います.
    上で紹介したのはJSDocの常用するいくつかのマークだけで、実際には更に多くの機能があります.具体的な文書の住所:jsdoc
    参考資料
  • jsdoc|@return
  • jsdoc|@param
  • jsdoc|@typedef
  • jsdoc|@property