ゆとり世代プログラマの備忘録

ゆとり世代プログラマが備忘録を書いていく

技術書典2に出店しました

技術書典2に出店してきました。

techbookfest.org

参加された方とか運営の方とかおつかれさまでした。

今回は『TypeScriptでつくるシングルページアプリケーション』という本のみ販売しました。

TypeScriptでつくるシングルページアプリケーション内のソースは以下のリポジトリで公開しています。 また、今回印刷した30部しか刷らなかったため、すぐに売り切れてしまい、 「githubの方には本文は載ってないんですか?」って結構聞かれたので、リポジトリの方には、本文のソースとしてワードファイルをあげました。

Microsoft Office ワードを持っていない場合、Microsoft Office OnlineやLibre Officeなどで開けば、若干デザインは崩れるかもですが、一応読むことはできると思います。

また、同様の内容の本を4月30日の超技術書典でも販売する予定です。

techbookfest.org

次はポスター的なものとか、机の上にかけるシート的なものとか準備して、もう少しブースっぽく構えたいなーと思いました。

まる。

Visual Studio Code でpackage.jsonが複数ある場合に各scriptsの内容をタスクランナーから実行する方法

何がしたいのか

package.jsonがカレントディレクトリになく、 且つ package.jsonが複数のサブディレクトリにまたがって複数存在する場合に、 VSCodeのタスクランナーからそれぞれのpackage.jsonの scripts に指定されているscriptを実行したい!!!!

したい!!!

どうしてそう思った

Webのフロントもサーバーも両方TypeScriptで書いていて、 フロントとサーバーを別々のフォルダで管理して、pacakge.jsonもそれぞれ別々に用意していると、 以下のようなフォルダ構成なることが考えられる。

というか、なった!

こういう構成にするのが馬鹿だって石投げつけられたら、もうそのまま石投げつけられますが!

root/   ←ここから VSCode で開いている
    │
    ├ client/  ← フロントエンド用プロジェクト Angular2とかやる方
    │    ├ index.ts
    │    ├ webpack.config.json
    │    │ ...etc
    │    └ package.json ← フロントエンド用の packatge.json こっちにフロントのビルド用scriptが書いてある
    │    
    └ server/ ← バックエンド用プロジェクト Express 使ってAPI作る
         ├ app.ts
         │ ...etc
         └ package.json ← バックエンド用の packatge.json こっちにサーバーのビルド用scriptが書いてある

で、俺は開いた。VSCodeのタスクランナーを。意気揚々と。Command + shift + P からの task からの Enter ターンッ !! npm を選択して Enter ターンッ!!!

あれ?カレントディレクトリに package.json にない場合どうするんだ??? というか複数のpackage.jsonを扱いたい場合どうするんだ? 絶望しました。

まぁ、VSCodeには端末機能あるからそこでコマンド叩けばいいんだけど、やっぱりタスクランナーがあるんだったらそれでやりたい!!!

pacakge.jsonのscriptsの内容

client/package.json

フロント側のpackage.json webpack使ってビルドしてる。 webpackの方で、ビルドした.jsファイルを server/public/script/ に吐き出してる。 とりあえず VSCodeのタスクランナーから build と watch を叩きたい

{
  // 省略
  "scripts": {
    "build": "webpack --progress --colors --config webpack.config.dev.js",
    "watch": "webpack --progress --colors --watch --config webpack.config.dev.js",
    "build-product": "webpack --progress --colors --config webpack.config.prod.js",
    "watch-product": "webpack --progress --colors --watch --config webpack.config.prod.js"
  },
  // 省略
}

server/package.json

サーバー側のpackage.json 一番使ってるのが dev だから最悪これだけでもタスクランナーから叩きたい

{
  // 省略
  "scripts": {
    "start": "node ./app.js",
    "dev": "tsc --watch & node-dev ./app.js",
    "build": "tsc",
    "watch": "tsc --watch"
  },
  // 省略
}

結論

できた!

f:id:jBellTree:20170213143918p:plain

できた!

こうする!

これを(タスクの種類で npm を選んだ場合の初期状態)

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "npm",
    "isShellCommand": true,
    "showOutput": "always",
    "suppressTaskName": true,
    "tasks": [
        {
            "taskName": "install",
            "args": ["install"]
        },
        {
            "taskName": "update",
            "args": ["update"]
        },
        {
            "taskName": "test",
            "args": ["run", "test"]
        }
    ]
}

こうする!

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "sh",
    "isShellCommand": true,
    "showOutput": "always",
    "suppressTaskName": true,
    "args": ["-c"],
    "tasks": [
        {
            "taskName": "build",
            "args": ["npm -prefix ./client run build && npm -prefix ./server run build;"]
        },
        {
            "taskName": "watch",
            "args": ["npm -prefix ./client run watch & npm -prefix ./server run dev;"]
        }
    ]
}

ポイント1

shコマンドを指定する。npmじゃなくてsh。発想の転換

    "command": "sh",

ポイント2

-cオプションをつける。 shellとか詳しくないけど、ようは端末で打った内容をそのまま実行するためのオプションらしい。

    "args": ["-c"]

ポイント3

args にもう全部書いちゃう!

    "args": ["npm -prefix ./client run build && npm -prefix ./server run build;"]

つまりこういうことだね。知らんけど。

$ sh -c npm -prefix ./client run build && npm -prefix ./server run build;

ポイント4

-prefix をつける。

npm -prefix ./client run build

https://docs.npmjs.com/cli/prefix

こういうことらしいです。

なるほどね ← 分かってない

ポイント5

&& とか & とか使って、フロント側の npm run と サーバー側の npm run をまとめて実行してやる。

今回は build の方は実行した一発だけでいいから &&(http://itpro.nikkeibp.co.jp/article/COLUMN/20060224/230604/) watchの方は両方はバックグラウンドで動かしたいから &(http://itpro.nikkeibp.co.jp/article/COLUMN/20060224/230589/) を使った。← よくわかってない。

npm -prefix ./client run build && npm -prefix ./server run build;
npm -prefix ./client run watch & npm -prefix ./server run dev;

まぁ、普段は IntelliJ使ってるんだけどな!!!!!!!!!!!

Visual Studio Code で TypeScript2.0を書いたらハマったこと

前回の記事から2ヶ月?くらいたっていて、気がついたらTypeScript2.0がリリースされていた…

ので、Visual Studio Code で TypeScript2.0 を書こうとしたらハマったところと解決策のメモ。 まぁ、普段は IntelliJ IDEA で書いているだけど。

まず、以下のようなコードを TypeScript で書いて、Visual Studio Code のタスクランナーでコンパイル使用としたら怒られた。

'use strict';


class Singleton {

    /** instanceを保持します。 */
    private static instance: Singleton;

    /**
     * コンストラクタ
     * TypeScript2.0からconstructor に private が指定できるようになった。
     */
    private constructor() {
        // do nothing.
    }

    /**
     * インスタンス取得メソッド
     * @return {Singleton} Singletonのインスタンス
     */
    public static getInstance() : Singleton {
        if (!Singleton.instance) {
            Singleton.instance = new Singleton();
        }
        return Singleton.instance;
    }

    public sayHello() : void {
        console.log('Hello World');
    }

}

Singleton.getInstance().sayHello();

どこで怒られたかっていうと、コンストラクタのところ。

    /**
     * コンストラクタ
     * TypeScript2.0からconstructor に private が指定できるようになった。
     */
    private constructor() {
        // do nothing.
    }

コンストラクタに private が指定できるようになったのは TypeScript2.0 からで、どうもVisual Studio Code が内部的に使っているTypeScriptは1.8らしい。

なので、Visual Studio Code 側の設定を変えてあげる必要がある。「ワークスペース設定」を開き…

f:id:jBellTree:20160926005606p:plain

以下のように、ワークスペースの設定でTypeScriptを自分がインストールしたものを指定してあげる。

f:id:jBellTree:20160926005842p:plain

すると、

f:id:jBellTree:20160926012505p:plain

うまくいった!めでたしめでたし。

TypeScriptの環境を整えた話

TypeScript用開発環境を整えたのでメモ

TypeScript用開発環境を整えるのでなんやかんや試して、自分なりにミニマムで開発しやすい環境を作れたので、それのメモ。 個人的には一番 IntelliJ IDEA 上でステップ実行できたってのがでかい。

一応作ったソースとか設定とかはGitHub上にあげておきます。

github.com

やりたいこと

  • TypeScriptを書きたい
  • ソースはモジュール化しておきたい
  • import/export などを解決したい
  • 今回はフロントエンドに使用したいので、jQueryも使えるようにしておきたい
  • IntelliJ IDEA 上でステップ実行したい

やったこと

まずは作業ディレクトリに移動

$ cd <作業ディレクトリのパス>

なにはともあれ npm init

$ npm init

とりあえずEnter連打。 細かいところはあとから修正します。

typescriptをインストール

$ npm install typescript -g

webpackをインストール

今回は依存関係の解決にwebpackを使用するのでwebpackもインストールします。 一緒に、webpackでtypescriptを扱うためのts-loaderもインストールします。

$ npm install webpack -g
$ npm install ts-loader --save-dev

webpack.confing.jsを作成

次にwebpack用設定ファイルを作成する。

// コマンドメモ
// --watch : ファイルの変更を監視 ビルドの自動化
// $ webpack --progress --colors --watch

var path = require('path');

module.exports = {
    // エントリーポイント
    entry: './script/src/main.ts',
    // ソースマップ出力
    devtool: "#source-map",
    // 出力先設定
    output: {
        path: __dirname,
        filename: './script/dist/bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.ts$/,
                loader: 'ts-loader'
            }
        ]
    },
    resolve: {
        // ここに登録した拡張子は import時に省略できる
        extensions: ['', '.ts', '.js']
    }
};

tsconfig.json を作成

TypeScriptからJavaScriptへ変換する際の設定ファイル(とお思います。) とりあえず以下のコピペで問題ない(と思います。)

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "noImplicitAny": false,
    "sourceMap": true
  },
  "exclude": [
    "typings/main.d.ts",
    "typings/main",
    "node_modules"
  ]
}

その2 に続く

Go言語でAPI作った話

書くこと

  • Go言語でRestAPIつくりましたって話

  • 参考にした本とか記事とか

  • 環境構築とか

  • 書いたソースと簡単な説明とか

  • その他感想とか

Go言語でRestAPI作りましたって話

RestAPIって言っても、ランダムに運勢をJSON形式で返すだけの おみくじAPIです。 GETメソッドで omikuji.json を叩くと運勢が帰ってきます。 ブラウザで直接開いた場合以下のような感じです。まんまJSONです。

f:id:jBellTree:20160516083509p:plain

参考にした本とか記事とか

まず一通り基本的な文法とか、お作法的なところを↓の本で勉強しました。 ちなみに今回はKindle版を買った。検索は対応してるっぽいです。

https://www.amazon.co.jp/%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0Go%E8%A8%80%E8%AA%9E-%E6%9D%BE%E5%B0%BE%E6%84%9B%E8%B3%80-ebook/dp/B01FH3KRTI?ie=UTF8&qid=&ref_=tmm_kin_swatch_0&sr=www.amazon.co.jp

で、RestAPI作りたいなーって思ったら以下の記事を見つけたので参考にさせていただきました。

qiita.com

環境構築とか

上の記事で使用されている go-json-rest なるライブラリを使いましょうという方針でいく。 が、俺の環境にはまだそんなライブラリを落としてきていない。ので落としてくるのだが、じゃあどうやるのかというと、 俺は↓の記事を参考に ghq なる物をインストールし、ghqを使用して go-json-rest をインストールしました。

ghq... 連合国軍総司令部???

qiita.com

書いたソースと簡単な説明とか

構成

パッケージ構成は以下のようにしました。 ソース内の packaege ~~~ も実際のフォルダ構成と同じ。

main
 ├ bin/
 └ main/
     ├ OmikujiApi.go
     │
    ├ data/
     │  └ OmikujiData.go
     │
      └ resource
          └ Omikuji.go

OmikujiApi.go

なんかいろいろやってる。 go-json-rest ライブラリのAPIをちゃんと読まないといけないんだけど、 たぶん、 * 受け付けるメソッドの設定(GETとかPOSTとかDELETEとか)、 * パスのルーティング(? っていう言葉でいいのかな) http:// ... /omikuji.json というパスとそのパスにアクセスされた場合に実行する処理の紐付け * 何番のポートを使うかの設定 (今回は 8081番)

をやっている。(つもりになってます。)

package main

import (
    "net/http"
    "github.com/ant0ine/go-json-rest/rest"
    "./resource"
    "log"
)


func main() {

    api := rest.NewApi()
    api.Use(rest.DefaultDevStack...)
    api.Use(&rest.CorsMiddleware{
        RejectNonCorsRequests: false,
        OriginValidator: func(origin string, request *rest.Request) bool {
            return true
        },
        AllowedMethods: []string{"GET"},
        AllowedHeaders: []string{
            "Accept", "Content-Type", "X-Custom-Header", "Origin"},
        AccessControlAllowCredentials: true,
        AccessControlMaxAge:           3600,
    })
    router, err := rest.MakeRouter(
        rest.Get("/omikuji.json", resource.GetOmikuji),
    )
    if err != nil {
        log.Fatal(err)
    }
    api.SetApp(router)
    log.Fatal(http.ListenAndServe(":8081", api.MakeHandler()))
}

OmikujiData.go これが実際にJSON形式にして返すデータ。 SetUnsei() を使うと運勢がランダムにセットされる。

package data

import (
    "time"
    "math/rand"
)


type OmikujiData struct {
    Unsei string
}

func (omikujiData *OmikujiData) SetUnsei() {

    unseiMap := map[int]string{
        0: "大吉",
        1: "中吉",
        2: "小吉",
        3: "末吉",
        4: "吉",
        5: "凶",
        6: "末凶",
        7: "小凶",
        8: "中凶",
        9: "大凶",
    }

    rand.Seed(time.Now().UnixNano())
    unsei := unseiMap[rand.Intn(10)]
    omikujiData.Unsei = unsei
}

Omikuji.go

OmikujiData構造体をJSONにして返す関数を書いた。

package resource

import (
    "github.com/ant0ine/go-json-rest/rest"
    "../data"
)


func GetOmikuji(w rest.ResponseWriter, r *rest.Request) {

    omikujiData := new (data.OmikujiData)
    omikujiData.SetUnsei()
    w.WriteJson(omikujiData)
}

その他感想とか

正直、ここまでめっちゃスムーズにできたと思う。 JavaJAX-RSのプロジェクト作って、RestAPIの動作確認まで…とかと比べてだけど。 たぶん Go言語の方がずっと詰まるところが少なかったと思う。

動作が確認できるまでの途中途中での、「なんかうまくいかないんだが?」っていうのってモチベーションの維持に非常に関わるので、 そういうのが少ないのって素晴らしいと思う。まる。

webpack + Babel + React(ES2015使用)の設定

やりたいこと。 * ReactをJSXを使用して書きたい。 * EcmaScriptの構文も使用して書きたい * .jsファイルと、.jsxファイルに変更があった場合自動的にビルドしてほしい。 * 自動的にソースマップも出力してほしい。

webpack.config.js

// コマンドメモ
// -p : minify
// --watch : ファイルの変更を監視 ビルドの自動化
// $ webpack -p --progress --colors --watch

var path = require('path');
var webpack = require('webpack');

module.exports = {
    // エントリーポイント
    entry: './script/src/main.jsx',
    // ソースマップ出力
    devtool: "#source-map",
    // 出力先設定
    output: { 
        path: __dirname,
        filename: './script/dest/bundle.js' 
    },
    module: {
        loaders: [
            // .jsxファイル用
            {
                test: /.jsx?$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                query: {
                    presets: ['es2015', 'react']
                }
            },
            // .jsファイル用
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                query: {
                    presets: ['es2015']
                }
            }
        ]
    },
    resolve: {
        // ここに登録した拡張子は import時に省略できる
        extensions: ['', '.js', '.jsx']
    }
};

以下のコマンドで実行

$ webpack -p --progress --colors --watch

俺がBracketsに入れてるエクステンションまとめ

f:id:jBellTree:20160410030442p:plain

Mac でも Windows でも使えて、動作が安定していて、標準で日本語に対応していてライブプレビューできて簡易サーバー立ち上げられる最強伝説エディタ Bracketsに俺がよく追加しているエクステンションまとめた。

相変わらずUTF-8のファイルしか扱えないけど、そこは割り切っていこう。

React (.jsx) language mode for Brackets

React(.jsx)モードを追加するエクステンション

Go-IDE

Go言語モードを追加するエクステンション

Monokai Dark Soda

テーマを変更するやつ。 黒ベースで最高にCoolだぜ。

FuncDocr

JSDocのテンプレートを挿入してくれるやつ。 ためしてないけどPHPでもいけるっぽい。

Tabs - Custom Working

開いてるファイルをタブ表示してくれるやつ。

Show Whitespace

スペースとかタブとかを可視化してくれるやつ。 可視化されてないと不安になるので、精神衛生上とても重要なエクステンション。

Indent Guides

インデントにあわせて縦線を表示してくれるやつ。 上の Show Whitespace とのコンボで最強になれる。

Brackets Exclude Indexing FileTree

開いているフォルダー内に 30000以上ファイルがあるとエラーになるんだが、node_moduleフォルダとかあると簡単に30000ファイルくらい超えるので、node_moduleを編集対象のフォルダから除外してくれるエクステンション。

上にあげたエクステンションのみ有効にした場合こんな感じになる。 f:id:jBellTree:20160410031653p:plain

もっとゴテゴテにカスタマイズしてた時もあったけど、今はシンプルに保つのもいいかなと思ったりしているところ。