IntelliJ上でFlowチェックとESLintチェックを実行して修正する

Analyze -> Run Inspection by Name...
または
Ctrl+Shift+Option+I を実行

f:id:memememomo:20180401164707p:plain

flowを実行する場合はflow errors

f:id:memememomo:20180401164916p:plain

ESLintを実行する場合はESLint

f:id:memememomo:20180401164918p:plain

F2を押すと順番にエラー該当箇所にジャンプできます。

import自動挿入時にfromの文字列をシングルクォーテーション囲うように設定する

f:id:memememomo:20180401161923p:plain

Editor > Code Style > Javascript > Punctuationタブ で設定を変更できます。

文字列を二重クォートで囲うと、ESlintで引っかかっていたので、変更しました。

mochaとSequelizeでテストをするときにmochaが終わらない現象

結論

--exitオプションを付けてmochaを実行すると、テストがすべて実行された後にプロセスが終了します。

stackoverflow.com

終わらない原因

SequelizeでDBへのコネクションが残っていると、mochaが終了しません。 だからといって、afterなどでsequlize.close()を実行してしまうと、後続するテストではDB接続が切れた状態になってしまうので、うまくいきません。

結論として、--exitオプションをつけて強制終了させることで、この問題を解決できます。

import/exportとmodule.exports/require

概要

Node.js、ES6、Typescriptを一気に調べていたせいで、いろいろなパターンのモジュール読み込み方法に出くわして、ちょっと混乱したので、整理しました。

Node.jsのモジュール読み込み

Node.jsのモジュール読み込みは以下のような形になります。

// node/myModule.js

class myModule {
    constructor() {
        console.log('Hello, I am a module');
    }

    hello() {
        console.log('hello!');
    }

    goodbye() {
        console.log('goodbye!');
    }
}

function test() {
    console.log("hoge");
};

//// test関数とmyModuleクラスをエクスポート
module.exports.test = test;
module.exports.myModule = myModule;
// node/main.js

//// モジュール読み込み
var mod = require('./myModule');

mod.test();
var m = new mod.myModule();
m.hello();

Node.jsは module.exportsでエクスポートを行い、 requireで読み込みを行います。

Node.jsの形式なので、そのままNode.jsで実行できます。

$ node node/main.js
hoge
Hello, I am a module
hello!

ES6(ECMAScript2015)のモジュール読み込み

ES6のモジュール読み込みは以下のような形になります。

// es6/myModule.js

export class myModule {
    constructor() {
        console.log('Hello, I am a module');
    }

    hello() {
        console.log('hello!');
    }

    goodbye() {
        console.log('goodbye"');
    }
}

export function test() {
    console.log('hoge');
}
// es6/main.js

import {myModule,test} from './myModule';

test();
var m = new myModule();
m.hello();

ES6では、exportをクラス定義や関数定義の前に付けてエクスポートを行い、importで読み込みを行います。

このままでは、Node.jsで実行することができません。

$ node es6/main.js
es6/main.js:1
(function (exports, require, module, __filename, __dirname) { import {myModule,test} from './myModule';
                                                              ^^^^^^

SyntaxError: Unexpected token import
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:599:28)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Function.Module.runMain (module.js:676:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3

ES6からES5に変換してくれるBabelを使うと以下のようなソースコードになります。

$ babel es6/myModule.js
'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

exports.test = test;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var myModule = exports.myModule = function () {
    function myModule() {
        _classCallCheck(this, myModule);

        console.log('Hello, I am a module');
    }

    _createClass(myModule, [{
        key: 'hello',
        value: function hello() {
            console.log('hello!');
        }
    }, {
        key: 'goodbye',
        value: function goodbye() {
            console.log('goodbye"');
        }
    }]);

    return myModule;
}();

function test() {
    console.log('hoge');
}
$ babel es6/main.js
'use strict';

var _myModule = require('./myModule');

(0, _myModule.test)();
var m = new _myModule.myModule();
m.hello();

Node.jsのmodule.exports/require形式に変換されていますね。

Typescriptのモジュール読み込み

Typescriptでは3パターンの方法が用意されています。

ES6と同じexport/import

Typescriptでは、ES6と同じ形式でモジュールの読み込みをサポートしています。 ほぼ同じなのでソースは省略します。

export =import = require()

また、以下のような形式もサポートしています。

// ts/myModule.ts

class myModule {
    constructor() {
        console.log('Hello, I am a module');
    }

    hello() {
        console.log('hello!');
    }

    goodbye() {
        console.log('goodbye!');
    }
}

function test() {
    console.log('hoge');
}

export = {myModule, test};
// ts/main.ts

import mod = require("./myModule");

mod.test();
var m = new mod.myModule();
m.hello();

/// reference path

読み込むソース(例ではmain.ts)で、/// <reference path="{ファイルパス}" />を記述する方法です。 この方法を使っていると、読み込まれる側(例ではmyModule.ts)では、exportなどの記述は不要になります。

// ts/myModule.ts

class myModule {
    constructor() {
        console.log('Hello, I am a module');
    }

    hello() {
        console.log('hello!');
    }

    goodbye() {
        console.log('goodbye!');
    }
}

function test() {
    console.log('hoge');
}
// ts/main.ts

/// <reference path="./myModule.ts" />

//import mod = require("./myModule");

test();
var m = new myModule();
m.hello();

まとめ

Node.js、ES6、Typescriptでそれぞれモジュールの読み込みの方式が定義されていて、ややこしかったので、まとめてみました。特にES6の方式で記述しているソースをNode.jsで実行しようとしてエラーが出てしまって、よく分かってませんでした。

まだまだいろいろな書き方はあると思いますが、今回は基本的なことだけにとどめました。

RESTful API設計をする際に考慮する点

認証API

一覧取得API

以下のパラメータをリクエストパラメータとして指定できるようにしておく。

  • ページネーション系パラメータ
    • per_page (1ページごとの件数)
    • page (何ページ目のリストを取得するか)
  • フィルタ系パラメータ
    • enum系(status/typeなど)
    • フリーワード検索
  • ソート系パラメータ
    • order_by(どのカラムでソートするか)
    • desc/asc(降順/昇順)

一括更新

  • 一覧ページで一括更新
  • CSVで更新

ステータスコード(レスポンス)

以下のページで紹介されているダイアグラムを参考にすると良さそう。

www.agilegroup.co.jp

Ruby on Rails チュートリアルを完走した

memememomo.hatenablog.com

1日2時間くらいで17日間かかりました。長かった。
演習も全てやりましたが、読み飛ばした文章も割とあっても結構時間がかかりましたね。
内容のクオリティはすごく高くて、初心者が何周かすれば、一通りの基礎知識は身につけられるのではないでしょうか(経験者のサポートは必要かもしれませんが)。
他のフレームワークでもこのレベルのチュートリアルが欲しいですね。
以下、良いと思った点です。

  • gitでバージョン管理して進めていく
  • minitestでテストを書きながら、アプリを開発していく
  • Heroku上にデプロイするので、自分が作ったアプリが公開されている状態になっている
  • ユーザー認証/パスワードリマインダー/画像アップロード/ページネーションなど、実際の開発で必要になってくる機能を一通り実装する

あとは最近発売された以下の書籍もやれば、Rubyistとして必要な基礎知識がかなりつきそうですね。

qiita.com

Rubyは、学習するための手厚いサポートが用意されているのが、とても良いですね。