使ってみて便利だったnpmパッケージ6選

最近使って便利だったnpmのパッケージをまとめました。

#Surge
超簡単に静的サイトをホスティングできるパッケージです。

`npm install -g surge`でパッケージをインストールした後に`surge`と打つと、メールアドレスとパスワードを聞かれます。これらとホスティングしたいフォルダを入力するだけでデプロイが完了します。

このように、コマンド一発で作成したWebサイトを誰かにシェアしたりすることができます。

```
(base) [7:58:10] → surge                                                          workflow ~/Programs/github-actions-practice/react-app

   Running as [e-mail] (Student)

        project: /Users/suzuki/Programs/github-actions-practice/react-app/build
         domain: elegant-name.surge.sh
         upload: [====================] 100% eta: 0.0s (19 files, 515239 bytes)
            CDN: [====================] 100%

     encryption: *.surge.sh, surge.sh (390 days)
             IP: 138.197.235.123

   Success! - Published to elegant-name.surge.sh
```

https://surge.sh/

https://dotstud.io/blog/static-site-hosting-surge/

#Prettier
いわずと知れたNode.js上で動作するコードフォーマッターです。
ユーザー環境に依存することなくプロジェクト単位でコードフォーマットを統一できるため、チーム開発では必須のパッケージです。

`npm install --save-dev --save-exact prettier`でパッケージをインストールします。
そして、PrettierのPlaygroundでフォーマットのルールを作成し、表示されたJSONコードをプロジェクト直下の`.prettierrc`にコピーします。

```json
{
  "arrowParens": "always",
  "bracketSpacing": false,
  "embeddedLanguageFormatting": "auto",
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "jsxBracketSameLine": false,
  "jsxSingleQuote": false,
  "printWidth": 80,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "requirePragma": false,
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "useTabs": false,
  "vueIndentScriptAndStyle": false
}
```

次に、フォーマットを実行しないファイルを`.prettierignore`に記述します。

```
build
coverage
node_modules
package-lock.json
```

`npx prettier --check "**/*.js"`を実行すると、フォーマットが必要なファイル(.js)をチェックすることができます。

```
(base) [13:52:41] → npx prettier --check "**/*.js"                                  master ~/Programs/github-actions-practice/react-app
Checking formatting...
[warn] src/App.js
[warn] src/App.test.js
[warn] src/index.js
[warn] src/reportWebVitals.js
[warn] src/setupTests.js
[warn] Code style issues found in the above file(s). Forgot to run Prettier?
```

`npx prettier --write "**/*.js"`を実行すると、作成したルールに沿ってコードのフォーマットを行います。

```
(base) [14:02:02] → npx prettier --write "**/*.js"                                  master ~/Programs/github-actions-practice/react-app
src/App.js 46ms
src/App.test.js 11ms
src/index.js 5ms
src/reportWebVitals.js 8ms
src/setupTests.js 3ms
```

長いコマンドなので、`package.json`にコマンドを追加しておくと便利です。
これでそれぞれのコマンドを`npm run format:check`と`npm run format`で実行することができます。

```
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "format:check": "prettier --check \"**/*.{js,jsx,yml,yaml,json,css,scss,md}\"",
    "format": "prettier --write \"**/*.{js,jsx,yml,yaml,json,css,scss,md}\""
  },
```

https://prettier.io/

#semantic-release
npmパッケージのバージョン管理を行ったり、GitHubと連携することでタグやリリースノートを自動で作成してくれるパッケージです。
このパッケージを使用するにあたって、Sementic VersionとConventional Commitsの知識が必要です。

##Semantic Versioning
Semantic Versioning はバージョン番号の付け方のルールです。バージョンの大小をプログラムで判別するために、番号の付け方がルール化されています。

`Major Version`.`Minor Version`.`Patch Version`と、3つの数字をドットでつないだ番号(ex. 1.0.0, 2.1.3, 3.10.1)となっており、それぞれの数字には以下のような意味があります。

- Major Version: 後方互換性のない変更(breaking changes)のときにインクリメントする番号
- Minor Version: 後方互換性のある変更(non-breaking)のときにインクリメントする番号 
- Patch Version: バグ修正による変更のときにインクリメントする番号

https://qiita.com/usamik26/items/c8911219b610101e69a9

##Conventional Commits
Conventional Commitsはコミットメッセージの記述ルールです。変更理由が何由来(Major, Minorなど)のものであるかをコミットメッセージの先頭につけてあげることで、変更理由がひと目で分かるコミット履歴をつくることができます。

```
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
```
このルールにそってコミットメッセージを記述すると以下のようになります。

```
fix(cart): change cart endpoint

BREAKING CHANGE:changed cart endpoint #Majorアップデートとして処理

closes issue #12
```
`BREAKING CHANGE`の記述があるので、このコミットはMajorとして処理されます。Semantic Versioningのルールに従うと、`2.1.3 -> 3.0.0`のようにバージョンがあがります。

以下はその他のメッセージの例です。

```
feat(auth): added Facebook authentification #Minorアップデートとして処理 ex.) 2.1.3 -> 2.2.0
```

```
fix(auth): fixed authentification #Patchアップデートとして処理 ex.) 2.1.3 -> 2.1.4
```

```
ci: added a new workflow #普通のアップデートとして処理 ex.) 2.1.3 -> 2.1.3
```

https://www.conventionalcommits.org/en/v1.0.0/

##semantic-releaseの導入
**Conventional Commitsのルールで記述されたメッセージを分析し、Semantic Versioningのルールに沿ったバージョンで、GitHubにタグやリリースノートを作成するのがsemantic-releaseの役割となります。**

`npm install --save-dev semantic-release`でパッケージをインストールし、`release.config.js`を作成します。

```release.config.js
module.exports = {
  branches: "master", //masterにマージされたときだけ実行
  repositoryUrl: "https://github.com/suzuki0430/react-app",
  plugins: [
    "@semantic-release/commit-analyzer", //コミットメッセージを分析
    "@semantic-release/release-notes-generator", //リリースノートの作成
    "@semantic-release/github", //githubで公開
  ],
};
```
`npx semantic-release`で実行できるのですが、これはCI環境で使われるコマンドになります。
実行結果については、別途、GitHub Actionsの記事で書きます。

https://krdlab.hatenablog.com/entry/2020/01/03/163307

https://dev.classmethod.jp/articles/github-actions-semantic-release-sample/


#commit-lintとhusky
semantic-releaseでタグやリリースノートを作成するために、Conventional Commitsの記述ルールでコミットメッセージを作成する必要があるということがわかりました。

ただ、現場ではコミットするときにConventional Commitsのルールをど忘れしてしまう人も中にはいると思います。そんなときにコミットメッセージがルール通りに記述されているのかをチェックしてくれるのが`commit-lint`です。

また、コミット時に`commit-lint`を実行してくれるのが`husky`というパッケージです。

`npm install --save-dev @commitlint/config-conventional @commitlint/cli husky@v4`でパッケージをインストールします。

`package.json`に以下を追加することで、コミットする前にcommit-lintを実行してくれるようになります。

```package.json
  "husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
      "prepare-commit-msg": "exec < /dev/tty && git cz --hook || true"
    }
  },
```

`echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js`を実行して、`commitlint.config.js`を作成します。

```commitlint.config.js
module.exports = {extends: ["@commitlint/config-conventional"]};
```
これで設定完了です。

Conventional Commitsのルールに沿っていない適当なメッセージでコミットを行ってみると、以下のようなエラーが出てコミットに失敗します。

```
(base) [7:48:34] → git commit -m 'daf'
husky > commit-msg (node v10.18.1)
⧗   input: daf
✖   subject may not be empty [subject-empty]
✖   type may not be empty [type-empty]

✖   found 2 problems, 0 warnings
ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

husky > commit-msg hook failed (add --no-verify to bypass)
```

#commitizen
commit-lintとhuskyでコミットメッセージのフォーマットをチェックしてくれる仕組みを作ることができました。
次に`commitizen`というパッケージを導入して、コミットメッセージを手順に沿って作成する仕組みを導入します。

`npm install -g commitizen`でパッケージをインストールし、`commitizen init cz-conventional-changelog --save-dev --save-exact`を実行します。

`git commit`コマンドを実行すると質問がでてきます。これに答えていくだけでConventional Commitsのルールに沿ったメッセージを作成することができます。

```
(base) [7:56:36] → git commit                                                     workflow ~/Programs/github-actions-practice/react-app
husky > prepare-commit-msg (node v10.18.1)
cz-cli@4.2.3, cz-conventional-changelog@3.3.0

? Select the type of change that you're committing: fix:      A bug fix
? What is the scope of this change (e.g. component or file name): (press enter to skip) ef
? Write a short, imperative tense description of the change (max 91 chars):
 (10) fewfeature
? Provide a longer description of the change: (press enter to skip)

? Are there any breaking changes? No
? Does this change affect any open issues? No
husky > commit-msg (node v10.18.1)
[workflow 882c75f] fix(ef): fewfeature
 4 files changed, 696 insertions(+), 6 deletions(-)
 create mode 100644 commitlint.config.js
```

https://github.com/conventional-changelog/commitlint

https://github.com/typicode/husky/tree/v4

#おわりに
Prettierくらいしか知らなかったので勉強になりました。

#参考資料
https://www.udemy.com/share/102DqFCEEZd11VRno=/