技術メモ

プログラミングとか電子工作とか

AWS SAMでCognito認証のPOSTが通らなかった

f:id:ysmn_deus:20190318182949p:plain

どうも、靖宗です。
docker-lambdaで開発して、コンソールからLambdaをデプロイするというちょっとアレな運用を直すべくSAM CLIを利用し始めました。
そこまでは良かったものの(逆になんで使って無かったんだ?というぐらい快適だしCloudFormation最高)、Cognitoとの連携をやり始めてCORSでPOSTするAPIがうまくいかず悩んでました。

とは言っても基本的には全てリクエストに情報は載っているもの。
調べて見るとPOSTの手前のOPTIONSリクエストでCognito認証がはじかれてる模様。
axiosでPOSTリクエストを送っている環境下だったので、わざわざOPTIONSのリクエストを描いてヘッダーにトークンを・・・というのはなんだか解決方法として間違ってる気がしたので執拗にウェブをあさっておりましたら該当する情報にたどり着きました。ありがたや。

nibral.hateblo.jp

SAMのテンプレートのAPI Gatewayの箇所にAddDefaultAuthorizerToCorsPreflightという項目を追加しfalseに設定すれば良いとのこと。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Parameters:
  CognitoUserPoolArn:
    Type: String
    Default: arn:aws:cognito-idp:~~~(該当するARNを入力)
  StageName:
    Type: String
    Default: dev

Globals:
  Function:
    Timeout: 3

Resources:
  ApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref StageName
      Auth:
        DefaultAuthorizer: CognitoAuthorizer
        AddDefaultAuthorizerToCorsPreflight: false
        Authorizers:
          CognitoAuthorizer:
            UserPoolArn: !Ref CognitoUserPoolArn
      Cors:
        AllowOrigin: "'*'"
        AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
        AllowMethods: "'OPTIONS,POST,GET'"
  Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ../../built(該当する箇所のパス)
      Handler: (該当ハンドラ)
      Runtime: nodejs10.x
      Events:
        Api:
          Type: Api
          Properties:
            Path: /post
            Method: post
            RestApiId: !Ref ApiGateway

Outputs:
  Region:
    Description: "Region"
    Value: !Ref AWS::Region
  ApiId:
    Description: "API ID"
    Value: !Ref ApiGateway
  ApiUrl:
    Description: "API endpoint URL"
    Value: !Sub 'https://${ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/${StageName}/'

これで問題無くAPIが使える筈です。

AmplifyのLambdaでデフォルトでTypeScript使えるようにならんかなぁ・・・(:3 」∠ )

MinecraftサーバーをAWSのEC2(Amazon Linux 2)で立ち上げる

f:id:ysmn_deus:20190904114458p:plain

どうも、靖宗です。
友人との話で度々「マイクラサーバー立てる」と言って無視してきた日々に終止符を打つべくAWSを利用してマイクラサーバーを立てることにしました。
料金的な観点で言えば動かしっぱなしにするなら絶対VPS(かLightsail)の方がいいんですが、EC2に慣れ親しむというのと拡張性(EC2だとインスタンスの性能がすぐ変えられる)という点でEC2をチョイスしました。
なので、これに当てはまらない方はVPSを選びましょう。

EC2でインスタンスを立ち上げる

この辺は記事が腐るほどあると思いますので割愛。
気が向けば別記事にします。
あと、もしかしたらAMIが転がってるかも。

インスタンスの選定

他の記事などで「small以上じゃないと動かない」という報告をいくつか見受けました。
自分は疑り深いので、敢えてt3.microで実行してみました。
Xmx900M Xms512M(最大メモリ900MB、最小メモリ512MB)で実行してみると、起動はするのですが非常にラグ(ブロックを破壊したのに破壊したことにならない)が生じたり、サーバーがクラッシュして落ちたりするところから最小メモリ1024MB程度は確保しておく必要があるのかもしれません。
ただ、この検証は後述するForgeサーバで行っていますので、もしかしたらバニラのサーバーはなんとか動作するかもしれません。

以上より、この記事ではt3.small相当のインスタンス(自分はt3a.smallを利用)することを想定しております。

Minecraft Serverのセットアップ

とりあえずパッケージマネージャーのアップデートと、Javaを入れときます。

sudo yum update -y
sudo yum install java-1.8.0-openjdk.x86_64

次に、Minecraftのサーバー版をダウンロードしてきます。
今回は1.14.4を公式サイトから直接ダウンロードします。

wget https://launcher.mojang.com/v1/objects/3dc3d84a581f14691199cf6831b71ed1296a9fdf/server.jar

たぶんこの辺でディレクトリを作成してその中で作業した方が良いです。
僕は後で後悔しました。

mkdir minecraft_server
mv server.jar minecraft_server/
cd minecraft_server

とりあえず起動してみます。

java -Xmx1024M -Xms1024M -jar server.jar nogui

文句言われて起動しないと思います。
使用ライセンスを許諾するか否かの確認が必要ですので、実行したら作成されるeula.txtを編集します。
eula=falseの箇所をeula=trueにします。

#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).
#Fri Aug 11 21:05:32 JST 2017
eula=true

これでサーバーが実行できるようになってる筈です。
先ほどのコマンドで実行します。

java -Xmx1024M -Xms1024M -jar server.jar nogui

これで、EC2のIP(か、ドメインを設定している場合はそのドメイン?)にアクセスすればMinecraftサーバーにアクセスできる筈です。
とりあえずの動作確認ですので、実行したサーバーは終了しておきます。
Ctrl+Cで強制終了するか、コマンド入力できる状態でstopと入力すれば止まります。

Forge Serverにする

MODなどを導入する際にはMinecraft Forgeというものにしておくと便利と聞きます。
実際にどうなのか知りませんが、大体サーバーのセットアップの記事を書いてる人達はForgeを導入しているので一応導入しておきます。
必要最低限構成で動かしたい方はスルーしてください。少々重たくなるかもしれません。
たぶんこいつのせいでt3.microとかが使えないのではないかと思っています。

Forgeのダウンロード

Forgeの公式サイトhttps://files.minecraftforge.net/)からインストーラーをダウンロードします。
参考にしたサイトにはuniversal.jarもダウンロードするよう指示がありましたが、1.14.4ではうまく動作しなかったので不要です。
installer.jarのみダウンロードしてください。

f:id:ysmn_deus:20190904103652p:plain

wgetでダウンロードしたいところですが、広告を読ませるためにリダイレクトする形式になってます。
無料で使えるありがたみをかみしめながら広告を読むぐらいは我慢しましょう。

Forgeインストーラをアップロード

先にForgeのディレクトリを作成しておきます。
通常のサーバーのディレクトリをそのままコピペします。

cd ~
cp -Rp minecraft_server forge_server
cd forge_server

作成したディレクトリにForgeインストーラをアップロードします。
SSHでアクセスしてる場合はSCPかなんかでアップロードしてください。

インストール

インストーラを実行します。

java -jar ./forge-1.14.4-28.0.83-installer.jar nogui --installServer

起動

何はともあれ起動してみます。
参考にしたサイトにはuniversal.jarを起動するよう書かれていましたが、なんか起動しなかった(のと、Webフォーラムで生成された奴を実行しろと書かれていた)ので、生成されたforge-1.14.4-28.0.83.jarを実行します。

java -Xms1024M -Xmx1024M -jar forge-1.14.4-28.0.83.jar nogui

これでしばらくまってサーバーが立ち上がれば問題無いと思います。
念のためMinecraftのクライアントから接続して確かめてみるのも良いと思います。

自動起動+コマンドを用意

メンテナンススクリプトの作成

このサイトを参考にしました。
なぜか大概の方の実行コマンドが最大メモリと最小メモリが同じになっているケースが多いんですが、折角最大と最小を指定出来るので一応分けておきます。
上記の手順に従った方は下記のスクリプトで起動などが可能かと思います。
Forgeサーバーでない方はディレクトリや実行するjarを適宜変更してください。

パーミッション

Minecraftサーバーのみ動かしている方は特に気にしなくてもいい気がしますが一応パーミッションも変更しておきます。

chmod 744 mc_script.sh

実行テスト

スクリプトを作成したらとりあえず手動でスクリプトが実行するか確認します。

sh -x ./mc_script.sh start

Minecraftサーバーの標準入出力はscreenに飛ばされてるので、まずscreenに存在しているか確認します。

screen -ls
There is a screen on:
        2295.minecraft  (Detached)
1 Socket in /var/run/screen/S-ec2-user.

数字とかは適宜変わると思います。

もしサーバー上で直接コマンドを入力したい場合(ホワイトリストの入力とか?)はscreenで接続します。

screen -r minecraft

screenから抜けるときはCtrl+aを押した後にdを押して抜けて下さい。

停止

実行テストが終わったら停止しといてください。

sh -x ./mc_script.sh stop

自動起動の設定

systemdに登録して起動したら実行されるようにしておきます。
/etc/systemd/system/minecraft.serviceを作成します。

sudo vi /etc/systemd/system/minecraft.service

内容は下記の通り

[Unit]
Description=Minecraft Server
After=network.target local-fs.target

[Service]
Type=forking
User=ec2-user
ExecStart=/home/ec2-user/mc_script.sh start
ExecStop=/home/ec2-user/mc_script.sh stop

[Install]
WantedBy=multi-user.target

上記が作成できたら、systemctlコマンドで登録します。

sudo systemctl enable minecraft

これで再起動して接続できれば問題無いかと思います。

動作状況

インスタンスの選定のところで言及しましたが、メモリがまあまあ食ってるみたいです。

free -m
              total        used        free      shared  buff/cache   available
Mem:           1961        1244         443           0         273         566
Swap:             0           0  

余裕を持っての動作でしょうけど、やはり2GBぐらいはメモリを確保しておきたいところです。
なので、VPSMinecraftサーバーを立てる方は、少人数であれば2GB程度は見ておくのが良いのではないでしょうか。

参考

minecraft.server-memo.net

Xiser(エクサー)のステッパーで踏み込む度に音が鳴る対処法(たぶん他の音も直る)

どうも、deus(靖宗)です。
メンタリストDaiGoさんの放送やパレオな男こと鈴木さんのブログをよんでいる人なんかはエクサー社のステッパーを利用している人が多いと思います。
(あとはオリンピック選手?)
ただ、たまに音が鳴るのが気になったので原因調査と対処をしてみました。

対処方法

対処法だけで良いよ!って人が大半だと思いますので先に対処法から書いておきます。
対処1だけであれば別にばらさなくてもいいので、1からやってそれでも直らなければ2もやってみるのをお薦めします。
(ただし、これらをやったからといって確実に直るとは限りませんが)

対処1: シリンダー

必要な物

シリンダーの露出部分の油を拭き取る

本当はパーツクリーナーなどで洗浄の後にグリスを塗布するのが鉄則ではありますが、明らかに分解できないので仕方なく気持ちペーパーで露出部分を拭き取ります。
キッチンペーパーやキムタオルの様な物がベストだと思いますが、ティッシュとかでも別に良いと思います。
たぶん拭かなくてもうまくいきますが、後々のトラブルを避けるために念のため拭き取っておきましょう。

シリンダーの露出部分にグリスを塗布する

シリンダーの露出部分にグリスを塗ります。
全面に広がるように指などで塗り広げて下さい。

f:id:ysmn_deus:20190827102635j:plain
露出している全面にグリスを塗る

運の良い方はコレで異音が直ると思います。

対処2: 接触部分(ボルト周辺、金属同士)

必要な物

パーツクリーナーで綺麗にする

内側のボルトの頭をペンチかウォーターポンププライヤー的な何かで押さえながら、外側のナイロンナットをスパナか何かで(こちらもペンチとかで良いけどできればきちんとした工具を使おう)外します。
たぶん多少緩めればあとは手で行ける筈。

部品を外したら、ボルトが刺さっていた箇所とその辺の部品をパーツクリーナーで洗浄します。

f:id:ysmn_deus:20190827095137j:plain

場合によってはシリンダーと接触してる箇所

f:id:ysmn_deus:20190827095300j:plain

も同様に洗浄しておくといいかも。

あと、可能ならステッパー側の穴もパーツクリーナーや綿棒で洗浄しておく。

f:id:ysmn_deus:20190827100337j:plain

グリスアップする

洗浄したら接触部分にグリスを塗布していきます。いわゆる「グリス」と呼ばれる物だったら何でも良いと思います。
付ける箇所は接触部分全般。

f:id:ysmn_deus:20190827101034j:plain

f:id:ysmn_deus:20190827101250j:plain

f:id:ysmn_deus:20190827101416j:plain

f:id:ysmn_deus:20190827101621j:plain

だいたいこんなもんで良いと思います。
もしシリンダーとの接触部分も洗浄していればそこもグリスアップするといいかも?

補足:シリコンスプレーじゃだめなの?

結論から言えばダメです。
このステッパーのボルトの箇所に入っている樹脂ワッシャーの部分はシリコンスプレーでもいいんですが、基本的に金属と金属の潤滑にシリコンスプレーは不向きです。
特に、力のかかる場所ではシリコンワックスは逆に抵抗感になる恐れがあります。今回で言うボルトに塗布した箇所や穴の内側などはシリコンスプレーは逆効果でしょう。

原因調査

そもそも今までどう対処してたか

買った当初から若干気になっており、今まではボルトの両サイドにシリコンスプレー(潤滑剤)を吹いて済ましていました。
上でダメって言っておきながらですが、ばらすのがめんどかったので・・・
(樹脂ワッシャー部分のこすれだと思っていたというのもありますが)

f:id:ysmn_deus:20190827094418j:plain
これでも多少はマシになることがある

ただ、今回これでは改善しない謎のコツコツ感?みたいなのを感じたのでいっそのことボルト周りを綺麗にして確かめてみます。
今回は右側のみ異音を感じたので右側のみ対処しました。

パーツクリーナーで綺麗にする

内側のボルトの頭をペンチかウォーターポンププライヤー的な何かで押さえながら、外側のナイロンナットをスパナか何かで(こちらもペンチとかで良いけどできればきちんとした工具を使おう)外します。
たぶん多少緩めればあとは手で行ける筈。

部品を外したら、ボルトが刺さっていた箇所とその辺の部品をパーツクリーナーで洗浄します。

f:id:ysmn_deus:20190827095137j:plain

場合によってはシリンダーと接触してる箇所

f:id:ysmn_deus:20190827095300j:plain

も同様に洗浄しておくといいかも。

あと、可能ならステッパー側の穴もパーツクリーナーや綿棒で洗浄しておく。

f:id:ysmn_deus:20190827100337j:plain

現段階で音は鳴るか

潤滑油とか付けてないんで結構なる筈なんですが、意外と大きな音はなりませんでした。

グリスアップする

洗浄したら接触部分にグリスを塗布していきます。いわゆる「グリス」と呼ばれる物だったら何でも良いと思います。
付ける箇所は接触部分全般。

f:id:ysmn_deus:20190827101034j:plain

f:id:ysmn_deus:20190827101250j:plain

f:id:ysmn_deus:20190827101416j:plain

f:id:ysmn_deus:20190827101621j:plain

だいたいこんなもんで良いと思います。
もしシリンダーとの接触部分も洗浄していればそこもグリスアップするといいかも?

でもまだ音が鳴る!

組み付けてみましたがまだ音が鳴る・・・
原理的に接触部分にはグリスで潤滑してるはずなのでそれ以外、という事はシリンダーか!

左右反転してみる

シリンダーは前後逆(180度回転)しても取り付けられるので、左右のシリンダーが逆になるようにセットしてみました。
すると案の定、今度は左のみ音がなる(一瞬の抵抗感?がある)ようになりました。
詰まり犯人はシリンダー・・・

シリンダーの露出部分にグリスを塗布する

本当はパーツクリーナーなどで洗浄の後に塗布するのが鉄則ではありますが、明らかに分解できないので仕方なく気持ちペーパーで露出部分を拭き取って、グリスを塗布しました。

f:id:ysmn_deus:20190827102635j:plain
露出している全面にグリスを塗る

すると、とうとう音が消えた!!!

なんだったのか

よく考えてみると、自分はステッパーを使っていないときは左だけ押し込んで右がマックス露出してる状態で置いてることが多いです。

f:id:ysmn_deus:20190827102433j:plain

なので、露出してる側のグリスが劣化して異音が鳴るようになったのでしょう。

Nuxt.jsが2.9になってからTypeScriptの対応が変わったようです。

f:id:ysmn_deus:20190719124755p:plain

どうも、靖宗です。
一生環境構築してる気がします。フロントもう嫌や・・・
ということでTypeScriptの対応がなにやら変わった?ようなので公式に沿ってセットアップしてみます。

Nuxtプロジェクトのセットアップ

ここに関してはいつも通りです。
よければ以前の記事をどうぞ。

TypeScriptのセットアップ

公式サイトのSetupに沿って進めます。
まずは必要なパッケージのインストールをyarnで行います。

yarn add -D @nuxt/typescript-build @nuxt/types

コンフィグファイルnuxt.config.js編集

コンフィグファイルを編集します。

buildModulesという項目に@nuxt/typescript-buildを追加します。

...
  plugins: [],
  /*
   ** Nuxt.js dev-modules
   */
  buildModules: [
    // Doc: https://github.com/nuxt-community/eslint-module
    '@nuxtjs/eslint-module',
    '@nuxt/typescript-build'
  ],
  /*
   ** Nuxt.js modules
   */
  modules: [
...

tsconfig.jsonの追加

tsconfig.jsonを追加します。
一応tscコマンドで追加しますが普通に作成して大丈夫だと思います。

tsc --init

一応ここまでの設定で動作はするようです。

nuxt.configをtsにする

これもうjsのままの方がええんでない?って気もしてきましたが、一応対応します。

必要パッケージのインストール

nuxt.configをtsにする場合はnode環境にもTypeScript対応が求められますので@nuxt/typescript-runtimeが必要になります。
yarnで追加していきますが、-Dではなく普通に依存関係に追加するようです。

yarn add @nuxt/typescript-runtime

package.jsonの編集

yarn devの実行をnuxtからnuxt-tsに変更します。

...
  "scripts": {
    "dev": "nuxt-ts",
    "build": "nuxt-ts build",
    "start": "nuxt-ts start",
    "generate": "nuxt-ts generate",
...

以上でNuxt.jsでTypeScriptを利用できるようになるみたいです。
煩雑なパッケージ関係が整理された感じではありますが、ちょっと手間が増えた感もありますね。
そのうちnuxtのウィザードに追加されそうな気はします。

ついでにLintにも対応する

つまり以前の記事はもう古い。もうしわけないです・・・

パッケージのインストール

これも必要なパッケージがあるのでインストールします。

yarn add -D @nuxtjs/eslint-config-typescript

.eslintrc.jsを編集

.eslintrc.jsに先ほどのパッケージ情報を追加していきます。

...
  extends: [
    '@nuxtjs',
    '@nuxtjs/eslint-config-typescript',
    'prettier',
    'prettier/vue',
    'plugin:prettier/recommended',
    'plugin:nuxt/recommended'
  ],
...

Prettier周りでたまに前後関係が効いてくる場合があるので念のため、Prettierよりは前に追加しました。

package.jsonを編集

package.jsonにlintのコマンドが記載されていますので、それを編集しておきます。といっても.tsを付け加えるだけですが。

...
    "lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore .",
...

試しにyarn lintを実行するとnuxt.config.tsがチェックされているのが分かります。

parserの変更

parserがbabel-eslintのままだと色々ESLintに怒られる時があります。なのでparserを@typescript-eslint/parserに変更しておきます。
まずは必要なパッケージをインストールします。

yarn add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

.eslintrc.jsを編集

parser: 'babel-eslint'

を消去して

  parserOptions: {
    parser: '@typescript-eslint/parser'
  },

を追記します。また、plugins'@typescript-eslint'を追加しておきます。

vueファイルなどにも対応

vueファイルではscriptタグにlang属性を付与することでTypeScriptとしてvueファイルのスクリプトを記載することができます。
ですが、lang="ts"を付けるだけではCannot find moduleとか怒られるのでその辺を対応します。

本当はtsconfig.jsonincludeオプションを利用することで解決できるかと考えていましたが、どうにも解決しませんでしたので

qiita.com

こちらを参考にして、srcディレクトリにshims-vue.d.tsを作成し、tsconfig.jsonfileを追加することで対応しました。
これでたぶんnuxt開発ができる筈!

参考

qiita.com

qiita.com

qiita.com

Nuxt.jsでTypeScriptが使いたいので、ESLintをいじる

f:id:ysmn_deus:20190820122936p:plain

靖宗です。
前回ESLintを設定したんですが、できればコレからはTypeScript(以下TS)を積極的に利用していきたいと考えています。
なので、TSにあった.eslintrcにしていきます。

Nuxt.jsのプロジェクトのセットアップ

別の記事を参照されたし。

パッケージの導入

TSを利用するのに必要な様々なパッケージを導入します。

yarn add ts-node @nuxt/typescript

もしTSを使うのが初めての人はyarn add typescriptも追加です。グローバルインストールかどうかはお任せしますが、多分グローバルで良いと思います。

tsconfig.jsonの作成

TSの設定ファイル(tsconfig.json)を作成します。
一応コマンドから新規作成します。

tsc --init

内容は実践TypeScriptのものを参考に作成します。

nuxt.config.js → nuxt.config.ts

TSを利用していくのでnuxt.config.jsだけ特別扱いはよくありません。
nuxt.config.tsに名前を変更し、内容を少々変更します。

NuxtConfigurationという型を適応するために一度定数として宣言し、最後にexportしています。
基本的にこれで問題無く動く・・・と思います。

.eslintrc.js

パッケージの追加

nuxt.configはjsからtsにしたんですが、.eslintrc.jsやjest.config.jsはtsに対応してないっぽい(そもそも読み込まない?)みたいなので、しかたなくjsのまま行きます。
(特にロジックを書いていく訳でも無いのでまぁいいでしょう)
まずはパッケージを追加していきます。yarnでインストールしていってもいいですが、色々多いのでpackage.jsonに追記してyarn addするのが良いと思います。

...
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.ts,.vue --ignore-path .gitignore .",
    "fix": "eslint --fix --ext .js,.ts,.vue --ignore-path .gitignore .",
    "test": "jest"
  },
  "dependencies": {
    "@nuxt/typescript": "^2.8.1",
    "@nuxtjs/axios": "^5.3.6",
    "nuxt": "^2.0.0",
    "nuxt-buefy": "^0.3.2",
    "ts-node": "^8.3.0"
  },
  "devDependencies": {
    "@nuxtjs/eslint-config": "^1.0.1",
    "@nuxtjs/eslint-module": "^1.0.0",
    "@typescript-eslint/eslint-plugin": "^2.0.0",
    "@typescript-eslint/parser": "^2.0.0",
    "@vue/test-utils": "^1.0.0-beta.27",
    "babel-jest": "^24.1.0",
    "eslint": "^6.1.0",
    "eslint-config-airbnb-base": "^14.0.0",
    "eslint-config-prettier": "^4.1.0",
    "eslint-loader": "^2.2.1",
    "eslint-plugin-nuxt": ">=0.4.2",
    "eslint-plugin-prettier": "^3.0.1",
    "eslint-plugin-vue": "^5.2.3",
    "jest": "^24.1.0",
    "node-sass": "^4.12.0",
    "prettier": "^1.16.4",
    "sass-loader": "^7.2.0",
    "vue-eslint-parser": "^6.0.4",
    "vue-jest": "^4.0.0-0"
  }
...

babel-eslintは敢えて取り除きました。

.eslintrc.jsの編集

基本は以前の記事のeslintrcを踏襲します。

www.tech-note.info

vuetifyを入れる際にはpluginとかが必要になってくると思います。

以上で基本的には動く筈。

参考

qiita.com

Nuxt.jsでいっつもやるやつ(初期の環境構築)

f:id:ysmn_deus:20190719124755p:plain

どうも、靖宗です。

最近Nuxt.js(Vue.js)をさわり始めたのですが、フロントよわよわ界隈としてはなかなか良さげです。
(React.js触ってる人も両方やるとより理解度が高まるかも?という動機で触ってました)
毎回機能を作り込むまでは同じなので、自分用メモとして記事にしておこうと思います。

Nuxt.js プロジェクト構築

create nuxt-appでプロジェクト作成

まずはどのフレームワークでも大体同じだと思いますが、npxやyarnで初期プロジェクトを作成していきます。
最近npxはnodistにバンドルされないと言うことを知ったのでyarnでやります。

yarn create nuxt-app [PROJECT-NAME]

プロジェクトの設定はよしなに。
僕は

  • パッケージマネージャーはYarn
  • UI frameworkはVuetify.js
  • server frameworkはとりあえず無し
  • moduleはAxiosのみon
  • linter+Prettier両方on(よくわかんないけど雰囲気で使ってる)
  • test frameworkはJest
  • rendering modeはとりあえずSSRでやっとく(SPAとかに切り替えるの楽だし)

というかんじです。
この辺は慣れてきたら変わるでしょうが、いまはこんなで。

Vuetify使ってるとエラー吐きまくる

なんか下書きの時はうまくいってなかったんですが今はうまくいくみたいです
参考までに項目は残しておきます。
(indexはどうせ綺麗にするので)

たぶんVuetifyを入れたらエラーだらけになると思います。

✖ 4 problems (4 errors, 0 warnings)
  4 errors and 0 warnings potentially fixable with the `--fix` option.

たぶんyarn lint --fixとかで修正できるのかもしれませんがなんか自分の環境ではうまくいかなかったので指摘がある箇所を手動で修正します。
どうせindex.vueとかはごっそり書き換えるので綺麗にします。

あとはpages/inspire.vueとかcomponents/VuetifyLogo.vueとか消す。これでたぶん通る。

Vuetifyとか使って無くても

一旦作成できたらyarn devぐらいはしてみてもいいかも。パッケージマネージャーのバグとかでそもそも動かない!とか発生する可能性があるので。

IDEの設定

これは人に寄りけりなのでJetBrain系じゃない人はスルーで。
WebStormのNew ProjectでEmpty Projectとして先ほど作成したプロジェクトフォルダをLocationに設定。

とりあえずRunでyarn devが走って欲しいので、右上のAdd Configuration...からRunの設定を追加。
設定するのは

  • Scripts: dev
  • Package manager: yarn

のとこだけ。設定できたらとりあえず動かしてみる。

とりあえずこれでOK。

WebStormのESLint(Prettier)の設定

この辺を参照。

qiita.com

メニューのPreference → Tools → File Watchers から追加します。
一覧の左下のプラスマークから追加しますが、「Prettier」という設定があるのでそこから修正するのが早いかもしれません。
一応自分はJavaScriptとTypeScriptとVueファイルの3種類のファイルウォッチャーを追加しました。

ESLintの設定

上でファイルウォッチャーとか登録すると、yarn generateするとえぐいことになるので.eslintignoreを設定しておきます。
任意ですが、たぶん.nuxtdistnode_modulesあたりを避けておけば問題無いと思います。

.nuxt/
dist/
node_modules/

ディレクトリを変更する

Dockerとか使い出すとプロジェクトルートがぐちゃぐちゃになるので、Vueのファイル群は別の所に変更します。
srcディレクトリを作成して移動します。

mkdir src
mv assets components layouts middleware pages plugins static store ./src

ついでにREADME.md群を消去

find ./src -name README.md -type f | xargs rm -f

このままでは動かないのでnuxt.config.jsを変更。

export default {
  mode: 'universal',
  /*
  ** Headers of the page
  */
+  srcDir: 'src',
  head: {

...

srcDir: 'src',を追加

とりあえずここでもyarn devを走らせておく。

とりあえずSSR(サーバーサイドレンダリング)の生成できるか試す

後から「なんかgenerateできへんねんけど・・・」とならないためにSSRを視野に入れてるならこの辺もやっとく。
特に設定変更していなければyarn generateで生成できるはず。

yarn buildが通るかもチェックしとくといいかも(基本的にyarn generateが通れば通る?)

ESLintのホットリロード

公式にも書いてあるとおり、ESLintをホットリロードできるようにしておきます。

環境変数とかの設定

dotenv入れるかどうか問題みたいなのもあるみたいなのですが、とりあえず現段階では導入してみたいと思います。
yarn add @nuxtjs/dotenvでモジュールを追加しておきます。

.envファイルを作成して設定したい環境変数をいれときます。とりあえずFirebaseを使う事が多いのでGOOGLE_APPLICATION_CREDENTIALSを設定したい場合は

GOOGLE_APPLICATION_CREDENTIALS = key.json

と書いておき、nuxt.config.js

require('dotenv').config()
...
  modules: [
    ...
    '@nuxtjs/eslint-module',
    '@nuxtjs/dotenv'
  ],
  env: {
    GOOGLE_APPLICATION_CREDENTIALS: process.env.GOOGLE_APPLICATION_CREDENTIALS,
  },

としておきます。ファイル頭のrequire('dotenv').config()ですが、ECMAScriptっぽくかくなら

import dotenv from 'dotenv'
dotenv.config()

ともできるっぽいですが、2行になるしどちらが美しいかは分かりません・・・

今後別の環境変数を追加する際は、.envファイルとnuxt.confi.jsの両方をいじることになると思います。

環境変数を切り替えるケースであれば、.envファイルを二つ使って実行することもできるそうです。

blog.ikedaosushi.com

gitの設定

何はともあれgitで管理しておいた方がいいのは間違いありません。
とりあえずデフォルトでgitは設定されているので、コミット+プッシュしておきましょう。

CircleCIの設定

Jestを導入したという事はできればテストは自動でやって貰いたいものです。
CircleCIの設定ファイルを追加しておきます。

これであとはGitHubにCircleCIへのWebhookを追加しておけばdevelopブランチへのコミットで自動テストしてくれます。たぶん。

追加するかもしれないこと(メモ)

routerのbaseを指定(環境変数

faviconなどhead周りの設定

PWAの設定(最初に選んでればやらなくていい?)

Nuxt.jsでESLint(Prettier)が使いたいけどよくわかんなくなったのでまとめた

f:id:ysmn_deus:20190810104633p:plain

こんにちは、靖宗です。
特にチームでのJavaScript案件はやってないんですが、チームじゃなくてもESLintを導入するべきなんじゃないかと感じ、導入してみることにしました。
とはいえよくわかんないので記事にしながら学習します。
とりあえず今回はTypeScriptを対象としていません。別の記事にまとめます。

ESLint

ESLintとは?

ESLintは2013年の6月にNicholas C. Zakasさん(オライリーの「ハイパフォーマンスJavaScript」などの著者)によって作られたツールです。
実行前にJavaScriptソースコードを解析するもので、基本的な間違いを検出するだけでなく、フォーマット(セミコロンの有無など)も検出して指摘してくれます。
まさにチーム開発では重宝されるツールでしょう。

他に似たツールにJSLintなどがあったのですが、最近ではあまり聞かなくなりました。
基本的にはESLint一択なんでしょう。

導入方法

使うプロジェクトでnpmかyarnでインストールすれば良さげです。

npm install eslint --save-dev

or

yarn add -D eslint

設定ファイルを作らなければただ容量を食ってるだけの代物ですが、基本準備はこれだけです。
ただ、今回はNuxt.jsで使う想定なので、nuxtのプロジェクトを作成しながら設定していきたいと思います。

Nuxt.jsのプロジェクトを作成する

まずはコマンドでnuxtのプロジェクトを作成します。

yarn create nuxt-app eslint-test

プロジェクト名はeslint-testとしました。

...
? Choose linting tools ESLint, Prettier
? Choose test framework Jest
? Choose rendering mode Universal (SSR)

nuxtのウィザードに従ってESlintとPrettierを有効にしました。
Jestまで色々書くか微妙ですが、とりあえず導入しておきます。

.eslintrc(ESLintの設定ファイル)の作成

.eslintrcを作成します。
この設定ファイルは6種類の記述手段があるらしく

  • .eslintrc.js
  • .eslintrc.yaml
  • .eslintrc.yml
  • .eslintrc.json
  • .eslintrc
  • package.json

というファイルに記述することができるそうです。
package.jsonに記述する方法はファイルが少なくて済むんですが、煩雑になるので避けた方が良いのでは?と思います。
nuxtなどで用意すると.eslintrc.jsが勝手に生成されるので、基本これで行きます。

ちなみに一番最初に書かれている中身がこれ

module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    parser: 'babel-eslint'
  },
  extends: [
    '@nuxtjs',
    'prettier',
    'prettier/vue',
    'plugin:prettier/recommended',
    'plugin:nuxt/recommended'
  ],
  plugins: [
    'prettier'
  ],
  // add your custom rules here
  rules: {
  }
}

とりあえず詳細は後回しにするとして、設定ファイルはcreate nuxt-appで用意すれば既に生成されています。

ESLintの実行

試しにstore/index.jsを生成して適当な事を書いてみます。

function helloWorld() {
  console.log('hello!')
}

helloWorld();

ESLintをコマンドから実行してみます。
ESLintは

eslint [JavaScriptファイル名]

で実行可能です。
プロジェクトのルートフォルダで

node_modules/.bin/eslint store/index.js

を実行します。

プロジェクトのパス/eslint-test/store/index.js
  5:13  error  Delete `;`  prettier/prettier

✖ 1 problem (1 error, 0 warnings)
  1 error and 0 warnings potentially fixable with the `--fix` option.

prettier/prettierのルールでセミコロンが着いてる!しばくぞ!と怒られています。どうやらprettierの方ではデフォルトでセミコロンは悪役の様です。
こういったフォーマットの規約などをチェックするのがESLintの役割です。

--fix

ちなみにエラー分を見ると「1 error and 0 warnings potentially fixable with the --fix option.」とあります。こういう場合は

node_modules/.bin/eslint store/index.js --fix

と実行すると、該当箇所を良い感じに修正してくれます。
ただし、後述するようにこの辺は全部Prettierに任せようと思います。
(とは言っても実行されるコマンドは同じみたいですが)

ESLintの設定ファイル

ここでようやくESLintの設定ファイルに関して見ていきましょう。

ルールの追加(rules)

ESLintのルールを追加するには設定ファイルに追記していきます。
細かい設定は.eslintrc.jsrulesに記載します。

...
    "rules": {
        "semi": ["error", "always"]
    }

設定項目はESLintの公式サイトや諸先輩方の設定ファイルを参考にさせて貰うとして、基本的には
設定項目: [設定のオンオフ, オプションの値]
という構成になります。設定のオンオフはerror(あったらエラーを送出する), warn(警告だけする), off(無視)が設定できます。
オプションは設定項目で色々ですが、例えばsemiではalwaysにすると「無いと怒る」、neverにすると「あると怒る」といった感じです。

ルートの指定(root)

nuxtのウィザードでESLintの設定ファイルを生成するとrootという設定項目があります。
これは「プロジェクトルートがここなので、これ以上親の階層は気にしなくて良い」という設定のようです。
ESLintは階層ごとに配置することもできるそうなので(たぶんそんなに頻繁にすることはない)、どこまで親をたどるのか明確にするときに設定するのでしょう。
基本そのままで大丈夫そうです。

環境の設定(env)

初期設定ではbrowsernodeがtrueになっていると思います。
スクリプト実行環境を指定出来るオプションのようで、ブラウザとNode.jsで実行されることを想定しています。
基本このままでも大丈夫そうですが、念のためes6jestを追加しておきます。

...
  env: {
    browser: true,
    node: true,
    es6: true,
    jest: true
  },
...

parserOptionsの設定(parserOptions)

上記でes6を追加しましたが、それだけではimport文などのES Moduleの機能までチェックできないようです。
そこで、設定ファイルの項目parserOptionsを設定していきます。

...
  parserOptions: {
    "sourceType": "module"
  },  
...

parserOptionsの項目に"sourceType": "module"を追加します。
これでES6に対応したはずです。

また、デフォルトではbabel-eslintが設定されていますが、いろんな設定を付加してくれる反面いろいろありすぎて推奨されない見方もあるそうなので、個人的な判断ですが削除します。
ちなみに、たぶんなんですがbabel-eslintを設定しておけばes6の記述と上記のmoduleの記述は不要になると思います。お好きな方をどうぞ。

ついでにJSXもチェックできるようにしておきます。

...
  parserOptions: {
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
...

nuxtなんであんま使わないと思いますが。

拡張ルールセット(extends)

ライブラリなど既に定義されているルールを取り込みたい時があります。むしろそれだけで事足りる事が多いんじゃないでしょうか?
そういうときの設定項目としてextendsがあります。nuxtのデフォルトでは何種類か指定されていると思います。

基本的な流れとしては

  • npmかyarnでルールを追加する
  • "extends"に追記する

といった感じです。楽勝ですね。
試しにかの有名なairbnbのルールを適応してみます。パッケージはeslint-config-airbnb-baseです。

yarn add -D eslint-config-airbnb-base

お次にeslintrcに追記。

...
  extends: [
    'airbnb-base',
    '@nuxtjs',
    'prettier',
    'prettier/vue',
    'plugin:prettier/recommended',
    'plugin:nuxt/recommended'
  ],
...

一番上に追記したのは、'plugin:prettier/recommended'の設定が後ろに回さないとうまく動かない事があるという噂を聞いたことがあるからです。
この噂に従い、基本的に後から追加したものは上から順に追記していきます。(ここは曖昧なので気になる方は調べて下さい。)

プラグイン(plugins)

先ほどのextendsのなかにplugin:prettier/recommendedなどplugin:で始まるものがあります。
これらはpluginsの項目で設定したプラグインの推奨設定で、プラグインを導入すると使えるルールだそうです。
全部extendsでどうにかならんの?という気がしないでもないんですが、おそらく内部構造的にプラグインとして別途読み込まなければならないルール(たとえば、上記のES6なんかはES Moduleの為にparserOptionsが必要になったのは内部構造によるもの)の際にはpluginに追記する必要があるんでしょう。
このへんは導入するルールによるものかと思います。その都度確認しましょう。

今回はnuxtの為に導入しているので、vueのルールを追加します。
なんでデフォルトで入らないか謎ですが、追加で加えていきます。

yarn add -D eslint-loader eslint-plugin-vue

大体セットでeslint-loaderも追加してるんですが、ホットリロードの為だと思います。
設定ファイルを書き換えます。

...
  extends: [
    'airbnb-base',
    '@nuxtjs',
    'prettier',
    'prettier/vue',
    'eslint:recommended',
    'plugin:vue/recommended',
    'plugin:nuxt/recommended',
    'plugin:prettier/recommended'
  ],
  plugins: [
    'vue',
    'prettier'
  ],
...

'plugin:vue/recommended'を追加したついでに'eslint:recommended'も追加しました。

ESLintの設定はだいたいこんなもんで良さそうです。

Prettier

PrettierはESLintと併用されることの多いソースコードを整形してくれるツールです。
要するにeslint --fixのつよいバージョンといったところでしょうか。
eslintだけでもええやん!て気もするんですが、どうも整形機能としてはPrettierの方が優れているらしく、併用するひとが多いイメージです。
冗長なのが嫌いな方は別に導入しなくても良いと思います。(チェック自体はESLintがやってくれるので)

導入方法

nuxtのウィザードで導入すると設定は既に完了しています。
後から導入する場合はeslint-config-prettiereslint-plugin-prettierをyarnかnpmでインストールすれば大丈夫だと思います。
設定に関しては

...
  extends: [
...
    'prettier',
    'prettier/vue',
...
    'plugin:prettier/recommended'
  ],
  plugins: [
...
    'prettier'
  ],
...

が該当します。

Prettierのルール

Prettierはあくまで補助ツールなので、全ての構文チェックなどはしていません。
イメージとしてはESLintの苦手な整形部分"だけ"を担当しているツールという認識が正しそうです。
なので、extendsの'plugin:prettier/recommended'を一番最後に持ってこないとPrettierで整形したあとにESLintで怒られる構文になったりするので、必ずこの設定は最後に書きましょう。

また、prettierの設定はESLintのrulesに記載することができ、

...
  rules: {
    "prettier/prettier": [
      "error",
      {
        "semi": true
      }
    ]
  }
...

と書くことで、ESLintでセミコロン無しを警告するし、Prettierでコードフォーマットする際にセミコロンを追加したりできます。
基本的にESLintでもPrettierでも指定出来る設定はPrettierで設定するのが良さそうです。(どうせ上書きされるので)
Prettierで指定出来るオプションは下記の通りです。

prettier.io

その他

大体上記までで設定などは完了なのですが、ESLintやPrettierはファイルウォッチャーなどで「保存したら勝手に整形する」といった設定が望ましいです。(いちいちコマンド実行するのはめんどい)
nuxt公式のホットリロードを設定しておけばローカルでサーバーを動かしている際にチェックできるのでそれで良いと思いますが、気になる方はお使いのIDEのファイルウォッチャーにeslintのコマンドを登録するのをお勧めします。

参考

eslint.org prettier.io qiita.com qiita.com qiita.com yokotakenji.me