Skip to content

Latest commit

 

History

History
576 lines (385 loc) · 21.8 KB

CONTRIBUTING.md

File metadata and controls

576 lines (385 loc) · 21.8 KB

Contribution Guide

この書籍へのコントリビュート方法についてガイドです。

HonKit

この書籍はHonKitで作成されています。 また、文章はMarkdownで書かれています。Markdownの記法についてはHonKitのヘルプを参照してください。

一部、{{book.console}}やHTMLコメントを使った仕組みも含まれているため、詳しくはこのガイドで紹介します。

Issues

次のIssueを受け付けています。

その他のIssueも歓迎しています。

Pull Request

Pull Requestはいつでも歓迎しています。

受け入れるPull Request

次の種類のPull Requestを受け付けています。 基本的なPull Request(特に細かいもの)は、Issueを立てずにPull Requestを送ってもらって問題ありません。

「このような修正/改善はどうでしょう?」という疑問がある場合は、Issueを立てて相談してください。

  • 誤字の修正
  • サンプルコードやスペルの修正
  • 別の説明方法の提案や修正
  • 文章をわかりやすくするように改善
  • ウェブサイトの改善
  • テストの改善

📝 Note: Pull Requestを受け入れるとあなたの貢献がContributorsリストに追加されます。 また、Pull Requestを送った内容はこの書籍のライセンス(MIT and CC BY-NC)が適応されます。 これは、あなたの貢献がこの書籍への努力的な寄付となることを意味しています。

受け入れていないPull Request

修正の送り方

文章の誤字の修正程度なら、直接GitHub上で編集してPull Requestを送ってください。

ローカルで編集して送りたい場合は次の手順を試してください。

  1. Forkする
  2. Branchを作る: git checkout -b my-new-feature
  3. テストする: npm install && npm test
  4. 変更をコミットする: git commit -am 'feat: add some feature'
  5. Pushする: git push origin my-new-feature
  6. Pull Requestを送る :D

修正の確認方法

この書籍はHonKitで作成されています。 npm startを実行後、http://localhost:4000/へアクセスすることで、HonKitのプレビュー表示ができます。

npm run start
# open http://localhost:4000/

また、Pull Requestを出した際にNetlify上へプレビュー用のサイトが公開されます。 Pull Request下部に表示されるCI Statusからプレビュー用のサイトを見られるため、HonKit上での表示を確認できます。

CI Status

テスト

$ npm test を実行するとコードや文章に対するテストを実行できます。

npm test

$ npm run textlint の文章表現のエラーで疑問がある場合は、とりあえずそのままPull Requestを送ってください。 IssueやPull Requestでやりとりしそのエラーを直すか無視するかを決定します。

テストの種類

このプロジェクトでは次のようなテストが npm test で実行されています。 特定のSuffixを持つファイル名を対象にしているテストも存在しています。

  • HonKitのビルドテスト
  • textlintによる文章のLint
  • ESLintによるコードのLint
  • textlint + ESLintによるMarkdown中のインラインコードブロックのLint
  • Markdown中のインラインコードブロックへのDoctest
  • Mochaによる*-test.jsファイルのユニットテスト
  • *-example.jsがJavaScriptとして実行できるかのテスト
  • *-invalid.jsがJavaScriptとして実行できないかのテスト

Markdown中のインラインコードブロックとは次のようなjs言語指定がされたCodeBlockを示しています。

```js
var foo = "string";
```

textlint

CIではMarkdownの文章に対してtextlintを使ったLintが実行されます。

textlintだけのテストをしたい場合は、次のコマンドを実行してください。

npm run textlint

prhでの用語統一

prh.ymlに用語統一用の辞書が定義されています。

この辞書を使ってtextlintで用語の統一しています 辞書がおかしい場合(誤検知している場合)は、prh.ymlを修正してください。

prh.ymlの書き方については次のページを参照してください。

textlintのエラーの無視方法

次のようにHTMLコメントで、特定の範囲のtextlintエラーを無視できます。

<!-- textlint-disable -->

すべてのtextlintエラーを無視する

<!-- textlint-enable -->

できるだけ、特定のルールのエラーを無視するようにコメントを指定してください。 textlint-disable ルール名 で特定のルールのエラーだけを無視できます。

<!-- textlint-disable preset-ja-technical-writing/no-doubled-conjunction -->

二重助詞のルールのエラーだけを無視する

<!-- textlint-enable preset-ja-technical-writing/no-doubled-conjunction -->

コメントの詳細は次のページを参照してください。

Doctest

*-example.jsのJavaScriptファイルとMarkdownのインラインコードブロックを対象にDoctestが実行されます。 次のように// => 値というコメントを書いた部分が、assert関数に変換されテストされます。

const a = 42;
console.log(a); // => 42

このコードは、は次のようなテストコードに変換されます。

const assert = requite("assert");
const a = 42;
assert.strictEqual(a, 42); // => 42

これにより、サンプルコードのコメントに書いた評価結果と実際の出力が一致するかをテストしています。

詳しい実装は次のドキュメントを参照してください。

サポートする書式

評価したい式; // => 期待する評価結果

or

console.log(評価したい式); // => 期待する評価結果

基本的には、console.log(式); // => 期待する評価結果を利用します。 console.logが冗長な場合は 式; // => 期待する評価結果と書いても良いことにしています。

Doctestエラーのテスト

Doctestの正常系は実行結果と期待結果が一致することです。 一方、そのコードの実行結果がエラーになることを期待する場合もあります。 エラーを期待する場合は、doctest: 期待するエラー名をHTMLコメントに書きます。

例) 実行結果がReferenceErrorとなることを期待するテスト

条件式という変数が定義されていないためエラーとなる。

<!-- doctest: ReferenceError -->
```js
if (条件式)
    実行する文;
```

個別の行がエラーとなることを期待する場合は、正常系のDoctestでも書けるためそちらを推奨します。

```js
NO_DEFINE++; // => ReferenceError
```

複数のDoctestを扱うケースケース

デフォルトでは、コード上の全てのDoctestが実行されまで結果を待ちます。 次のコードでは、3つのassertが実行されるまでテストコードの終了を待ちます。

```js
1; // => 1
2; // => 2
3; // => 3
```

次のように条件分岐で片方のassertのみが実行されることを期待する場合は、doctest:options:{ "runMode": "any" }を指定してください。 一つでもassertが実行された時点でテストを終了します。

 <!-- doctest:options:{ "runMode": "any" } -->
```js
if (Math.random() < 0.5 ) {
    console.log(true); // => true
} else {
    console.log(false); // => false
}
```

Doctest非同期のテスト

DoctestでPromiseやAsync Functionを使った非同期のテストも書けます。

非同期処理のタイムアウトを明示的に指定したい場合はdoctest:options:{ "timeout": 1000 } をHTMLコメントに書きます。

例) 実行結果が1000ミリ秒以内に完了する非同期処理をテストする

<!-- doctest:options:{ "timeout": 1000 } -->
```js
function wait(ms){
    return new Promise((resolve) => {
        setTimeout(() => resolve(ms), ms)
    })
}
wait(1000).then(() => {
    console.log(value); // => 1000 
});
```

Note: vmモジュールの制約からタイムアウト指定の時間が正しく指定させていることが前提となっています。

DoctestのECMAScriptバージョン

DoctestはNode.jsで実行されます。 実行するNode.jsがECMAScriptの最新のバージョンをサポートしていない場合があります。 そのため、コードのECMAScriptバージョンを指定することで、そのDoctestをスキップできます。

例) DoctestがECMAScript 2019であることを表記する

<!-- doctest:meta:{ "ECMAScript": "2019" } -->
```js
[1,[2], [3]].flat();
```

DoctestでサポートしてないECMAScriptバージョンのテストは実行されません。

Doctestの無視

CodeBlockの手前に<!-- doctest:disable -->というHTMLコメントがある場合はDoctestをしません。 Node.jsで実行できないビルドインオブジェクトを使うパターンや例外的なケースに利用できます。

例) 無視するケース

次の例はAPIの説明のための擬似コードであるため無視しています。

<!-- doctest:disable -->
```js
array.map(コールバック関数);
```

別の手法:

ファイル名が*-invalid.jsのコードは実行できないことを検証できます。(エラーになるとテストが通る) これを[include]することでより正確に表現できます。

  • *-invalid.jsがJavaScriptとして実行できないかのテスト

関連

ディレクトリ構造

source 下に章や節ごとにディレクトリを切り、 その下にコード(src/)、テスト(test/)、リソース(img/)などを配置して扱います。

└── source
    └── ch1
        ├── basic
        │   └── README.md
        ├── comments
        │   ├── README.md
        │   └── src
        │       └── html-like-comments-example.js
        └── hello
            ├── README.md
            ├── img
            ├── src
            │   └── hello-world.js
            └── test
                └── hello-world-test.js

コミットメッセージ規約

AngularのGit Commit Guidelinesをベースとしています。

以下のような形で

  • 1行目に概要
  • 2行目は空行
  • 3行目から本文

最後に関連するIssue(任意)を書きます。 fix #<issue番号> のように書くことで、PRをマージした時に自動的にIssueを閉じることができます。

feat(ngInclude): add template url parameter to events

The `src` (i.e. the url of the template to load) is now provided to the
`$includeContentRequested`, `$includeContentLoaded` and `$includeContentError`
events.

Closes #8453
Closes #8454
                         scope        commit title

        commit type       /                /      
                \        |                |
                 feat(ngInclude): add template url parameter to events

        body ->  The 'src` (i.e. the url of the template to load) is now provided to the
                 `$includeContentRequested`, `$includeContentLoaded` and `$includeContentError`
                 events.

 referenced  ->  Closes #8453
 issues          Closes #8454

commit type としては次のようなものがあります。

  • feat
    • 新しい機能、章、節の追加など
    • 更新履歴に載るような新しいページを追加
  • fix
    • 意味が変わる修正
    • 更新履歴に載るような修正
  • docs
    • 基本的には使わない
    • README.mdやCONTRIBUTING.mdや本体のプロジェクト全体のドキュメントについて
  • refactor
    • 意味が変わらない修正
    • 更新履歴に載らないような修正
  • style
    • スペースやインデントの調整
    • Lintエラーの修正など
  • perf
    • パフォーマンス改善
  • test
    • テストに関して
  • chore
    • その他
    • typoの修正など

commit typeは、迷ったらとりあえずchoreと書きます。 scopeも省略して問題ないので以下のような形でも問題ありません。

chore: コミットメッセージ

書き方の色々

書き方に関するルールや表記統一について

「次の」 or 「下記の」 or 「以下の」

出版される書籍では、版組などの関係から「下」に書いた文章が右や次のページに表示されることがある。 そのため、基本的に「次の」を利用する。

文章に対する相対的な位置の指し示す場合は、 できるかぎり「次のコード」というように事前に説明する。

読んでいる人がサンプルコードのどこに注目すればいいかが、事前にわかるように書いてからコードを説明する。 そのため、多くのケースでは「前」よりも「次」を優先して利用する。


次のコードは xxx について説明しています。

code

「上記」も同じ理由でできるだけ避ける。 「先ほど」や「その結果」といったように説明した直後を参照する言葉を使う。

文章との距離が離れている場合(章をまたぐ場合)は、リンクとして参照する。 詳細は、章へのリンクを参照。

コードの参照方法

事前に説明した特定のコードを参照したい場合は、 サンプルコードのファイル名を参照に利用する。

[import, example.js](src/example.js)

色々文章...

[example.js](#example.js)では、 ....

コードのコンソールモード

次の変数をコードブロックの前に書くことで、コードがインタラクティブに実行できるコンソールモードとして表示されます。 (ウェブのみ)

{{book.console}}
```js
var interactive = "code";
```

importしたコードにも対応しています。

{{book.console}}
[import, example.js](src/example.js)

コードのエディタ/HTMLプレビューモード

honkit-plugin-sandpackを使ったCodeSandboxのコードエディタ埋め込みに対応しています。

HTMLコメントで、JSやHTMLを読み込むエディタとプレビューを埋め込めます。

  • isOpen:true の場合は、エディタが最初から表示されます
  • isOpen:false の場合は、実行ボタンを押すまで表示はされません
  • Note: いくつかの問題点があるので回避策を追加して使う場合があります
    • loadイベントは正しく発生しない → window.dispatchEventで手動で発火させる
    • headのCSSは無視される → CSSが読まれないので、appendCodeなどで手動でCSSを追加する

次のように、<!-- sandpack:{/*options*/} --> のコメントを書いた場所に埋め込まれます。

<!-- sandpack:{
  "files": {
    "/src/index.js": {
      "path": "example/index.js"
    },
    "/index.html": {
      "path": "example/index.html"
    }
  },
  "entry": "/src/index.js",
  "main": "/src/index.js",
  "environment": "static",
  "template": "vanilla",
  "options": {
    "showLineNumbers": true,
    "editorHeight": 550
  },
  "honkitSettings": {
    "isOpen": true,
    "hideExitButton": true
  }
} -->

ES6 or ES2015

ES2015は正式な名称ですが、ES6も一般によく使われている名称です。 どちらの表記をメインに利用するかは以下のIssueで議論した結果、ES2015という表記をメインとしています。 これから出てくる仕様はES2016、ES2017と年号形式であるためそちらに揃えていこうという形です。

現在のECMAScriptバージョンを参照するとき

この書籍では"最新版のECMAScript"という定義は変更される場合があります。 2017年においてはECMAScript 2017ですが、2018年では異なります。

そのため、現在のECMAScriptバージョンを扱うときは{{book.esversion}}という変数を利用します。

現在のECMAScriptの最新版はECMAScript {{book.esversion}}です。

この変数はbook.jsonに定義されています。

var vs. let/const

基本的にコードではletまたはconstを利用します。 varの機能を説明する場合においてはvarを利用します。

章へのリンク

別の章へのリンクを書くときは「[章のタイトル][]」の章という形でリンクする。 章の途中の場合は「[章のタイトル][]」の[#付きのリンク][]という形にする。

真偽値へ変換した結果が`true`となる値の種類は多いため、逆に変換した結果が`false`となる値を覚えるのが簡単です。JavaScriptでは次の値は`false`に変換され、これらの値は**falsy** と呼ばれます。(「[暗黙的な型変換][]」の章を参照)

リリースフロー

次の2種類のリリースフローが存在する。

  • ウェブ版
  • 書籍版

ウェブ版

変更予定を事前にIssueを作り、対応箇所をまとめる。

毎年のECMAScriptの対応が終わったらメジャーバージョンをアップデートし、リリースノートに変更点をまとめる。

リリースが終わったら、変更点にリリースノートへのリンクを追加する

書籍版

書籍版の差分を変更点に追加する。