Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(nodecli): リファクタリング、文章の修正 #919

Merged
merged 9 commits into from
Aug 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions prh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,9 @@ rules:
- expected: ローカルサーバー
patterns:
- /ローカルサーバ(?!ー)/
- expected: ウェブブラウザ
patterns:
- Webブラウザ

# 一致とマッチ
## 一致は ===
Expand Down
2 changes: 1 addition & 1 deletion source/basic/json/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ console.log(JSON.parse(json)); // => [1, 2, 3]
与えられた文字列がJSON形式でパースできない場合は例外が投げられます。
また、実際のアプリケーションでJSONを扱うのは、外部のプログラムとデータを交換する用途がほとんどです。
外部のプログラムが送ってくるデータが常にJSONとして正しい保証はありません。
そのため、`JSON.parse`メソッドは基本的にtry...catch文で例外処理をするべきです
そのため、`JSON.parse`メソッドは基本的に`try...catch`構文で例外処理をするべきです

{{book.console}}
```js
Expand Down
8 changes: 4 additions & 4 deletions source/basic/module/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ ECMAScriptモジュールには名前付きとデフォルト以外にもいく

## ECMAScriptモジュールを実行する {#run-es-modules}

作成したECMAScriptモジュールを実行するためには、起点となるJavaScriptファイルをECMAScriptモジュールとしてWebブラウザに読み込ませる必要があります
Webブラウザは`script`タグによってJavaScriptファイルを読み込み、実行します。
次のように`script`タグに`type="module"`属性を付与すると、WebブラウザはJavaScriptファイルをECMAScriptモジュールとして読み込みます
作成したECMAScriptモジュールを実行するためには、起点となるJavaScriptファイルをECMAScriptモジュールとしてウェブブラウザに読み込ませる必要があります
ウェブブラウザは`script`タグによってJavaScriptファイルを読み込み、実行します。
次のように`script`タグに`type="module"`属性を付与すると、ウェブブラウザはJavaScriptファイルをECMAScriptモジュールとして読み込みます

```html
<!-- my-module.jsをECMAScriptモジュールとして読み込む -->
Expand All @@ -170,7 +170,7 @@ import { foo } from "./my-module.js";
`type="module"`属性が付与されない場合は通常のスクリプトとして扱われ、ECMAScriptモジュールの機能は使えません。
スクリプトとして読み込まれたJavaScriptで`import`文や`export`文を使用すると、シンタックスエラーが発生します。

Webブラウザの環境では、インポートされるモジュールの取得はネットワーク経由で解決されます。
ウェブブラウザの環境では、インポートされるモジュールの取得はネットワーク経由で解決されます。
そのため、モジュール名はJavaScriptファイルの絶対URLあるいは相対URLを指定します。
詳しくは[Todoアプリのユースケース][]を参照してください。

Expand Down
6 changes: 5 additions & 1 deletion source/use-case/ajaxapp/entrypoint/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ Webアプリケーションにおいては、常にHTMLドキュメントがエ

## プロジェクトディレクトリを作成 {#create-project-directory}

今回作成するアプリにはHTMLやJavaScriptなど複数のファイルが必要となります。そのため、まずそれらを置くためのディレクトリを作成します。
今回作成するアプリにはHTMLやJavaScriptなど複数のファイルが必要となります。
そのため、まずそれらのファイルを置くためのディレクトリを作成します。

ここでは `ajaxapp` という名前で新しいディレクトリを作成します。ここからは作成した`ajaxapp`ディレクトリ以下で作業していきます。

またこのプロジェクトで作成するファイルは、必ず文字コード(エンコーディング)を**UTF-8**、改行コードを**LF**にしてファイルを保存します。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ユースケースに文字コードと改行コードの指定を追加



## HTMLファイルの用意 {#preparing-html}

エントリポイントとして、まずは最低限の要素だけを配置したHTMLファイルを`index.html`というファイル名で作成しましょう。
Expand Down
2 changes: 1 addition & 1 deletion source/use-case/nodecli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Hello Worldアプリケーションを通じてNode.jsのCLIアプリケーシ

### [ファイルを読み込む](./read-file/README.md) {#read-file}

Node.jsのfsモジュールを使ったファイルの読み込みについて学びます
Node.jsの`fs`モジュールを使ったファイルの読み込みについて学びます

### [MarkdownをHTMLに変換する](./md-to-html/README.md) {#md-to-html}

Expand Down
86 changes: 49 additions & 37 deletions source/use-case/nodecli/argument-parse/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ description: "コマンドライン引数を受け取り、アプリケーショ
詳細は[公式ドキュメント](https://nodejs.org/dist/latest-v8.x/docs/api/process.html#process_process)を参照してください。

コマンドライン引数へのアクセスを提供するのは、`process`オブジェクトの`argv`プロパティで、文字列の配列になっています。
例として、次のように`process-argv.js`を記述します
例として、次のように`process.argv`をコンソール出力するだけの`process-argv.js`を作成します

[import process-argv.js](src/process-argv.js)
[import title:"process-argv.js"](src/process-argv.js)

このスクリプトを次のようなコマンドで実行します。

```shell-session
$ node process-argv.js one two=three four
```

すると、出力結果は次のようになります
このコマンドの実行結果は次のようになります

```
[
Expand All @@ -48,26 +48,27 @@ $ node process-argv.js one two=three four
文字列処理を自前で行うこともできますが、このような一般的な処理は既存のライブラリを使うと簡単に書けます。
今回は[commander][]というライブラリを使ってコマンドライン引数をパースします。

### commanderパッケージをインストールする {#install-commander}
### `commander`パッケージをインストールする {#install-commander}

commanderは[npm][]の`npm install`コマンドを使ってインストールできます。
まだnpmの実行環境を用意できていなければ、先に[アプリケーション開発の準備][]を参照してください。

npmでパッケージをインストールする前に、まずは`pacakge.json`というファイルを作成しましょう
npmでパッケージをインストールする前に、まずは`pacakge.json`というファイルを作成します
`package.json`とは、アプリケーションが依存するパッケージの種類やバージョンなどの情報を記録するJSON形式のファイルです。
`package.json`ファイルのひな形は、`npm init`コマンドで生成できます。
通常は対話式のプロンプトによって情報を設定しますが、ここではすべてデフォルト値で問題ないため、`--yes`オプションを付与します。
次のコマンドを実行して`pacakge.json`を作成しましょう。
通常は対話式のプロンプトによって情報を設定しますが、ここではすべてデフォルト値で`pacakge.json`を作成する`--yes`オプションを付与します。

`nodecli`のディレクトリ内で、`npm init --yes`コマンドを実行して`pacakge.json`を作成しましょう。

```shell-session
$ npm init --yes
```

生成された`package.json`ファイルは次のようになっています。

[import package.json](src/package.init.json)
[import, title:"package.json"](src/package.init.json)

`package.json`ファイルが用意できたら、`npm install`コマンドを使ってcommanderパッケージをインストールします
`package.json`ファイルが用意できたら、`npm install`コマンドを使って`commander`パッケージをインストールします
このコマンドの引数にはインストールするパッケージの名前とそのバージョンを`@`記号でつなげて指定できます。
バージョンを指定せずにインストールすれば、その時点での最新の安定版が自動的に選択されます。
次のコマンドを実行して、commanderのバージョン2.9をインストールします。[^1]
Expand All @@ -78,50 +79,59 @@ $ npm install commander@2.9

インストールが完了すると、`package.json`ファイルは次のようになっています。

[import package.json](src/package.json)
[import, title:"package.json"](src/package.json)

また、npmのバージョンが5以上であれば `package-lock.json`ファイルが生成されています。
このファイルはnpmがインストールしたパッケージの、実際のバージョンを記録するためのものです。
さきほどcommanderのバージョンは`2.9`としましたが、実際にインストールされるのは`2.9.x`に一致する最新のバージョンです。
`package-lock.json`ファイルには実際にインストールされたバージョンが記録されています。
これによって、ふたたび`npm install`を実行したときに異なるバージョンがインストールされることを防ぎます
これによって、ふたたび`npm install`を実行したときに、異なるバージョンがインストールされることを防ぎます

### CommonJSモジュール {#commonjs-module}

インストールしたcommanderパッケージを使う前に、**CommonJSモジュール**のことを知っておきましょう。
インストールした`commander`パッケージを使う前に、**CommonJSモジュール**のことを知っておきましょう。
[CommonJSモジュール][]とは、[Node.js][]環境で利用されているJavaScriptのモジュール化の仕組みです。
CommonJSモジュールは基本文法で学んだ[ES Module](../../../basic/module/README.md)の仕様が策定されるよりもずっと古くから使われています
CommonJSモジュールは基本文法で学んだ[ECMAScriptモジュール][]の仕様が策定されるより前からNode.jsで使われています
Node.jsの標準パッケージやnpmで配布されるパッケージは、CommonJSモジュールとして提供されていることがほとんどです。
先ほどインストールしたcommanderパッケージも、CommonJSモジュールとして利用できます。
先ほどインストールした`commander`パッケージも、CommonJSモジュールとして利用できます。

CommonJSモジュールはNode.jsのグローバル変数である`module`変数を使って変数や関数などをエクスポートします。
次のように`module.exports`プロパティに代入されたオブジェクトが、そのJavaScriptファイルからエクスポートされます。
複数の名前付きエクスポートが可能なES Moduleと違い、CommonJSでは`module.exports`プロパティの値だけがエクスポートの対象です。
CommonJSモジュールでは`module.exports`プロパティに代入されたオブジェクトが、そのJavaScriptファイルからエクスポートされます。
複数の名前付きエクスポートが可能なES Moduleとは異なり、CommonJSでは`module.exports`プロパティの値だけがエクスポートの対象です。

[import, commonjsExport.js](src/cjs-export.js)
次の例では、`cjs-export.js`というファイルを作成し、`module.exports`でオブジェクトをエクスポートしています。

CommonJSモジュールをインポートするには、グローバル関数である[require関数][]を使います。
次のように`require`関数にモジュール名を渡し、戻り値としてエクスポートされた値を受け取ります。
[import, title:"cjs-export.js"](src/cjs-export.js)

[import, commonjsImport.js](src/cjs-import.js)
このCommonJSモジュールをインポートするには、グローバル関数である[require関数][]を使います。
次のように`require`関数にインポートしたいモジュールのファイルパスを渡し、戻り値としてエクスポートされた値をインポートできます。
インポートするファイルパスに拡張子が必須なES Moduleとは異なり、CommonJSの`require`関数では拡張子である`.js`が省略可能です。

このユースケースで今後登場するモジュールはすべてCommonJSモジュールです。
Node.jsではES Moduleもサポートされる予定ですが、現在はまだ安定した機能としてサポートされていません。

### commanderパッケージを使う {#use-commander}
[import, title:"cjs-import.js"](src/cjs-import.js)

また、`require`関数は相対パスや絶対パス以外にもnpmでインストールしたパッケージ名を指定することもできます。
`npm install`コマンドでインストールされたパッケージは、`node_modules`というディレクトリの中に配置されています。
次のように`require`関数を使って、`node_modules`ディレクトリに配置されたcommanderパッケージを読み込みます。
`require`関数にインストールしたパッケージ名を指定することで、`node_modules`ディレクトリに配置されたパッケージを読み込めます。

次の例では、先ほどインストールした`commander`パッケージを`node_modules`ディレクトリから読み込んでいます。

```js
const program = require("commander");
```

commanderは`parse`メソッドを使ってコマンドライン引数をパースします。
このユースケースで今後登場するモジュールはすべてCommonJSモジュールです。
Node.jsではES Moduleもサポートされる予定ですが、現在はまだ安定した機能としてサポートされていません。

### `commander`パッケージを使う {#use-commander}

先ほどインストールした`commander`パッケージを使ったコマンドライン引数のパース例を見ていきます。

次の`commander-flag.js`では、コマンドライン引数の`--foo`オプションを真偽値としてパースしています。
commanderは`options`メソッドを使って、受け取りたいオプションを定義します。
オプションの定義後に、`parse`メソッドに`process.argv`を渡してコマンドライン引数をパースします。
パースした後に`opts`メソッドを呼び出すと、定義したオプションと与えられた値をオブジェクトとして取り出すことができます。
次の`commander-flag.js`では、値をもたないオプションを真偽値にパースしています。

[import commander-flag.js](src/commander-flag.js)
[import title:"commander-flag.js"](src/commander-flag.js)

このスクリプトを次のように実行すると、`--foo`オプションがパースされ、`options.foo`プロパティとして扱えるようになっています。

Expand All @@ -130,26 +140,27 @@ $ node commander-flag.js --foo
true
```

もし、次のようなエラーが表示されたときは、commanderパッケージが`node_modules`ディレクトリ内にないことを示しています。
commanderパッケージのインストールに失敗しているので、パッケージのインストールからやり直してみましょう。
もし、次のようなエラーが表示されたときは、`commander`パッケージが`node_modules`ディレクトリ内にないことを示しています。
`commander`パッケージのインストールに失敗しているので、パッケージのインストールからやり直してみましょう。

```
Error: Cannot find module 'commander'
```

値をもつオプションをパースする場合は、次の`commander-param.js`のように記述します
次の`commander-param.js`では、コマンドライン引数の`--bar`オプションに渡された値を受け取っています

[import commander-param.js](src/commander-param.js)
[import title:"commander-param.js"](src/commander-param.js)

`--foo`オプションに値を与えて実行すれば、文字列が`options.foo`プロパティにセットされていることがわかります。
`--bar`オプションに値を与えて実行すれば、文字列が`options.bar`プロパティにセットされていることがわかります。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--foo だと被るので --bar に変更してみた

`options`メソッドで、`--オプション名 <値の種類>`を定義することで、指定したオプション名に渡された値を取得できます。

```shell-session
$ node commander-param.js --foo bar
bar
$ node commander-param.js --bar "value"
value
```

このように、`process.argv`配列を直接扱うよりも、commanderのようなライブラリを使うことで簡単にコマンドライン引数を処理できます
次のセクションからは、こうして受け取ったコマンドライン引数を使って、CLIアプリケーションを作成していきます。
このように、`process.argv`配列を直接扱うよりも、commanderのようなライブラリを使うことで宣言的にコマンドライン引数を定義し処理できます
次のセクションからは、同じようにコマンドライン引数を定義し、CLIアプリケーションを作成していきます。

## このセクションのチェックリスト {#section-checklist}

Expand All @@ -165,4 +176,5 @@ bar
[Node.js]: https://nodejs.org/ja/
[require関数]: https://nodejs.org/dist/latest-v8.x/docs/api/modules.html#modules_loading_from_node_modules_folders
[アプリケーション開発の準備]: ../../setup-local-env/README.md
[ECMAScriptモジュール]: ../../../basic/module/README.md
[^1]: --saveオプションをつけてインストールしたのと同じ意味。npm 5.0.0からは--saveがデフォルトオプションとなりました。
3 changes: 2 additions & 1 deletion source/use-case/nodecli/argument-parse/src/cjs-import.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
const myModule = require("../../../../basic/module/src/myModule.js");
const myModule = require("./cjs-export");
console.log(myModule.foo); // => "foo"
4 changes: 2 additions & 2 deletions source/use-case/nodecli/argument-parse/src/commander-param.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const program = require("commander");
program.option("--foo <text>");
program.option("--bar <text>");
Copy link
Collaborator Author

@azu azu Aug 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<text> ってどういう意味なのか結局よくわかってない
type checkとかあるのかな

program.parse(process.argv);
const options = program.opts();
console.log(options.foo);
console.log(options.bar);
Loading