経緯
前にMacでdirectのボット開発環境構築作ったけどWindowsでの手順メモ作っておく
https://qiita.com/taketakekaho/items/4fbaa34924d67c9bac60
私のPC環境
- Windows 1803 Build 17134.765
- Node.js v11.13.0
- npm v6.7.0
- nodistを入れるとnpmも一緒に入ります。ローカルに直接Node.jsをインストールしていてnpmが入っていない方は
sudo apt-get install npm
コマンドでインストールできます。
- nodistを入れるとnpmも一緒に入ります。ローカルに直接Node.jsをインストールしていてnpmが入っていない方は
- nodist v0.9.1
- nodistはWindowsでNode.jsのバージョン管理をするツールです。こちらのqiita記事がわかりやすいかと思います。私はDocumentフォルダではなくC:\Program Files (x86)に入れてます。
- nodistの古いバージョンには不具合が含まれるので最新を入れた方がよいかと思います。手順はこちら参考
- Python3.7
- daabの中にはwebsocketが入っていて、インストールするためにPythonがないとインストールが途中で止まるっぽい。
PS C:\Users\take> node -v
v11.13.0
PS C:\Users\take> npm -v
6.7.0
PS C:\Users\take> nodist -v
0.9.1
のちほどDockerで環境作る手順メモも作る予定。
node.jsのバージョンを変える
Node.js初心者の方はdaab公式ドキュメントのと同じNode.jsのバージョンにしておきましょう。インストール可能なバージョンを確認するために以下のコマンドを実行します。
>nodist dist
0.1.14
0.1.15
0.1.16
0.1.17
…
6.9.0
6.9.1
6.9.2
6.9.3
…
12.3.0
12.3.1
12.4.0
>
バージョンを変えたい6.9.2が表示されていることを確認して6.9.2をインストールします。
>nodist add v6.9.2
PS C:\Users\take> nodist add v6.9.2
6.9.2 [===============] 18078/18078 KiB 100% 0.0s
6.9.2
PS C:\Users\take>
アクティブなnodeを確認すると、まだv11.13.0がアクティブな状態になってます
PS C:\Users\take> nodist
(x64)
6.9.2
> 11.13.0 (global: 11.13.0)
PS C:\Users\take>
バージョンを切り替え、v6.9.2がアクティブになったことを確認します。
PS C:\Users\take> nodist v6.9.2
v6.9.2
v6.9.2 (global)
PS C:\Users\take> nodist
(x64)
> 6.9.2 (global: v6.9.2)
11.13.0
PS C:\Users\take>
npmのバージョンをnodeに合わせるコマンドを実行しておきます。
PS C:\Users\take> nodist npm match
npm match
https://codeload.github.com/npm/cli/tar.gz/v3.10.9 [============== ] 3057/3281 KiB 93% 0.1s
PS C:\Users\take> npm -v
3.10.9
PS C:\Users\take>
daab SDKをインストール
あとはdaabドキュメントに従ってセットアップしていきます。
PS C:\Users\take> npm install -g daab
C:\Program Files (x86)\Nodist\bin\daab -> C:\Program Files (x86)\Nodist\bin\node_modules\daab\lib\daab.js
> websocket@1.0.23 install C:\Program Files (x86)\Nodist\bin\node_modules\daab\node_modules\websocket
> (node-gyp rebuild 2> builderror.log) || (exit 0)
C:\Program Files (x86)\Nodist\bin\node_modules\daab\node_modules\websocket>if not defined npm_config_node_gyp (node "C:\Program Files (x86)\Nodist\npmv\3.10.9\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node "" rebuild )
C:\Program Files (x86)\Nodist\bin
`-- daab@0.1.8
+-- commander@2.20.0
+-- direct-js@0.1.32
| +-- node-localstorage@1.3.0
| | `-- write-file-atomic@1.3.4
| | +-- graceful-fs@4.1.15
| | +-- imurmurhash@0.1.4
| | `-- slide@1.1.6
| +-- tunnel-agent@0.6.0
| | `-- safe-buffer@5.1.2
| +-- unorm@1.4.1
| `-- websocket@1.0.23
| +-- debug@2.6.9
| | `-- ms@2.0.0
| +-- nan@2.14.0
| +-- typedarray-to-buffer@3.1.5
| | `-- is-typedarray@1.0.0
| `-- yaeti@0.0.4
+-- dotenv@4.0.0
+-- read@1.0.7
| `-- mute-stream@0.0.8
`-- rimraf@2.6.3
`-- glob@7.1.4
+-- fs.realpath@1.0.0
+-- inflight@1.0.6
| `-- wrappy@1.0.2
+-- inherits@2.0.4
+-- minimatch@3.0.4
| `-- brace-expansion@1.1.11
| +-- balanced-match@1.0.0
| `-- concat-map@0.0.1
+-- once@1.4.0
`-- path-is-absolute@1.0.1
インストールされたことを確認
helpコマンドとバージョン確認で正常にインストールできてるか確認します。
PS C:\Users\take> daab -V
0.1.8
PS C:\Users\take> daab help
Usage: daab [options] [command]
Options:
-V, --version output the version number
-h, --help output usage information
Commands:
init setup the daab environment.
login login as a bot account.
logout logout from the service.
run run the daab. (Ctrl-C to stop)
start run the daab as a deamon.
stop stop the daab deamon.
deploy upload the server.
invites show and accept a domain invite.
help [cmd] display help for [cmd]
PS C:\Users\take>
ボットフォルダにボットアプリを作成
アプリケーションを配置するフォルダを作成してカレントを移動します。私はいつもデスクトップにあるcode用フォルダの中に開発するアプリケーション置いてますので以下になります。
PS C:\Users\take> cd .\Desktop\code\
PS C:\Users\take\Desktop\code> mkdir myfirstdaab
PS C:\Users\take\Desktop\code> cd .\myfirstdaab\
PS C:\Users\take\Desktop\code\myfirstdaab> pwd
Path
----
C:\Users\take\Desktop\code\myfirstdaab
PS C:\Users\take\Desktop\code\myfirstdaab>
※コマンドプロンプトだとpwd
ではなくdir
で確認できます。
ここにボットアプリを作成します。
PS C:\Users\take\Desktop\code\myfirstdaab> daab init
Initialized empty Git repository in C:/Users/take/Desktop/code/myfirstdaab/.git/
remote: Enumerating objects: 288, done.
remote: Total 288 (delta 0), reused 0 (delta 0), pack-reused 288
Receiving objects: 100% (288/288), 503.19 KiB | 817.00 KiB/s, done.
Resolving deltas: 100% (116/116), done.
From https://github.com/lisb/daab-starter
* branch master -> FETCH_HEAD
* [new branch] master -> daab-starter/master
daab initialized.
PS C:\Users\take\Desktop\code\myfirstdaab>
ボットアカウントにログイン
作成したボットアプリをボットアカウントに接続します。まずはdirectのボット用のアカウントを用意してください。自分のアカウント使ってもいいですが、テストするためには自分のアカウントともう一つ別のボット用のアカウントがあった方がいいかと思います。
ボット用アカウントがまだない人はdirect管理者からアカウントを招待します。
ボットっぽいアイコンセットしときます。
それではボットアプリケーションとボットアカウントをつなぎます。先ほどセットしたボット用アカウントのメールアドレスとパスワードの入力を求められますので入力するとつながります。
PS C:\Users\take\Desktop\code\myfirstdaab> daab login
[2019-06-24 01:14:48] WebSocket opened.
Email: hogehoge@example.co.jp
Password:
logged in.
PS C:\Users\take\Desktop\code\myfirstdaab>
daabの実行
ボットアプリケーションを起動します。初回の起動は2,3分くらい時間がかかりました。
PS C:\Users\take\Desktop\code\myfirstdaab> daab run
npm WARN deprecated mixin-deep@1.3.1: Critical bug fixed in v2.0.1, please upgrade to the latest version.
npm WARN deprecated set-value@2.0.0: Critical bug fixed in v3.0.1, please upgrade to the latest version.
npm WARN deprecated set-value@0.4.3: Critical bug fixed in v3.0.1, please upgrade to the latest version.
> websocket@1.0.28 install C:\Users\take\Desktop\code\myfirstdaab\node_modules\websocket
> (node-gyp rebuild 2> builderror.log) || (exit 0)
C:\Users\take\Desktop\code\myfirstdaab\node_modules\websocket>if not defined npm_config_node_gyp (node "C:\Program Files (x86)\Nodist\npmv\3.10.9\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node "" rebuild )
starter@0.3.6 C:\Users\take\Desktop\code\myfirstdaab
+-- lisb-forever@1.0.0
| +-- async@0.2.10
| +-- cliff@0.1.10
| | +-- colors@1.0.3
| | `-- eyes@0.1.8
| +-- clone@1.0.4
| +-- colors@0.6.2
| +-- flatiron@0.4.3
| | +-- broadway@0.3.6
| | | +-- cliff@0.1.9
| | | +-- utile@0.2.1
| | | `-- winston@0.8.0
| | +-- director@1.2.7
| | +-- optimist@0.6.0
| | `-- prompt@0.2.14
| | +-- read@1.0.7
| | | `-- mute-stream@0.0.8
| | +-- revalidator@0.1.8
| | `-- utile@0.2.1
| +-- forever-monitor@1.7.1
| | +-- chokidar@1.7.0
| | | +-- anymatch@1.3.2
| | | | +-- micromatch@2.3.11
| | | | | +-- arr-diff@2.0.0
| | | | | | `-- arr-flatten@1.1.0
| | | | | +-- array-unique@0.2.1
| | | | | +-- braces@1.8.5
| | | | | | +-- expand-range@1.8.2
| | | | | | | `-- fill-range@2.2.4
| | | | | | | +-- is-number@2.1.0
| | | | | | | +-- isobject@2.1.0
| | | | | | | `-- randomatic@3.1.1
| | | | | | | +-- is-number@4.0.0
| | | | | | | +-- kind-of@6.0.2
| | | | | | | `-- math-random@1.0.4
| | | | | | +-- preserve@0.2.0
| | | | | | `-- repeat-element@1.1.3
| | | | | +-- expand-brackets@0.1.5
| | | | | | `-- is-posix-bracket@0.1.1
| | | | | +-- extglob@0.3.2
| | | | | +-- filename-regex@2.0.1
| | | | | +-- kind-of@3.2.2
| | | | | | `-- is-buffer@1.1.6
| | | | | +-- object.omit@2.0.1
| | | | | | +-- for-own@0.1.5
| | | | | | | `-- for-in@1.0.2
| | | | | | `-- is-extendable@0.1.1
| | | | | +-- parse-glob@3.0.4
| | | | | | +-- glob-base@0.3.0
| | | | | | `-- is-dotfile@1.0.3
| | | | | `-- regex-cache@0.4.4
| | | | | `-- is-equal-shallow@0.1.3
| | | | | `-- is-primitive@2.0.0
| | | | `-- normalize-path@2.1.1
| | | | `-- remove-trailing-separator@1.1.0
| | | +-- async-each@1.0.3
| | | +-- glob-parent@2.0.0
| | | +-- inherits@2.0.4
| | | +-- is-binary-path@1.0.1
| | | | `-- binary-extensions@1.13.1
| | | +-- is-glob@2.0.1
| | | | `-- is-extglob@1.0.0
| | | `-- readdirp@2.2.1
| | | +-- graceful-fs@4.1.15
| | | +-- micromatch@3.1.10
| | | | +-- arr-diff@4.0.0
| | | | +-- array-unique@0.3.2
| | | | +-- braces@2.3.2
| | | | | +-- extend-shallow@2.0.1
| | | | | +-- fill-range@4.0.0
| | | | | | +-- extend-shallow@2.0.1
| | | | | | +-- is-number@3.0.0
| | | | | | | `-- kind-of@3.2.2
| | | | | | +-- repeat-string@1.6.1
| | | | | | `-- to-regex-range@2.1.1
| | | | | | `-- is-number@3.0.0
| | | | | +-- isobject@3.0.1
| | | | | +-- snapdragon-node@2.1.1
| | | | | | +-- define-property@1.0.0
| | | | | | | `-- is-descriptor@1.0.2
| | | | | | | +-- is-accessor-descriptor@1.0.0
| | | | | | | +-- is-data-descriptor@1.0.0
| | | | | | | `-- kind-of@6.0.2
| | | | | | +-- isobject@3.0.1
| | | | | | `-- snapdragon-util@3.0.1
| | | | | `-- split-string@3.1.0
| | | | +-- define-property@2.0.2
| | | | | +-- is-descriptor@1.0.2
| | | | | | +-- is-accessor-descriptor@1.0.0
| | | | | | +-- is-data-descriptor@1.0.0
| | | | | | `-- kind-of@6.0.2
| | | | | `-- isobject@3.0.1
| | | | +-- extend-shallow@3.0.2
| | | | | +-- assign-symbols@1.0.0
| | | | | `-- is-extendable@1.0.1
| | | | | `-- is-plain-object@2.0.4
| | | | | `-- isobject@3.0.1
| | | | +-- extglob@2.0.4
| | | | | +-- define-property@1.0.0
| | | | | | `-- is-descriptor@1.0.2
| | | | | | +-- is-accessor-descriptor@1.0.0
| | | | | | `-- is-data-descriptor@1.0.0
| | | | | +-- expand-brackets@2.1.4
| | | | | | +-- define-property@0.2.5
| | | | | | | `-- is-descriptor@0.1.6
| | | | | | | +-- is-accessor-descriptor@0.1.6
| | | | | | | | `-- kind-of@3.2.2
| | | | | | | +-- is-data-descriptor@0.1.4
| | | | | | | | `-- kind-of@3.2.2
| | | | | | | `-- kind-of@5.1.0
| | | | | | +-- extend-shallow@2.0.1
| | | | | | `-- posix-character-classes@0.1.1
| | | | | `-- extend-shallow@2.0.1
| | | | +-- fragment-cache@0.2.1
| | | | | `-- map-cache@0.2.2
| | | | +-- kind-of@6.0.2
| | | | +-- nanomatch@1.2.13
| | | | | +-- arr-diff@4.0.0
| | | | | +-- array-unique@0.3.2
| | | | | +-- is-windows@1.0.2
| | | | | `-- kind-of@6.0.2
| | | | +-- object.pick@1.3.0
| | | | | `-- isobject@3.0.1
| | | | +-- regex-not@1.0.2
| | | | | `-- safe-regex@1.1.0
| | | | | `-- ret@0.1.15
| | | | +-- snapdragon@0.8.2
| | | | | +-- base@0.11.2
| | | | | | +-- cache-base@1.0.1
| | | | | | | +-- collection-visit@1.0.0
| | | | | | | | +-- map-visit@1.0.0
| | | | | | | | `-- object-visit@1.0.1
| | | | | | | | `-- isobject@3.0.1
| | | | | | | +-- get-value@2.0.6
| | | | | | | +-- has-value@1.0.0
| | | | | | | | +-- has-values@1.0.0
| | | | | | | | | +-- is-number@3.0.0
| | | | | | | | | | `-- kind-of@3.2.2
| | | | | | | | | `-- kind-of@4.0.0
| | | | | | | | `-- isobject@3.0.1
| | | | | | | +-- isobject@3.0.1
| | | | | | | +-- set-value@2.0.0
| | | | | | | | `-- extend-shallow@2.0.1
| | | | | | | +-- to-object-path@0.3.0
| | | | | | | +-- union-value@1.0.0
| | | | | | | | `-- set-value@0.4.3
| | | | | | | | `-- extend-shallow@2.0.1
| | | | | | | `-- unset-value@1.0.0
| | | | | | | +-- has-value@0.3.1
| | | | | | | | +-- has-values@0.1.4
| | | | | | | | `-- isobject@2.1.0
| | | | | | | `-- isobject@3.0.1
| | | | | | +-- class-utils@0.3.6
| | | | | | | +-- arr-union@3.1.0
| | | | | | | +-- define-property@0.2.5
| | | | | | | +-- isobject@3.0.1
| | | | | | | `-- static-extend@0.1.2
| | | | | | | +-- define-property@0.2.5
| | | | | | | `-- object-copy@0.1.0
| | | | | | | +-- copy-descriptor@0.1.1
| | | | | | | `-- define-property@0.2.5
| | | | | | +-- component-emitter@1.3.0
| | | | | | +-- define-property@1.0.0
| | | | | | | `-- is-descriptor@1.0.2
| | | | | | | +-- is-accessor-descriptor@1.0.0
| | | | | | | +-- is-data-descriptor@1.0.0
| | | | | | | `-- kind-of@6.0.2
| | | | | | +-- isobject@3.0.1
| | | | | | +-- mixin-deep@1.3.1
| | | | | | | `-- is-extendable@1.0.1
| | | | | | `-- pascalcase@0.1.1
| | | | | +-- define-property@0.2.5
| | | | | | `-- is-descriptor@0.1.6
| | | | | | +-- is-accessor-descriptor@0.1.6
| | | | | | +-- is-data-descriptor@0.1.4
| | | | | | `-- kind-of@5.1.0
| | | | | +-- extend-shallow@2.0.1
| | | | | +-- source-map@0.5.7
| | | | | +-- source-map-resolve@0.5.2
| | | | | | +-- atob@2.1.2
| | | | | | +-- decode-uri-component@0.2.0
| | | | | | +-- resolve-url@0.2.1
| | | | | | +-- source-map-url@0.4.0
| | | | | | `-- urix@0.1.0
| | | | | `-- use@3.1.1
| | | | `-- to-regex@3.0.2
| | | `-- readable-stream@2.3.6
| | | +-- core-util-is@1.0.2
| | | +-- isarray@1.0.0
| | | +-- process-nextick-args@2.0.1
| | | +-- string_decoder@1.1.1
| | | `-- util-deprecate@1.0.2
| | +-- minimatch@3.0.4
| | | `-- brace-expansion@1.1.11
| | | +-- balanced-match@1.0.0
| | | `-- concat-map@0.0.1
| | +-- ps-tree@0.0.3
| | | `-- event-stream@0.5.3
| | | `-- optimist@0.2.8
| | `-- utile@0.2.1
| | +-- deep-equal@1.0.1
| | `-- ncp@0.4.2
| +-- mkdirp@0.5.1
| | `-- minimist@0.0.8
| +-- nconf@0.6.9
| | +-- async@0.2.9
| | +-- ini@1.3.5
| | `-- optimist@0.6.0
| +-- nssocket@0.5.3
| | +-- eventemitter2@0.4.14
| | `-- lazy@1.0.11
| +-- object-assign@3.0.0
| +-- optimist@0.6.1
| | +-- minimist@0.0.10
| | `-- wordwrap@0.0.3
| +-- path-is-absolute@1.0.1
| +-- prettyjson@1.2.1
| | +-- colors@1.3.3
| | `-- minimist@1.2.0
| +-- shush@1.0.0
| | +-- caller@0.0.1
| | | `-- tape@2.3.3
| | | +-- deep-equal@0.1.2
| | | +-- defined@0.0.0
| | | +-- jsonify@0.0.0
| | | +-- resumer@0.0.0
| | | `-- through@2.3.8
| | `-- strip-json-comments@0.1.3
| +-- utile@0.3.0
| | +-- async@0.9.2
| | +-- deep-equal@0.2.2
| | +-- i@0.3.6
| | +-- ncp@1.0.1
| | `-- rimraf@2.6.3
| | `-- glob@7.1.4
| | +-- fs.realpath@1.0.0
| | +-- inflight@1.0.6
| | | `-- wrappy@1.0.2
| | `-- once@1.4.0
| `-- winston@0.8.3
| +-- cycle@1.0.3
| +-- isstream@0.1.2
| +-- pkginfo@0.3.1
| `-- stack-trace@0.0.10
+-- lisb-hubot@3.3.2
| +-- chalk@1.1.3
| | +-- ansi-styles@2.2.1
| | +-- escape-string-regexp@1.0.5
| | +-- has-ansi@2.0.0
| | | `-- ansi-regex@2.1.1
| | +-- strip-ansi@3.0.1
| | `-- supports-color@2.0.0
| +-- cline@0.8.2
| +-- coffeescript@1.6.3
| +-- connect-multiparty@2.2.0
| | +-- http-errors@1.7.2
| | | +-- inherits@2.0.3
| | | `-- toidentifier@1.0.0
| | +-- multiparty@4.2.1
| | | +-- fd-slicer@1.1.0
| | | | `-- pend@1.2.0
| | | `-- uid-safe@2.1.5
| | | `-- random-bytes@1.0.0
| | +-- on-finished@2.3.0
| | | `-- ee-first@1.1.1
| | +-- qs@6.5.2
| | `-- type-is@1.6.18
| | +-- media-typer@0.3.0
| | `-- mime-types@2.1.24
| | `-- mime-db@1.40.0
| +-- express@4.17.1
| | +-- accepts@1.3.7
| | | `-- negotiator@0.6.2
| | +-- array-flatten@1.1.1
| | +-- body-parser@1.19.0
| | | +-- bytes@3.1.0
| | | +-- iconv-lite@0.4.24
| | | | `-- safer-buffer@2.1.2
| | | +-- qs@6.7.0
| | | `-- raw-body@2.4.0
| | +-- content-disposition@0.5.3
| | +-- content-type@1.0.4
| | +-- cookie@0.4.0
| | +-- cookie-signature@1.0.6
| | +-- debug@2.6.9
| | | `-- ms@2.0.0
| | +-- depd@1.1.2
| | +-- encodeurl@1.0.2
| | +-- escape-html@1.0.3
| | +-- etag@1.8.1
| | +-- finalhandler@1.1.2
| | | `-- unpipe@1.0.0
| | +-- fresh@0.5.2
| | +-- merge-descriptors@1.0.1
| | +-- methods@1.1.2
| | +-- parseurl@1.3.3
| | +-- path-to-regexp@0.1.7
| | +-- proxy-addr@2.0.5
| | | +-- forwarded@0.1.2
| | | `-- ipaddr.js@1.9.0
| | +-- qs@6.7.0
| | +-- range-parser@1.2.1
| | +-- safe-buffer@5.1.2
| | +-- send@0.17.1
| | | +-- destroy@1.0.4
| | | +-- mime@1.6.0
| | | `-- ms@2.1.1
| | +-- serve-static@1.14.1
| | +-- setprototypeof@1.1.1
| | +-- statuses@1.5.0
| | +-- utils-merge@1.0.1
| | `-- vary@1.1.2
| +-- hubot-direct@1.0.1
| | `-- direct-js@1.101.3
| | +-- node-localstorage@1.3.1
| | | `-- write-file-atomic@1.3.4
| | | +-- imurmurhash@0.1.4
| | | `-- slide@1.1.6
| | +-- tunnel-agent@0.6.0
| | +-- unorm@1.5.0
| | `-- websocket@1.0.28
| | +-- nan@2.14.0
| | +-- typedarray-to-buffer@3.1.5
| | | `-- is-typedarray@1.0.0
| | `-- yaeti@0.0.6
| +-- log@1.4.0
| +-- optparse@1.0.4
| `-- scoped-http-client@0.11.0
`-- lisb-hubot-redis-brain@1.0.0
`-- redis@2.8.0
+-- double-ended-queue@2.1.0-0
+-- redis-commands@1.5.0
`-- redis-parser@2.6.0
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
[2019-06-24 01:20:00] WebSocket opened.
[Mon Jun 24 2019 01:20:02 GMT+0900 (東京 (標準時))] INFO hubot-redis-brain: Discovered redis from REDIS_URL environment variable
プロンプトが返ってこず止まったように見えますが、これで正常です。
この状態で、directで動作確認してみます。
daab動作確認
daabにはデフォルトで動作確認要のpigアプリが存在しますのでdaab起動した状態で動作確認してみます。ボットアカウントとのルームでping
とメッセージを送るとPONG
と返ってくれば正常に動作しています。
一旦止める場合には[Ctrl]+C
で止められます。
^Cバッチ ジョブを終了しますか (Y/N)? Y
PS C:\Users\take\Desktop\code\myfirstdaab>
これ起動しっぱなしなの?とか毎回起動しないと動かないの?とか思いますが、バックグラウンドで起動する方法があります。
Macの方は.envの中にあるHUBOT_DIRECT_TOKEN=xxxxxxxxxxxxxx
を~/.bashrcの中に書き込むとこちらに書いてある$ bin/hubot start
とかで永続起動した状態を維持できたりするのですが。
Windowsだとどうやるんだろ…
参考リンク
初めてのdaab
npmとは何か
hithub daab