HAKASHUN / manabi

manabi
14 stars 1 forks source link

AngularJSプロジェクトにおけるngdoc・jsdocルール案 #65

Open HAKASHUN opened 9 years ago

HAKASHUN commented 9 years ago

ポイント

  1. 必ず書かないと行けないことを定義する
    • angular/materialが、丁寧すぎず、アノテーションもしっかりと書いているので、最も参考することとなった。
  2. どうやって書くかを確認する
  3. どうすれば楽に書けるかを考える

    文献

HAKASHUN commented 9 years ago

必ずなルール

/** ... */で囲まなければならない

記法スタイルを統一しなければならない

基本

/**
 * ここに名前
 * @param {number} [num] 数字。
 * @return {string} 文字列。
 */
function hoge(num) { ...

AngularJS本体とあわせる

/**
 * @ngdoc service
 * @name $window
 *
 * @description
 * A reference to the browser's `window` object. While `window`
 * is globally available in JavaScript, it causes testability problems, because
 * it is a global variable. In angular we always refer to it through the
 * `$window` service, so it may be overridden, removed or mocked for testing.
 *
 * Expressions, like the one defined for the `ngClick` directive in the example
 * below, are evaluated with respect to the current scope.  Therefore, there is
 * no risk of inadvertently coding in a dependency on a global value in such an
 * expression.
 *
 * @example
   <example module="windowExample">
     <file name="index.html">
       <script>
         angular.module('windowExample', [])
           .controller('ExampleController', ['$scope', '$window', function($scope, $window) {
             $scope.greeting = 'Hello, World!';
             $scope.doGreeting = function(greeting) {
               $window.alert(greeting);
             };
           }]);
       </script>
       <div ng-controller="ExampleController">
         <input type="text" ng-model="greeting" />
         <button ng-click="doGreeting(greeting)">ALERT</button>
       </div>
     </file>
     <file name="protractor.js" type="protractor">
      it('should display the greeting in the input box', function() {
       element(by.model('greeting')).sendKeys('Hello, E2E Tests');
       // If we click the button it will block the test runner
       // element(':button').click();
      });
     </file>
   </example>
 */

参考文献

HAKASHUN commented 9 years ago

@ngdoc

AngularJSのソースでは以下が使われています。

Angular Materialのソースでは以下が使われています。

Angular MaterialではAngular本体と比べて、docを書きすぎないようにしているのか、アノテーションの範囲が少ない感じでした。

上記6つに絞ったルールでよいかもしれません。

HAKASHUN commented 9 years ago

@name

with @ngdoc module

/**
 * @ngdoc module
 * @name material.services.theming

 ...

angular.module('material.services.theming', []);

with @ngdoc directive

/**
 * @ngdoc directive
 * @name mdSubheader

...

Module.directive('mdSubheader', [])

with @ngdoc service

/**
 * @ngdoc service
 * @name $mdToast

...

Module.factory('$mdToast', [])

with @ngdoc provider

/**
 * @ngdoc provider
 * @name $controllerProvider

...

Module.provider('$controllerProvider', [])

with @ngdoc filter

/**
 * @ngdoc filter
 * @name orderBy

...

Module.filter('orderBy', [])

Ex. orderBy.js

with @ngdoc object

constant
/**
 * @ngdoc object
 * @name $ionicLoadingConfig

...

Module.constant('$ionicLoadingConfig', {
  template: '<i class="icon ion-loading-d"></i>'
});
config
/**
 * @ngdoc object
 * @name sample.config

...

angular.module('sample').config([function(){}]);
controller
/**
 * @ngdoc object
 * @name mdSidenavController

...

function mdSidenavController($scope, $element...

Module.controller('mdSidenavController', mdSidenavController);

Ex. sidenav.js

HAKASHUN commented 9 years ago

@description

used to provide a description of a component in markdown Writing-AngularJS-Documentation

jsDocでは、htmlを用いてdescriptionを書くこともありますが、AngularJSプロジェクトでは、Markdownによって記載することが多いです。

/**

...

 * @description
 * The `<md-card>` directive is a container element used within `<md-content>` containers.
 *
 * Cards have constant width and variable heights; where the maximum height is limited to what can
 * fit within a single view on a platform, but it can temporarily expand as needed

...

 */
HAKASHUN commented 9 years ago

@module

/**
 * @ngdoc module
 * @name material.components.sidenav
 *
 * @description
 * A Sidenav QP component.
 */
var Module = angular.module('material.components.sidenav', []);

/*
 * @ngdoc object
 * @name mdSidenavController
 * @module material.components.sidenav
 *
 * @description
 * The controller for mdSidenav components.
 */

...

Module.controller('mdSidenavController', mdSidenavController)
HAKASHUN commented 9 years ago

@param

基本の型

@param {type} name description

typeのパターン

AngularJS Angular Material ionic
string string string
boolean boolean boolean
Function function function / Function
number number number
Object object object/Object
DOMElement /Element el HTMLElement
expression expression expression
Error 使用箇所なし 使用箇所なし
RegExp 使用箇所なし 使用箇所なし
Array 使用箇所なし 使用箇所なし
DOMEvent
int
Promise/promise

typeの表現を以下に決めてみた

type
string
boolean
Function
number
Object
DOMElement
expression
Error
RegExp
Array
Promise

色々探したところだとこれが一番まとまっているかも?

http://www38.atwiki.jp/aias-jsstyleguide2/pages/17.html#id_6f37ee9a

その他のTips

複数の型を指定したいとき

@param {string|DOMElement}

絶対にnullでない値であることを指定したいとき

@param {!Object}

省略可能な値(undefinedを許す)であることを指定したいとき

@param {Object=}

nullとundefinedを意識した型定義

/** 
 * 4つの引数を取ります。そのうち2つはnullを許容し、2つは省略可能です。 
 * @param {!Object} nonNull 必須(undefinedは不可)、nullは不可。 
 * @param {Object} mayBeNull 必須(undefinedは不可)、nullでもよい。 
 * @param {!Object=} opt_nonNull 省略可 (undefinedでもよい)、しかし値があるなら、 
 *     それはnullであってはならない! 
 * @param {Object=} opt_mayBeNull 省略可 (undefinedでもよい)、nullでもよい。 
 */
function strangeButTrue(nonNull, mayBeNull, opt_nonNull, opt_mayBeNull) { 
 // ... 
};
HAKASHUN commented 9 years ago

@returns

基本の型

@returns {type} description

Tips

どの型が返るかわからないとき

@returns {*}
HAKASHUN commented 9 years ago

@restrict(@ngdoc directive時のみ)

@restrict E
HAKASHUN commented 9 years ago

ルールまとめ

アノテーションで必ず意識するべきアノテーション7選

  1. @ngdoc
  2. @name
  3. @module
  4. @description
  5. @restrict
  6. @param
  7. @returns

@ngdoc タイプ別のアノテーション

@ngdoc @name @module @description @restrict @param @returns
module × × × ×
directive ×
service ×
provider × ×
filter ×
object × × ×

これ以外のアノテーション