手早く Node.js の検証用リポジトリを作成する

JavaScript の新しい技術やアイデアを試す時のリポジトリを作成するワークフローについて書きます。快適な作業環境を手早く作ることを目指します。

## プロジェクトを開始する

プロジェクトフォルダを作って、 Git での管理を開始しましょう。

```shell
$ mkdir sandbox-something
$ git init
$ git create
```

`git create`は [GitHub Hub](https://github.com/github/hub) という Git の GitHub 拡張ツールが提供するコマンドです。 この場合、 `<usernname>/sandbox-something` というリポジトリを [github.com](https://github.com) に作成し、ローカルリポジトリに remote を登録してくれます。

```shell
$ git remote -v
origin	git@github.com:<usernname>/sandbox-something.git (fetch)
origin	git@github.com:<usernname>/sandbox-something.git (push)
```

## .gitignore を作成

プロジェクト固有の自動生成ファイルなどはぼちぼち .gitignore に追加していくとして、 一般的な .gitignore を [gibo](https://github.com/simonwhitaker/gibo) で生成します。gibo コマンドは、 node をはじめ主要な言語・フレームワークに対応した汎用的な .gitignore を標準出力に渡してくれます。

```shell
$ gibo node > .gitignore
```

## npm にする

npm としてリポジトリを初期化します。今回は [Yarn](https://yarnpkg.com/ja/) を使います。細かい点ですが、 `yarn init` コマンドに先立って `git create` してリモートリポジトリを登録しておくことで、 package.json の repository フィールドを埋めてくれるので気持ちいいです。

```shell
$ yarn init -y
yarn init v1.10.1
warning The yes flag has been set. This will automatically answer yes to all questions, which may have security implications.
success Saved package.json
✨  Done in 0.06s.
```

```shell
$ cat ./package.json
{
  "name": "sandbox-something",
  "version": "1.0.0",
  "main": "index.js",
  "repository": "git@github.com:<usernname>/sandbox-something.git",
  "author": "<usernname>",
  "license": "MIT"
}
```

## Linter とコードフォーマッターを導入する

[ESLint](https://eslint.org/) と [Prettier](https://prettier.io/) を導入します。　

```shell
$ yarn add eslint babel-eslint prettier-eslint prettier-eslint-cli --dev
```

Prettier はエディタープラグインを使って、ファイル保存時に自動でフォーマットされるようにしておくのがおすすめです。

[VSCode プラグイン](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
[Atom パッケージ](https://atom.io/packages/prettier-atom)
[webStorm プラグイン](https://prettier.io/docs/en/webstorm.html#running-prettier-on-save-using-file-watcher)

phpStorm （webStorm） の場合でも、 File Watcher との組み合わせで保存時にフォーマットを実行できます。

ESLint と Prettier の設定は、 ESLint　の新しいルールの追加やプロジェクトの性質に応じてよく変更するので、 最近アクティブだった別のプロジェクトから持ってきて、項目を適当に削ったり足したりします。使い回しを追求するならば、Gist や GitHub に置いておくか、 コンフィグを npm パッケージとして作成し公開しておくといいかもしれません[^1]。

```shell
$ cp ~/prev-project/.eslint* ./
$ cp ~/prev-project/.prettier* ./
```

参考までに、私がよく使う設定をはいつもこんな感じになります。

```config
# .eslintignore
/node_modules
/dist
/docs
```

```javascript
// .eslint.js
module.exports = {
  env: {
    es6: true,
    node: true,
  },
  extends: ['eslint:recommended'],
  parser: 'babel-eslint',
  parserOptions: {
    ecmaVersion: 2017,
    sourceType: 'module',
    ecmaFeatures: {
      experimentalObjectRestSpread: true,
    },
  },
  rules: {
    'array-callback-return': ['error'],
    'quote-props': ['error', 'as-needed'],
    'arrow-parens': ['error', 'as-needed'],
    'arrow-spacing': ['error', { before: true, after: true }],
    'brace-style': ['error', '1tbs', { allowSingleLine: true }],
    'comma-spacing': ['error', { before: false, after: true }],
    'comma-dangle': [
      'error',
      {
        arrays: 'always-multiline',
        objects: 'always-multiline',
        imports: 'always-multiline',
        exports: 'always-multiline',
        functions: 'always-multiline',
      },
    ],
    eqeqeq: ['error', 'always'],
    indent: ['error', 2, { SwitchCase: 1 }],
    'jsx-quotes': ['error', 'prefer-double'],
    'valid-jsdoc': ['off'],
    'key-spacing': ['off'],
    'keyword-spacing': ['error'],
    'linebreak-style': ['error', 'unix'],
    'no-dupe-args': ['error'],
    'no-console': ['warn'],
    'no-const-assign': ['error'],
    'no-irregular-whitespace': [
      'error',
      {
        skipStrings: true,
        skipComments: true,
        skipRegExps: true,
        skipTemplates: true,
      },
    ],
    'no-unused-vars': ['error'],
    'no-undefined': ['error'],
    'no-var': ['error'],
    'no-multiple-empty-lines': ['error'],
    'object-curly-spacing': ['error', 'always'],
    'require-jsdoc': [
      'off',
      {
        require: {
          ArrowFunctionExpression: true,
          ClassDeclaration: true,
          FunctionDeclaration: true,
          MethodDefinition: true,
        },
      },
    ],
    quotes: ['error', 'single'],
    semi: ['error', 'never'],
    'spaced-comment': [
      'error',
      'always',
      {
        line: {
          markers: ['/'],
          exceptions: ['-', '+'],
        },
        block: {
          markers: ['!'],
          exceptions: ['*'],
          balanced: true,
        },
      },
    ],
    'space-before-blocks': [
      'error',
      { functions: 'always', keywords: 'always', classes: 'always' },
    ],
    'space-unary-ops': ['error'],
    'space-infix-ops': ['error', { int32Hint: false }],
    'sort-imports': ['off'],
  },
}
```

package.json などのフォーマットは、 Yarn　や npm に任せます。

```config
# .prettierignore
package.json
package-lock.json
yarn.lock
```

prettierrc を入れておくと、意図しないフォーマット（例えば、グローバルな .prettierrc が使われてしまうケース）を防いでくれるので便利です。

```javascript
// .prettierrc.js
module.exports = {}
```

## npm コマンドを定義

こちらも前回の自分のプロジェクトから持ってきたりして package.json 内で適当に定義します。

```json
{
  "scripts": {
    "lint": "eslint --cache --ext=js .",
    "format": "prettier-eslint \"./*.js\" \"./**/*.js\" --write"
  }
}
```

### オプション

検証用のリポジトリを立ち上げることから話が逸れますが、 Prettier のエディタプラグインの導入は開発者個人の環境に依存するので、チーム開発の場合は未フォーマットのコードを必要に応じて CI などで弾くといいかもしれません。

```shell
# TravisCI や Circle CI の設定ファイルで走らせるコマンド
$ npm run format
$ git diff --exit-code --quiet || (echo 'run prettier.' && exit 1)
```

あるいは、 [lint-staged](https://github.com/okonet/lint-staged) を使うのも選択肢の一つです。 git の操作にフックして linter や prettier を実行させることができます。

## Git にコミット

準備完了なので、 最初のコミットを作成してプッシュしておきます。

```shell
$ git add .
$ git commit -m "Init the project🚀"
$ git push origin master
```

## 素振りタイム

ここから試したいライブラリをインストールするなどして試します。

```shell
$ yarn add some-awesome-tool
```

それでは良い Node.js ライフを!

## その他

デプロイなども試す場合は、セキュアなファイル（例えば AWS の認証情報が詰まった .envrc[^2] など） がコミットされていないか確認しましょう。グローバルな .gitignore にこれらを設定しておくのは良い戦略だと思います。

```shell
$ cat ~/.gitignore_global
.envrc
```

最初のコミット前に `git status` で確認したり、あるいはコミットのプッシュ後に不安を感じたらブラウザでも確認したりしています。

```shell
$ git open
```

[`git-open`](https://github.com/paulirish/git-open) [^3] はカレントディレクトリのリモートリポジトリをブラウザで開いてくれるツールです。 GitHub や Bitbucket などの主要なサービスに対応しているようです。

[^1]: 参考: [ESLint | Shareable Configs](https://eslint.org/docs/developer-guide/shareable-configs#publishing-a-shareable-config)
[^2]: [direnv](https://github.com/direnv/direnv) の設定ファイル
[^3]: `git-x`というコマンドにパスが通っていると、 Git に `git x` というサブコマンドが生えます。