selmertsxの素振り日記

ひたすら日々の素振り内容を書き続けるだけの日記

nodejsでdebuggerを動かす

モチベーション

typescript & vscode & jest環境でdebugするにあたって、debuggerを使っていたが、そもそもdebuggerって何よ。ってくらいの理解だったので、この機会に色々確認したかった。

debuggerの実行方法

https://nodejs.org/dist/latest-v6.x/docs/api/debugger.html そもそも debuggerとは、nodejs本体に搭載されている機能である。

console.log('hogehoge');
var a = "hogehoge";
debugger;
a = "1234";
console.log('hagehage');
$ node debug test.js
< Debugger listening on [::]:5858
connecting to 127.0.0.1:5858 ... ok
break in test.js:1
> 1 console.log('hogehoge');
  2 debugger;
  3
debug> repl
Press Ctrl + C to leave debug repl
> a
'hogehoge'

ということで、何の設定もしなくても動く。

debuggerのコマンド

watch

指定した変数の変化を追ってくれる

debug> watch('a');
debug> n
< hogehoge
break in test.js:2
Watchers:
  0: a = undefined

  1 console.log('hogehoge');
> 2 var a = "hogehoge";
  3 debugger;
  4 a = "1234";
debug> n
break in test.js:3
Watchers:
  0: a = "hogehoge"

  1 console.log('hogehoge');
  2 var a = "hogehoge";
> 3 debugger;
  4 a = "1234";
  5 console.log('hagehage');
debug> unwatch('a')
debug> n
break in test.js:4
  2 var a = "a";
  3 debugger;
> 4 a = "1234";
  5 console.log('hagehage');

list

Listはソースコードを、実行中の部分から前後5行の範囲内で表示してくれる。

debug> list(1)
> 1 console.log('hogehoge');
  2 var a = "hogehoge";
debug> list(5)
> 1 console.log('hogehoge');
  2 var a = "hogehoge";
  3 debugger;
  4 a = "1234";
  5 console.log('hagehage');

とりあえず、普通に使う分には把握した気がする。

ふつうのLinuxプログラミング読書 (1章)

第1章は下記のような構成になっています

  • この本で学ぶことができること
  • C言語開発の一通りの手順
  • 情報の探し方と基礎知識について

それぞれについて、簡単にまとめます

この本で学べる内容

Linuxを構成するものやその世界を見て、Linuxに関する常識を身につけることを目的として、下記3点の概念について学びます。

  • ファイルプロセス
  • プロセス
  • ストリーム

この3点を選んだ理由は、この3つがLinux世界を構成する重要な概念だからです。

C言語開発の一通りの手順

ここでは下記の内容について学びます

gccを使ったビルド

# -o optionでビルドされるプログラム名を指定する
gcc -o ${ビルドされるプログラム名} {Cのプログラム名}

github.com

コマンドライン引数

int main (int argc, char *argv[]){
   ...
}

上記のプログラムにコマンドライン引数を与えて実行すると、argc, argvの値は下記のようになります。

$ ./args x y
argc=3
argv[0] = ./args 
argv[1] = x
argv[2] = y

ここで./args * などのグロブを使って、複数の引数を一度に渡すことも可能です。 また、ダブルコーテーションを使うと、コマンドライン変数をまとめることができます。 ./args "*"./args "x y z"と入力した場合、"*" や "x y z" も1つのコマンドライン引数とみなされます。

情報の探し方と基礎知識

cプログラミングで情報を集める際、manコマンドが便利です。 例えば、man strlen とすると、下記のような出力が得られます。

STRLEN(3)                BSD Library Functions Manual                STRLEN(3)

NAME
     strlen, strnlen -- find length of string

LIBRARY
     Standard C Library (libc, -lc)

SYNOPSIS
     #include <string.h>

     size_t
     strlen(const char *s);

     size_t
     strnlen(const char *s, size_t maxlen);
...

printfのように、コマンドや関数など、複数のセクションに同じ名前のページが存在する場合、man printf と入力すると下記のような出力が得られます。

PRINTF(1)                 BSD General Commands Manual                PRINTF(1)

NAME
     printf -- formatted output

SYNOPSIS
     printf format [arguments ...]
...
SEE ALSO
     echo(1), printf(3)

PRINTF(1)の(1)はコマンドを示します。STRLEN(3) の (3)は関数を示します。 LinuxUnixの世界では、この使われ方はよく出るので覚えておいて損は無いです。その他にも man png と入力するとpngのフォーマットが出力されたりします。表にすると下記の通りです。

1: ユーザーコマンド ( man printf)
2: システムコール (次の章で説明)
3: ライブラリ関数 (`man 3 printf` or `man strlen`)
4: デバイスファイル (`man tcp`)
5: ファイルフォーマット (`man png`)

まとめ

以上、この本で学べる内容、C言語でのビルドから、コマンドの調べ方まで、Linuxの世界を学ぶために必要な道具を渡される感じの1章でした。

自作ライブラリのバージョンの上げ方

モチベーション

github.com

  • iioptのupdateをしたい
  • updateに際して必要な対応を理解し、まとめたい

※ 自作ライブラリの管理は初めてなので、おかしい点があればコメント頂けるとうれしいです!

libraryのupdateで必要なこと

Libraryのバージョンを上げるときには、機能開発とは別に下記2点の対応が必要となってきます。

  • CHANGELOG.mdの作成
  • libraryのversionを上げる

この記事では、それぞれについて、資料を読んだのでまとめます。

CHANGELOG.mdの作成

CHANGELOGの作り方については、下記の資料を参考にしました。

keepachangelog.com

Wiki で一番最初に参照されているので、それなりの知名度があるのでしょう。 Changelog - Wikipedia

この Keep a ChangeLog のホームーページ上で記載されている内容について、簡単にまとめようと思います。

Change Logを作る意味

Change Logとは、このプロジェクトの各リリース間における変更について、何が注目に値するのか、開発者や利用者に対して、正確に把握して貰うために作るものです。

開発者も利用者も、新しく追加された機能や、その背景が気になるはずです。なのでChage Logを作って、それらを追えるようにする必要があります。

Change Logに書く内容

keep-a-changelog/CHANGELOG.md at master · olivierlacan/keep-a-changelog · GitHub

具体的にどのように書くのか把握するため、Keep a Change Logのサイト自体の Change Logを確認しました。抜粋したものを下に書きます。

Changelog
All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog and this project adheres to Semantic Versioning.

Unreleased
1.0.0 - 2017-06-20
Added
New visual identity by @tylerfortune8.
Version navigation.

Changed
Start using "changelog" over "change log" since it's the common usage.
Start versioning based on the current English version at 0.3.0 to help translation authors keep things up-to-date.

0.0.3 - 2014-08-09
Added
"Why should I care?" section mentioning The Changelog podcast.

Change Logは上から最新のものを記載します。 それぞれのバージョンについて、更新内容と更新した日付を書きます。 更新内容については、added, changed, removed, fixed, Security の5つの項目に分けて記載します。それぞれ、書く内容は下記のようになっています。

  • Added: そのバージョンアップで追加した新しい機能
  • Changed: 既存の機能の修正
  • Removed: 機能の削除
  • Fixed: バグの修正
  • Security: 脆弱性対策

小ネタとして、まだリリースしていないけれども開発した内容は Unreleasedに乗せておくとよいとのことです。その理由は下記の通りです。

  • 人々は次のリリースで使えるようになる機能を見ることができる
  • releaseするときに、unreleased sectionを次のリリースバージョンに置き換えれば良い。

libraryのバージョンの上げ方

セマンティック バージョニング 2.0.0 | Semantic Versioning

libraryのバージョンの決め方は、こちらのサイトを参考にしました。

  • APIの変更に互換性のない場合はメジャーバージョンを、
  • 後方互換性があり機能性を追加した場合はマイナーバージョンを、
  • 後方互換性を伴うバグ修正をした場合はパッチバージョンを上げます

ということです。今回のiioptのupdateは機能追加だけなので、v0.2.0 としました。

まとめ

以上、自作ライブラリのバージョンの上げ方をまとめました。SemVerについては深掘りが足りてないので、おいおいちゃんと読んでいこうと思います。

TypeScript & Jest & VSCode環境でDebuggerを動かす

モチベーション

  • TypeScript & Jest & VSCode環境でDebuggerを動かしたい。
  • ちゃんと設定ファイルを見れていなかったので、これを期に一通り確認したい

動作内容

test以外のコードでも、debuggerは効きます。

f:id:selmertsx:20180118213748p:plain f:id:selmertsx:20180118213806p:plain

設定ファイル一覧

vscodeの設定

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Debug Jest",
      "preLaunchTask": "build", 
      "program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
      "args": [
        "${file}",
        // 現在のプロセスで逐次テストを実行していく設定.
        // この設定をしないと複数のchildプロセスでテストを実行するらしい
        // cliのpackage の性質上、子プロセスがテスト画像を変更してしまうリスクがあるし、
        // debuggingのために有用とのことだったので、この設定を有効にした
        // https://facebook.github.io/jest/docs/en/cli.html#runinband
        "--runInBand", 
        // debugの際はcacheを無効にした。
        // cacheを無効にすると、2倍くらい遅くなるらしい。
        "--no-cache"
      ],
      "cwd": "${workspaceRoot}",
      "console": "integratedTerminal"
    }
  ]
}

tasks.json

https://vscode-doc-jp.github.io/docs/userguide/tasks.html

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build",
      "type": "shell",
      "command": "yarn build"
    }
  ]
}

とりあえず、テスト前にbuildすれば良いだけの設定。 typeのところには、npm, shell, gulpが使えるようだ。下記資料参照。 https://github.com/Microsoft/vscode/blob/master/.vscode/tasks.json typeのところにyarnが無かったので、shellとおいて commandの部分に yarn buildと書いた。

jest.config.json

https://facebook.github.io/jest/docs/en/configuration.html

module.exports = {
  rootDir: "./",
  transform: {
    "^.+\\.tsx?$": "ts-jest"
  },
  testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
  modulePathIgnorePatterns: [
    "<rootDir>/build/"
  ],
  moduleFileExtensions: [
    "ts",
    "js",
    "json"
  ]
}

transform はソースコードを変換する必要があるものを正規表現で記載するもの。 typescriptなど利用している場合は、ここに記載する必要がある。 typescriptを使う場合、jest本家は下記のようにコンパイルしている。 https://github.com/facebook/jest/blob/master/examples/typescript/package.json#L18

今回は ts-jestを利用しているため、ts-jestのドキュメントが指定する通りにした。 https://github.com/kulshekhar/ts-jest#usage

tsconfig.json

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "alwaysStrict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": false,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "noUnusedParameters": false,
    "noUnusedLocals": false,
    "outDir": "../build/",
    "removeComments": true,
    "strictNullChecks": false,
    "target": "es5",
    "traceResolution": false
  },
  "include": [
    "**/*.ts"
  ],
  "exclude": [
    "**/*.spec.ts"
  ]
}

debugのための設定としては、exclude の部分だけである。 testコードはcompileする必要がないので、excludeに含めた。

Serverless Architecture を翻訳しようとしてFAQを読んだ

Frequently Asked Questions

モチベーション

serverlessに関して、体系的な知識を身につけたかったので、下記ページの読んで、自分のブログに理解した内容を掲載したかった。

martinfowler.com

FAQの内容

Frequently Asked Questions

Can I translate one of your web articles?

In general I'm happy for people to do translations. However in recent months I've learned that many translations that are done are of poor quality. So if you do a translation I will try to check that it's of decent quality by finding a colleague to take a look it. As long as they tell me it's ok, I'm happy for it to be posted. I do need you to put a link to the original article and the date of the translation in the translation. (The date helps people spot if I've changed the article since the translation.) Once you've done that please let me know and I will link to it in my paper, (but that may take a while if I'm busy traveling). The only exception to this is material that I'm working into a book. I have to be careful with these since they will be published commercially.

I'm afraid I don't host translations on martinfowler.com as I'm not comfortable serving up text that I can't comprehend.

I haven't checked the older translations to see if they are of decent quality, if you see one that is of poor quality, please email me and I'll at least remove the link.

翻訳したものを公開するときは、その文章が正しいかどうかチェックしたいから、必ず fowler氏のチェックを通してねとのこと。

結論

martinfowler.com の文章を翻訳するときは、必ずfowlerさんにemailで送ってチェックして貰うこと。チェックしてもらってない文章は、ブログに掲載しないこと。

TypeScriptで書いたcliのnpm packageをリリースする方法

背景

人生初のnpm packageをリリースしました。

画像を所定のフォーマットで圧縮してくれるCLIです。現在はシンプルに画像を圧縮するだけですが、おいおい未圧縮の画像を検知する機能であったり、gitのpre-commitにhookして自動で圧縮する機能などを追加していこうと考えています。なお、このpackageはTypeScriptで書かれています。

本日のブログでは、npm packageをリリースする方法、TypeScript(altJS 全般で使えそう)でnpm packageを作る際の方法、npm packageでcliを作る際の注意点について記載していきます。

なお、今回の npm package が僕の初めてのリリースですので、間違った部分や至らない部分があるかもしれません。そこを意識して見て頂ければ幸いです。誤りなどありましたら、コメントを頂けると喜びます!

npm packageをリリースする

シンプルな npm packageであれば、下記の手順を踏めば簡単に npm packageをpublishすることが可能です。

  • npmjs にユーザー登録する
  • npm config にnpmjsに登録したユーザー情報を設定する
  • npm の2要素認証設定をする
  • npm packageをpublishする

以降、図を使いながらより詳細に説明していきます。

npmjsにユーザー登録する

https://www.npmjs.com/signup

上記URLにアクセスして npmjs.com に自分のユーザーを作ります。説明どおりにやれば大丈夫です。

f:id:selmertsx:20180111192236p:plain

npm configにユーザー情報を設定する

terminal から npm login と叩いて、npmjs に登録したユーザー情報を入力します。 問題なく設定できてたら、npm whoami と叩くと自分のユーザー名が返されます。

$ npm login
Username: ${yourName}
Password:
Email: (this IS public) ${yourEmail}
Logged in as shuhei.morioka on https://registry.npmjs.org/.
$ npm whoami
${yourName}

参考URL: Redirecting…

2要素認証をする

自分のpackageに悪さされないように、2要素認証も入れておきましょう。

Requires npm version 5.5.1 or greater

2要素認証は、 バージョンが5.5.1以上のnpmから対応されているため、必要であればnpmのバージョンを上げましょう。

$ npm -v
3.10.10
$ npm update -g npm
/nodepath/node/v6.10.3/lib
└── npm@5.6.0
$ npm -v
5.6.0
$ npm profile enable-2fa

するとバーコードがterminal上で表示されるので、表示されたバーコードを使って2要素認証の設定ができるようになります。

参考URL: Redirecting…

npm packageをpublishする

$ npm publish --access public (--otp xxxx)

上記コマンドで作成したpackageをリリースすることができます。ただし2要素認証の設定をしていた場合、--otpのあとにotpcodeを入力することを忘れないで下さい。

TypeScriptでnpm packageを作る

nodejsのシンプルなコードであれば、上記の手順でnpm packageをpublishすることができます。ただしTypeScriptなどのaltJSを使って開発をしている場合、build後のコードはGitでは管理しないけれども、packageには含めたくなります。

gitでは管理していないコードをpackagesに含めるための方法は2つあって、.npmignoreを使う方法と、packages.jsonのfiles fieldを利用する方法です。ざっくり書くと .npmignoreはブラックリストであって、packages.jsonのfiles fieldはホワイトリストになります。確認が容易なものではないので、何を入れるのか明示的に指定したほうが事故がないと判断し、今回は packages.json の files fieldを採用しました。

packages.json の files field

ioptにおける files field の設定内容は下記のように、たった2行になります。

# packages.json
  "files": [
    "build",
    "bin"
  ],

iiopt/package.json at master · speee/iiopt · GitHub

files fieldはデフォルトで、package.json、README、CHANGES、LICENSE、NOTICE 等のファイルを含めます。なので、ここに記載するコードは少なくてすみます。

https://docs.npmjs.com/files/package.json#files

altJSを使った npm packageをリリースする上で、必要だった作業は僕がやった限りこれだけでした。

npm packageでCLIを作る上での注意点

CLIツールのコマンドは、参考資料に示すように bin fieldに実行コードへのパスを指定し、yarn linkすることによって使えるようになります。

# packages.json
  "bin": {
    "iiopt": "./bin/cli"
  },
$ yarn link
yarn link v1.3.2
success Registered "@speee/iiopt".
info You can now run `yarn link "@speee/iiopt"` in the projects where you want to use this module and it will be used instead.
✨  Done in 0.14s.

yarn linkを実行した際に、/usr/local/bin/iiopt に対して、bin fieldsで指定したコードのパスへのリンクを貼ることで、コマンドが使えるようになります。

$ ls -l /usr/local/bin/iiopt
/usr/local/bin/iiopt -> /path_to_iiopt/iiopt/bin/cli

その他

packages.jsonの整理や抜け漏れチェックには fixpackが便利だった

nodejsで開発をしていると、packages.jsonの要素の順番がごちゃごちゃしてきたりします。 また初めてのnpm package開発だと、packages.jsonに何を記載すれば良いのか分からないと思います。 fixpackは、その問題に対する解決方法になります。

$ fixpack
missing main
package.json already clean!

上が、fixpackの実行結果になります。packages.jsonの中に記載されていない情報があれば、通知してくれます。また、中の要素もfixpack指定の順番に並べてくれます。

最後

以上、npm packageをリリースする方法を記載しました。

参考URL

公式ドキュメント以外で参照したページです。お世話になりました。

2018年の抱負 (4月まで)

2017年は、ふわっと目標を定めたので、ふわっと終わってしまいました。2018年は、もう少し具体的に目標を定めて、言語化し、達成してきたいと思っています。

目標のざっくり全体像

2018年は、一言で言うとエンジニアとしての基礎力を上げるということをテーマとしてやっていこうと思います。より具体的に言うと、下記の内容です。

  • 自らがサービスで利用しているコアな技術に関して、選定理由を明確に語ることができる
    • どの条件が変われば、他の技術の方に軍配が上がるのかも説明できる
  • サーバーサイドエンジニアの領域に関して、現在のトレンドを幅広く把握している
  • 英語での読み書きが開発に支障無い範囲内で行える

具体例で言うと、ゆううきさんみたいに、深い技術的な理解に基づいた文章が書けるエンジニアにあこがれています。

もうちょっと具体的な目標

  • 継続してキャッチアップするもの
  • ちゃんとやってみるもの
    • serverless
    • nodejs
  • 一通り触ってみるもの
    • docker & k8s
    • react
  • その他

4月までの詳細な目標

とりあえず、4月までの目標をざざっと書いてみます。 細ければ細かいほど良いと思うので、思いつく限り書きまくります。 OKRの考え方にもとづいて、全体の70%くらい実現できたらいいなと。 業務のことはとりあえず、置いといてます。

  • serverlessについて語れるようになる
    • https://martinfowler.com/articles/serverless.html これ読んでブログにまとめる
    • micro service について把握する
      • serverlessはmicro serviceからの流れを組むものだと思っているので、その流れなどを語れるようになる
    • https://github.com/selmertsx/serverless-prpolice これを作り切る
      • PR policeを AWS SAM Localを使ってリプレイスしたもの
    • serverless-prpoliceに関して、エラー監視をできるようにする
    • serverless-prpoliceに関して、トラフィック監視をできるようにする
    • serverless-prpoliceに関して、適切なデプロイ戦略を考えることができる
    • これらの知識をまとめて技術書展で本を出す
  • 英語頑張る
    • 1日1時間は勉強する
    • 1日1時間半勉強する
    • TOEIC 受ける
    • TOEIC 700点
    • TOEIC 800点
  • その他
    • ふつうのLINUXプログラミングを読了する
    • ふつうのLINUXプログラミングをブログにまとめる
    • 週2~3本はブログ書く
    • 週1本は、ちゃんと頭を使い切ったブログを書く

どうして serverlessを選んだのか

個人的には serverlessは将来、webサービス開発における選択肢として、十分に挙がってくるものになると考えています。

今のserverlessでは、コードをコンテナにデプロイし、使い終わったら破棄するという仕組みのため、大きなコードを用意してしまったらデプロイに時間が掛かってしまい早いレスポンスが返せない。サービスが拡大したとき、functionの関連性を管理することが難しい。などなどデメリットも多くあります。

しかしながら、AWSを見ていると大きなメモリやコードを許容できるようにする動きもありますし、awslabにて expressフレームワークで作った webサービスをlambdaで動かす実験的なコードも生まれてきました。 GitHub - awslabs/aws-serverless-express: Run serverless applications and REST APIs using your existing Node.js application framework, on top of AWS Lambda and Amazon API Gateway

今ある serverlessの欠点の多くは、仕組み以上に、エコシステムに起因する部分が大きいのではないかと感じていて、AWSはそこの解決に力を入れているように見えています。そこをやりきった後には、今とは違う形の serverlessの世界が見えてくるのでは無いかと思ってちゃんとキャッチアップしてみることにしました。

今のところまだまだ感覚で話してはいますが、3ヶ月後はこれについて自信を持って話せるようになりたいですな。 それでもって、良い所感を持てたら、この分野でOSS等にコミットしていきたいと思ったり思わなかったり。

後半力尽きましたが、2018年前半の抱負はこんな感じでいこうと思います!