- 投稿日:2019-02-15T22:58:16+09:00
node-cronにスケジュール書式を渡しすぎると値がずれ想定外のスケジュールになる
結論
書式が足りない部分はデフォルトの値が適用される。
簡単に言えば、書式設定が右にずれる。
多すぎた場合はこの少なかったとき用の計算が意図せず働き、設定が左にずれる。例えば、
書式が5個と通常よりひとつ少なかった場合。
1 2 3 4 5
本来秒数指定の場所の左端の値(1)は、右にずれて分数指定の記述として扱われる。
(秒数指定にはデフォルト値の0が指定される)
0 1 2 3 4 5
書式が7個と通常よりひとつ多かった場合。
1 2 3 4 5 6 7
本来日数として指定された値は、左にずれて時数指定の記述として扱われる。
(週の指定にはデフォルト値の*
が指定される)
2 3 4 5 6 7 *
Linuxなどのcrontabは値を5つ指定する(standard cron syntaxと表現)=node-cronではできる秒数指定ができない。
node-cronにstandard cron syntaxが指定されたとき、エラーと意図の相違なくパースさせる処理が、渡しすぎた場合にエラーなく意図と相違あるパースになってしまった。ライブラリ
kelektiv/node-cron: Cron for NodeJS.
Cron Ranges
When specifying your cron values you'll need to make sure that your values fall
within the ranges. For instance, some cron's use a 0-7 range for the day of
week where both 0 and 7 represent Sunday. We do not.
- Seconds: 0-59
- Minutes: 0-59
- Hours: 0-23
- Day of Month: 1-31
- Months: 0-11 (Jan-Dec)
- Day of Week: 0-6 (Sun-Sat)
指定できる場所は6個あることが特徴です。
バージョン
"cron": "^1.4.0"
コード
node-cron/cron.js at 1ec1e81eba34fc0b2c034ea65c943ba62b3e16b4 · kelektiv/node-cron
var timeUnits = [ 'second', 'minute', 'hour', 'dayOfMonth', 'month', 'dayOfWeek' ]; CronTime.parseDefaults = ['0', '*', '*', '*', '*', '*']; CronTime.prototype = { _parse: function() { var aliases = CronTime.aliases; var source = this.source.replace(/[a-z]{1,3}/gi, function(alias) { alias = alias.toLowerCase(); if (alias in aliases) { return aliases[alias]; } throw new Error('Unknown alias: ' + alias); }); var split = source.replace(/^\s\s*|\s\s*$/g, '').split(/\s+/); var cur; var i = 0; var len = timeUnits.length; for (; i < timeUnits.length; i++) { // If the split source string doesn't contain all digits, // assume defaults for first n missing digits. // This adds support for 5-digit standard cron syntax cur = split[i - (len - split.length)] || CronTime.parseDefaults[i]; this._parseField(cur, timeUnits[i], CronTime.constraints[i]); } },
source
が渡した書式です。
* * * * *
ならStandard cron syntax。左端は分です。
* * * * * *
ならcron-node用のsyntax。左端は秒です。
0 0 0 * * * *
これが今回誤って渡していた書式です。毎日0時に実行してほしいつもりが、毎時実行になっていました。
cur = split[i - (len - split.length)] || CronTime.parseDefaults[i];
このコード、len
は6で固定です。node-cronのsyntaxが渡された場合、
(len - split.length)
は常に0なので、そのままの値が順番に渡されます。
Standard cron syntaxが渡されたとき、
i = 0
、秒数のパースの際は、
cur = split[0 - (6 - 5)] || CronTime.parseDefaults[0];
と
split[-1]
が参照されることになり、当然undefined
なのでparseDefaults[0]
が適用されます。以降、Standard cron syntaxで指定された分数指定、split[0]は、
i = 1
のとき、
cur = split[1 - (6 - 5)] || CronTime.parseDefaults[1];
となりsplit[0]
がnode-cronのsyntaxでの分数([1]
)として入り、整合性がとれます。
0 0 0 * * * *
を渡した場合。
split.length
は7で、(len - split.length)
は常に-1
。
- (len - split.length)
なので常に+1
されることになります。
i = 0
の場合、
cur = split[0 + 1] || CronTime.parseDefaults[0];
で秒数にsplit[1]、分と考えていたものがズレて入りました。時を指定する
i = 2
では
cur = split[2 + 1] || CronTime.parseDefaults[2];
でsplit[3] = *
が時間の値として処理され、毎時実行になりました。
コードのコメントにあるように、この引き算は
5-digit standard cron syntax
をサポートするためのものです。
なので、7-digit cron syntax
などという不正な書式はエラーにしてしまうことが、本来は正しいのかもしれません。
CronTime day of week is non-standard (Sunday is 1, not 0) · Issue #36 · kelektiv/node-cron
サポートが入った経緯。
- 投稿日:2019-02-15T21:54:28+09:00
Mac に spherov2.js をインストールする
Sphero Mini を Mac で制御するために、spherov2.js をインストールしたメモ
Node.js のインストール
Node version management をインストール
$ curl -L https://git.io/n-install | bash $ . ~/.bash_profileHomebrew のインストール
Yarn のインストール
$ brew install yarn --ignore-dependenciesspherov2.js のインストール
$ git clone https://github.com/igbopie/spherov2.js $ cd sphero2.js $ yarn installテスト
$ cd examples $ yarn patrol-sm参考にした記事
- 投稿日:2019-02-15T21:54:28+09:00
[WIP] Mac に spherov2.js をインストールする
Node.js のインストール
Node version management をインストール
$ curl -L https://git.io/n-install | bash $ . ~/.bash_profilen コマンドの使い方は、上の GitHub の ドキュメントを参照してください。
たとえば、8.11.3 を使いたい場合は、次のように実行します。$ n v8.11.3Homebrew のインストール
Yarn のインストール
$ brew install yarn --ignore-dependenciesspherov2.js のインストール
$ git clone https://github.com/igbopie/spherov2.js $ cd sphero2.js $ yarn install参考にした記事
- 投稿日:2019-02-15T19:53:39+09:00
Node.jsとAngularのプロジェクトをvscodeでデバッグする
バックエンドにNode.js、フロントエンドにAngularを使っているプロジェクトのデバッグ方法についてです。
まず手始めにバックエンド(Node.js)の開発を行っており、vscodeのlaunch.jsonにnodemonの設定をしてデバッグしていました。
次に、フロントエンド(Angular)の開発に入り、デバッグしようとしたところ、ブレークポイントが効きません。
nodemonじゃフロントのデバッグはできない事を知り、調べて見るとDebugger for Chromeという拡張機能があり、それを使うとフロンドエンド(Angular)のデバックができました。しかしです!
一人で開発する場合は、フロントエンドとバックエンドって、一歩ずつ開発してデバッグするわけです。いちいち、どっちのデバッグをするのかを考えて進めるのは、めんどくさいし、効率が悪い。
そこで、同時にデバッグできる方法はないものかと調べた結果見つけました。
その方法を紹介します。nodemonのインストール
node.jsをデバックするために利用するnodemonをインストールします(nodeでもできますが、nodemonの方がトレースが表示されるので便利)。
npm install nodemon -g
nodemonによるデバッグの設定
.vscodeフォルダにあるlaunch.jsonに、デバッグ時にnodemonが起動するように設定します。
(vscodeのデバッグに行き、プルダウンで構成の追加を選択するとlaunch.jsonを開くことができます)
これで、vscodeでデバッグを開始すると、nodemonが起動し、Node.jsのプログラムがデバックできるようになります。launch.json{ "version": "0.2.0", "configurations": [ // nodemonによるnode.jsのデバック設定 { "type": "node", "request": "launch", "name": "nodemon", "runtimeExecutable": "nodemon", "program": "${workspaceFolder}\\dist\\server\\server.js", "restart": false, "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", "env": { "DEBUG": "express:*" } } ] }Debugger for Chromeによるデバッグの設定
まず、拡張機能「Debugger for Chrome」をインストールします。
インストール後、.vscodeフォルダにあるlaunch.jsonに、Debugger for Chromeを使ってデバックするように設定します。
vscodeのデバッグでchromeを選択して開始すると、chromeが立ち上がってAngularをデバッグできます。launch.json{ "version": "0.2.0", "configurations": [ // Debugger for ChromeによるAngularのデバック設定 ← ここ! { "type": "chrome", "request": "launch", "name": "chrome", "url": "http://localhost:3000", "webRoot": "${workspaceFolder}" }, // nodemonによるnode.jsのデバック設定 { "type": "node", "request": "launch", "name": "nodemon", "runtimeExecutable": "nodemon", "program": "${workspaceFolder}\\dist\\server\\server.js", "restart": false, "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", "env": { "DEBUG": "express:*" } }, ] }AngularとNode.jsを一緒にデバッグする設定
さて、お膳立ては終わりました。
launcher.jsonには、node.jsのデバッグ、angularのデバッグの設定を仕込みました。
これを一緒に起動できれば、どっちもデバッグできるようになるわけです。
launch.jsonに、compoundsセクションを追加します。launch.json{ "version": "0.2.0", "configurations": [ // Debugger for ChromeによるAngularのデバック設定 { "type": "chrome", "request": "launch", "name": "chrome", "url": "http://localhost:3000", "webRoot": "${workspaceFolder}" }, // nodemonによるnode.jsのデバック設定 { "type": "node", "request": "launch", "name": "nodemon", "runtimeExecutable": "nodemon", "program": "${workspaceFolder}\\dist\\server\\server.js", "restart": false, "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", "env": { "DEBUG": "express:*" } } ], // Node.jsとAngularのデバッグを開始する設定 ← ここ! "compounds": [ { "name": "fullstack", "configurations": ["nodemon", "chrome"] } ] }これでvscodeのデバッグにfullstackが表示されます。これを実行すると、Debugger for Chromeとnodemonが起動され、Angularなソースもnode.jsなソースもデバッグできます。
おまけ
nodemonを使うと、node.jsのプロセスが残ったまんまになります。気づくとやたら重たくなっています(私だけでしょうか?Windowsだからでしょうか?)
そこで、nodemonのデバッグが終わった時に、node.jsのプロセスを一掃する仕組みを考えました。task.jsonにnode.jsプロセス一掃設定
.vscodeフォルダにあるtask.jsonに、node.jsプロセスを一掃する設定を行います。
PowerShellのtaskkillコマンドで、node.exeのプロセスを全てkillする設定を行っています。task.json{ "version": "2.0.0", "tasks": [ "label": "stop node", "type": "shell", "command": "taskkill /F /IM node.exe" } ] }launch.jsonにtaskを設定
launch.jsonに、task.jsonで設定したタスクを、nodemonが終了するときに実行するように設定します。
これで、node.jsプロセスが残ったままになりません。
※これはWindows限定の方法です。launch.json{ // nodemonによるnode.jsのデバック設定 { "type": "node", "request": "launch", "name": "nodemon", "runtimeExecutable": "nodemon", "program": "${workspaceFolder}\\dist\\server\\server.js", "restart": false, "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", "env": { "DEBUG": "express:*" }, "postDebugTask": "stop node" ← ここ! } }
- 投稿日:2019-02-15T19:30:23+09:00
Node.js v11.10.0リリースノート
https://nodejs.org/en/blog/release/v11.10.0/
deps
- Updated libuv to 1.26.0.
- libuvを1.25.0から1.26.0に更新
- Updated npm to 6.7.0.
- npmを6.5.0から6.7.0に更新
http, http2
- response.writeHead now returns the response object.
- response.writeHead()が今まで何も返さなかったのを、レスポンスを返すように変更
- これからさらにend()を呼び出すことが可能になった
perf_hooks
- Implemented a histogram based API.
- 頻度分布に基づいた測定用APIを作成?
process
- Exposed process.features.inspector.
- inspectorを使っているかどうかを判断する方法が、process.config.variables.v8_enable_inspectorからprocess.features.inspectorに変更
repl
- Added repl.setupHistory for programmatic repl.
- プログラムでREPLをするときに履歴ログを初期化できる関数repl.setupHistory()を追加
tls
- Introduced client "session" event.
- sessionイベントが通知されるようになった
- 投稿日:2019-02-15T17:58:07+09:00
要チェックな10個の Node.js フレームワーク
本記事は、10 Node.js Frameworks Worth Checking Out: Express, Loopback, Hapi, and Beyond の日本語訳です。
要チェックな10個のNode.js フレームワーク
テクノロジーは急速に変化しているので、開発者たちは新しいテクノロジーを使用し、Web開発のニーズに合わせて、より便利なフレームワークを採用しています。Node.js は、アプリ開発にJavaScriptを使うのが好きな開発者達から、大いに注目されています。
開発者であるあなたは、クライアントサイドとサーバーサイドのスクリプト両方を同じ言語で管理できます。そしてこれは、Nodeの膨大な利用や採用をもたらしました。
Node.js フレームワークは、Web開発の市場で膨大な需要を獲得し続けており、2019年でも、より多くの機能や利点をもたらし続けています。現在のWeb開発の市場で利用されている 人気プログラミング言語 は多岐にわたりますが、2019年最高の Node.js フレームワークは、このWeb開発における開発プロセスを劇的に変えているのです。しかし、深く議論する前に、Node フレームワークとは何かを理解することが重要です
Node.jsは、ブラウザの外部でJavaScriptを実行する、オープンソースかつクロスプラットフォームのJavaScriptランタイム環境です。JavaScript フレームワーク のリストを作成する際に、そのことを無視するわけにはいきません。
JavaScriptは主に、WebページのHTMLに埋め込まれ、ブラウザの JavaScriptエンジンによってクライアントサイドで実行されるスクリプトとして利用されています。
Node.jsは、開発者がコマンドラインツールを書くために、JavaScriptを利用できるようにしています。サーバーサイドスクリプトの場合、アクセス可能なユーザーのブラウザに動的なWebページが表示される以前にて、その動的なWebページのコンテンツを作成するために必要なスクリプトをサーバーサイドで実行します。その結果、Node.jsは、ある特定の1プログラミング言語で、クライアントサイドとサーバーサイド両方のWebアプリケーション開発をまとめるという、「JavaScript everywhere」のパラダイムを体現しているのです。Node.js フレームワークの主な利点
Node.js フレームワークは、同フレームワークが持つ、最高の生産性、高速性、およびスケーラビリティといった驚異的な機能によって、その利用が広まっています。これらすべての機能が、大企業向けのエンタープライズレベルのアプリケーション開発において、Node.jsを最初の選択肢とさせているのです。
Node.jsは、フロントエンドとバックエンドの両方で同じ言語を使用することを可能にしています。これにより、未知のプログラミング言語を学ぶことや、全てのコード構造やプログラムを実行するために、未知のプログラミング言語で実装を行うストレスから解放されます。
Node.js フレームワークの手助けによって、さまざまなツールを使用したり、さまざまなガイドラインを参照することができます。また最終的には、多くの時間を節約する方法にもなるため、お勧めしています。そうしたアプローチによって、あなたはコーディングの分野でプロとなることができるのです。主な利点は次のとおりです。
- 高速で機能する
- データストリーミングをサポート
- リアルタイム動作
- 全てのデータベース問い合わせに対応する解決策がある
- 単純なコーディング
- オープンソース
- クロスプラットフォーム
- プロキシサーバーとして併用できる
- より高い生産性
- 同期の問題に対応
- ユーザーとコミュニティにやさしい
2019年および今後数年間において輝くであろう、上位の Node.js フレームワークたちを見ていきましょう。
1. AdonisJs
AdonisJsは 、すべての主要なオペレーティングシステムで動作する、最も人気のあるNode.js フレームワークの1つです。このフレームワークは、サーバーサイドのWebアプリケーションを作成するための静的なエコシステムを持っているので、ビジネスニーズをターゲットに、どのパッケージを使用するのかを選択することが可能です。最も単純なフレームワークであり、とりわけ開発に焦点を当てています。
AdonisJsの特徴
- SQLデータベースで構成されているORMをサポート
- アクティブレコードのアイデアに基づいた効率的なSQLクエリ作成
- 簡単なクエリをすばやく作成できる、わかりやすいクエリビルダー
- MongoDBのようなNoSQLデータベースへの良いサポートを提供
2. Express.js
Express.jsは、最も単純、最も最速で、non-opinionatedのNode.js フレームワークです。これはNode.js上に構築され、サーバーと通信経路を管理するためのミドルウェアとして機能する、シンプルな技術です。
Node.jsには非同期性があり、またExpress.jsには複数の要求をシームレスに処理できる軽量アプリケーションを開発するための機能があり、Expressテクノロジーの機能に依存しています。Express.jsの特徴
- フルカスタマイズ可能
- Node.js Webミドルウェアの標準
- 低い学習曲線
- ブラウザへの注力
3. Hapi.js
Hapi.jsは、アプリケーションのプログラムインターフェイス開発に利用されている、最高のNode.js Webフレームワークです。
Hapi.jsは、Webアプリケーション開発におけるNode.jsフレームワークの最上位にあり、スクリプト全体の管理作業が容易であると、開発者たちから愛されています。Hapi.jsの特徴
- 強力な入力バリデーション
- 構成ベースの機能
- キャッシングの実装
- 改善されたエラー処理
4. Meteor.js
Meteor.jsは、最新のWebおよびモバイルアプリケーションを構築するために使用されており、フルスタックのJavaScriptプラットフォームとして定義されています。Meteor.jsの最も重要な機能は、Web上のすべての変更が、テンプレート上で即座に更新されるという、リアルタイム更新を提供しているということです。
このフレームワークは、アプリの階層全体のための単純化されたプラットフォームを持っており、同じ言語(JavaScript)になっています。これにより、このフレームワークをサーバーサイド並びにクライアントサイドで、より効率的な方法で機能させられるのです。Meteor.jsの特徴
- より大きなプロジェクトを管理するための能力(ケーパビリティ)がある
- 豊富で整理されたドキュメントコミュニティ
- Facebook GraphQLデータスタックを利用している
- 多くの開発者にとって理解が簡単である
5. Sails.js
Sails.jsは、独自のエンタープライズ品質なNode.jsアプリケーションを開発するのに使用される、もう1つの人気があるNode.js フレームワークです。モダンなアプリに必要とされる対応がされており、最高のアプリを構築するためのすべての機能を持っています。Sails.jsは、スケーラブルなサービス指向アーキテクチャーにアタッチされた、データ駆動型(データドリブン)のAPIで構成されています。
Sails.jsの特徴
- 数多くの自動ジェネレータがある
- 追加ルーティングが不要
- 様々なフロントエンドテクノロジーとの素晴らしいフロントエンド互換性がある
- Web Socketに対する明確なサポート
- 全データベースに対応
6. Koa.js
Express.jsを作ったチームがKoa.jsを開発しました。Express.jsのギャップを埋めるために、開発されています。Koaは、それぞれ異なるブラウザで動作させるための独自スクリプトやメソッドを持っています。それは、コールバックなしのプログラム動作させることへの助けとなり、力が入れられたエラーハンドリングの提供も受けられることでしょう。
Koa.jsの特徴
- コールバックを管理し処理するために必要なジェネレータを利用できる
- 強力で効率的なエラー処理プロセスがある
- コンポーネントに基づいたビルディングブロック
- ミドルウェアのカスケーディングとコールバック地獄の放棄
7. LoopBack.js
LoopBack.jsは、もう1つの、有名でよく利用されているNode.js フレームワークであり、使いやすいCLIと、動的なAPIエクスプローラーを備えています。必要なスキーマに応じて(またはスキーマが不要な場合でも)、さまざまなモデルを作成するのに役立ちます。MySQL、MongoDB、Oracle、Postgresなど、さまざまなRESTサービスやデータベースとの互換性があります。
LoopBack.jsの特徴
- 動的なe2eのREST APIsを迅速に作成
- さまざまなデバイスやブラウザの中でより良い接続ができる
- 多様なデータとサービス間における相関性の向上
- クライアントアプリを作成するためのAndroid、iOS、Angular SDKの利用
- オンプレミスでもクラウドでも実行可能
8. Derby.js
Derby.jsはサーバーとクライアント間の、シームレスなデータ同期を提供しています。Derby.jsは、モダンなWebアプリケーションを作成するためのフルスタックNode.js フレームワークとして有名です。Derby.jsは、カスタマイズされたコードを追加し、そして非常に効率的なWebアプリケーションを構築する機会を提供しています。Derby.jsは、いくつかの優れた機能を持っているため、2019年に大きな注目を浴びることでしょう。
Derby.jsの特徴
- クライアントサイドとサーバーサイド両方のためのMVCアーキテクチャ
- モバイルおよびWebアプリケーションの作成に最適
- WebページやHTMLテンプレートを高速ロードするためのサーバーレンダリングおよび検索エンジンのサポート
9. Total.js
Total.jsは、ほとんどメンテナンスを必要とせず、強力なパフォーマンスと完璧なスケーリングの移行を実現します。ユーザーの要求を満たし、それを世界中で愛用可能で非常に使いやすいNode.js フレームワークにするためにTotal.jsのチーム全体で一生懸命取り組んでいるのです。これは、Total.jsフレームワークが今後数年間で好評を博すだろうことを示しています。
Total.jsの特徴
- MVCアーキテクチャ
- 高度に拡張可能で非同期のフレームワーク
- RESTfulなルーティングメカニズムをフルサポート
- Web Socketとメディアストリーミングのフルサポート
10. Nest.js
Nest.jsは、プロフェッショナルでスケーラブルなNode.jsサーバーサイドアプリケーションの開発に使用される、Node.js フレームワークの1つです。JavaScriptを使用し、TypeScriptで記述されています。TypeScriptを使用して構築されているため、強力な入力が可能であり、オブジェクト指向プログラミング(OOP)、関数型プログラミング(FP)、および関数型反応性プログラミング(FRP)のすべての要素が組み合わされているのです。
Nest.jsの特徴
- すぐ利用可能なアプリケーションアーキテクチャを持っている
- 高度にテスト可能でスケーラブルなアプリケーションを簡単に作成
- Nest.jsアプリケーションの生成にNest CLIが使用される
Node フレームワークを選択する方法
ここで見てきたように、Web開発の市場には非常に多くの Node.js フレームワークがあるので、これは難しい判断です。しかし、この判断は専ら、あなたが関わるプロジェクトやビジネスの要件に依存するものです。それぞれのNode.js フレームワークは、それぞれ専門としているものがあり、速度、学習曲線、コーディング構造、柔軟性、構成など、内容は様々です。
主なポイント
テクノロジーの普及は、今日のデジタル世界で大きくなり続けています。これは、フレームワークとさまざまなテクノロジーとの間の競争レベルが、ますます高くなっていることを意味しているのです。Web開発の市場には非常に多くのNode.js フレームワークが用意されていますが、ビジネスの要求を満たすためには、最適なものを選択する必要があります。
Node.js フレームワークの特徴や機能は、企業向けの、強力でエラーのないアプリケーションの構築を可能にするための、全ての能力を持っていることです。そのために 最高のNode.js開発者を雇う ことだって出来ます。
それぞれ特定のフレームワークの詳細について理解するには、多くの研究と分析が必要なことから、最良のNodeJSフレームワークを選択するということは、タフな作業です。さらなる研究をした上で、最高のWebサイトアプリケーションを開発するのに役立つこのフレームワークを選択するかは、あなた次第です。原文記事(引用元)
- 投稿日:2019-02-15T16:21:37+09:00
[Node.js]WindowsにNode.js(npm)をインストールしよう。
npmを使用することが多いのでWindowsでのNode.jsのインストール手順をまとめました。
※2019/02時点ではv10.15.1+Node.jsの確認
まずはPCにNode.jsがインストールされているかの確認をします。
1.コマンドプロンプトを立上げる。
2.以下のコマンドのいずれかを入力する。> node --versionOR
> npm --version3.以下の様にバージョンが表示されればインストール済みです。
また以下の様なメッセージが表示されればインストールされていません。
+インストール
1. Node.jsインストーラーのダウンロード
以下公式サイトに移動します。
Node.js公式
Windows用の10.15.1 LTS をクリックしてインストーラーをダウンロードします。
2. Node.jsのインストール
ダウンロードしたインストーラ(.msi)を実行します。
インストール画面が起動したら[Next]をクリックします。
利用規約を確認・チェックしたあとに[Next]をクリックします。
インストール先(特に変更しなくて大丈夫)を指定して[Next]をクリックします。
インストール設定ですが変更せずに[Next]をクリックします。
インストールの設定は完了ですので、[install]をクリックします。
インストール中になります。しばらくお待ちください。
以上でインストール完了となります。[Finish]クリックで画面を閉じます。
+もう一度インストールの確認
先ほどと同様にインストールの確認をします。
1.コマンドプロンプトを立上げる。
2.以下のコマンドを入力する。> node --version
- 投稿日:2019-02-15T15:22:50+09:00
node.jsでbitcoin自動取引する話
注意
本記事はあくまで技術的な内容であり、実際のbitcoinの運用に関して一切の責任を負いません。
取引を行う際はご自分の責任のもとでお試しいただくことをご了承ください。この記事のターゲット
- node.js触ってみたい
- bitcoinでちょっとお小遣い稼ぎしてみたい
- プログラムを一定間隔で常に動かすにはどうしたらいいの?
- (Mac環境)
ゴール
node.jsで一定間隔ごとにbitflyerの板情報を監視して自動で注文を出すプログラムをEC2のインスタンス上で動かす。
本題
bitflyer
本記事ではbitcoinの取引所にbitflyerを利用します。
アカウントの取得はサイトの指示に従ってください。
取引はLightning FX で行いますので板が見れる状態にしてください。node.js
入っていない場合はinstallします。
以下参照。
https://qiita.com/Alex_mht_code/items/422f5ce10d9c9d5729b7プロジェクト作成
新規nodeプロジェクトを用意します。
mkdir my-project cd my-project npm init touch main.jsapiキーの取得
bitflyerで自分のAPIキーを取得します。
重要なパラメータなのでgithubにあげたりしないように注意してください。
別ファイルに切り分けて読み込みます。touch config.jsconfig.jsmodule.exports = { apiKey: __apiKey__, secret: __secret__, }main.jsconst config = require ('./config')cctxの導入
bitflyerのAPIにリクエストするため、cctxというライブラリを利用します。
npm install cctxmain.jsconst ccxt = require ('ccxt') const bitflyer = new ccxt.bitflyer (config) //bitflyerの板情報を取得するメソッドを実行(板はFX_BTC_JPYを指定) const ticker = await bitflyer.fetchTicker ('FX_BTC_JPY')一定間隔で実行
async awaitを利用します。
main.jsconst ccxt = require ('ccxt') const config = require ('./config') //10秒 const interval = 10000 const sleep = (timer) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve() }, timer) }) } (async function () { while(true) { //bitflyerの板情報を取得するメソッドを実行(板はFX_BTC_JPYを指定) const ticker = await bitflyer.fetchTicker ('FX_BTC_JPY') await sleep(interval) } }) ();いつ買っていつ売るの
本来ならじっくり考えてそれなりに複雑アルゴリズムが必要なところですが、今回はクソザコなめくじアルゴリズムをとりあえず実装します。
方針としては
- 10秒毎に板情報を取得
- 3回連続で値上がりしていたら買う
- 3回連続値下がりしたら売る
とします。main.jsconst ccxt = require ('ccxt') const config = require ('./config') //過去3回文のデータを保持するところ const records = [] //注文情報 let order = null //注文単位 0.01BitCoin const orderSize = 0.01; //10秒 const interval = 10000 const sleep = (timer) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve() }, timer) }) } (async function () { while(true) { //bitflyerの板情報を取得するメソッドを実行(板はFX_BTC_JPYを指定) const ticker = await bitflyer.fetchTicker ('FX_BTC_JPY') //最終取引価格 records.push(ticker.last) if (records.length > 3) { //4つめがきたら古いものを消す records.shift() } if(order) { //注文情報がある if (records[2] < records[1] && records[1] < records[0]) { //売る order = await bitflyer.createMarketSellOrder("FX_BTC_JPY", orderSize); console.log(order) order = null } } else { //注文情報がない if (records[0] < records[1] && records[1] < records[2]) { //購入 order = await bitflyer.createMarketBuyOrder("FX_BTC_JPY", orderSize); console.log(order) } } await sleep(interval) } }) ()ずっと実行するには?
foreverというツールがあります。
Node.jsを動かし続けるためのツールです。以下参照
foreverコマンドでNodeJSアプリを起動したままにするEC2インスタンス
AWSアカウントを取得して適当に立てましょう。
ここはきっとたくさん記事があるのでスキップ。
処理的には全く重くないのでt2.nanoとかでもいいと思います。まとめ
人事を尽くして天命を待つ。
もちろんこのアルゴリズムで勝てる時もあれば負ける時もあります。
手を変え品を変えいろんなアルゴリズムを試してますがうまくいかないものですね。
まぁ自分が板にへばりつくよりもはっきりした基準で売買してくれるのでストレスみたいなものはないかも。よりよi
アルゴリズムを考えるゲームだと思うと結構楽しいですよ。
- 投稿日:2019-02-15T13:42:09+09:00
Articulateでビジネスチャットボットをつくる
チャットボットをはじめとした会話型サービスの開発に関心がある方向けに、この分野のオープンソースをざっくりレビューしていきます。
今回は Articulate https://github.com/samtecspg/articulate です。
Articulateとは
Articulateは、自然言語理解エンジン Rasa NLU をベースにした「ビジネスチャットボットCMS」とでもいえるアプリケーションです。Apacheライセンスで、Smart Platform Groupが開発しています。
Rasa NLUは、Rasa Technologiesが開発するオープンソースのNLUです。オープンソースのNLUではデファクトスタンダードのようなポジションで、Rasa NLUを使ったOSSが数多くあります。
ただし、Rasa NLUは残念ながら 日本語に未対応 です。(取り組んでみている人もいるようですが精度は不明)そのため、Articulateに日本語のトレーニングデータを登録しても、日本語を理解するボットを作ることは(現時点では)できません。
Articulateの特徴
チャットボットを構成するためのCMS&コンパネ
一般的に、チャットボットは様々なソフトウェアコンポーネントで構成されていますが、大きく分けて「表側」と「裏側」があります。
表側は、チャットユーザーに直接対応するアプリケーションです。質問や要求に答えたり、プロアクティブにメッセージを送ったりします。このとき「チャットユーザーの発言の意味」を理解するという過程でNLUを利用します。(NLUがチャットボットそのものであるかのように語られることもありますが、ソフトウェア全体としては部品の1つにすぎないのですよね)
裏側は、表側のアプリケーションのためのいわゆる「管理画面」です。チャットボットが回答に使用するコンテンツの登録、どのように回答するかのロジックやフローの登録、そしてNLUを訓練するためのトレーニングデータの登録などができます。
Articulateは、この「裏側」にフォーカスしたアプリケーションです。
オープンソースのチャットボットフレームワークやアプリケーションには、「表側」にフォーカスしたものが比較的多くあります。もちろん「裏側」が全くないチャットボットは成立しないので、いずれも多少なりとも機能をもってはいるのですが、裏側に「フォーカス」して作られているところが特徴的です。
エンタープライズで「運用される」ことが考えられた設計
Articulateは、エンタープライズでのチャットボット利用を意識して設計されているように見えます。設計者に知見があるのでしょう。
チャットボットは、実際に企業で利用すると「運用」が重要であることが分かります。構築段階から運用期間を通して、QA集め、コンテンツのチャット最適化、トレーニングデータ作成、チューニングなどの業務を繰り返し行うことになります。もちろん、自動化の余地は多いにあるものの、チャットボットの管理画面は半分「業務システム」みたいなところがあります。
オープンソースのプロダクトではこの「運用」というものが軽視されがちというか、エンジニアが作る前提であることが多いのですが、Articulateは、これをエンジニアでない人が継続的に行うために使うアプリケーションとして、概念や画面が整理されています。
同じポジションのソフトウェアにRasa Coreがありますが、Rasa Coreよりも「ease of useを維持する方針」だそうです。(コメント)
開発者向けアクションアイデア
エンジニアの方向けに、このOSSの活用アイデアや、コントリビュートしたいことについてのアイデアも残します。
- 日本語対応(表側)
- 前述したように、Rasa NLU(およびDuckling)を前提としたソフトウェアなので、Rasa NLUで日本語を扱えるようにするようにしないと始まりません。
- Articulateにおけるコンテンツやトレーニングデータで日本語テキストを扱うことは可能なので、Rasa NLUにコミットするか、あるいはオルタナティブを作るか。
- 日本語対応(裏側)
- せっかく非エンジニア向けに設計された管理画面でも、日本人が運用できるようにするには、管理画面の文言も日本語にしないと厳しいですよね。
- 管理画面の多国語化はサポートされていて、現時点で英語とスペイン語に対応しています。なので、日本語の言語リソースファイルさえあればできるのではと思います。(まず表側が対応しないと意味ないですが)
企業が開発しているということもありますが、質のよいOSSだと思うので、ぜひ試してみてください。UIはNode.jsで動くReactアプリケーションです。
We're hiring!
AIチャットボットを開発しています。
ご興味ある方はWantedlyページからお気軽にご連絡ください!
- 投稿日:2019-02-15T10:02:31+09:00
Next.js 8がリリースされた ? 新機能・改善点まとめ
2月11日にNext.js 8のリリースが公式ブログでアナウンスされました。
昨年9月のバージョン7のリリースから5ヶ月ぶりのメジャーアップデートですね。後方互換性を保ったアップデートとされています。
元記事で発表された新機能や改善点、変更点などをかいつまんでまとめてみました。
実際に自分で開発しているサービスをアップデートしてみた所感も少し書いています。
新しく追加された機能
サーバーレスに対応したビルド
アプリケーションをAWS Lambdaなどのサーバーレス環境にデプロイするための設定が追加されました。
pages/以下のファイル単位で単一の関数としてビルドされるようになっています。有効化するには設定をこのようにします。
next.config.jsmodule.exports = { target: "serverless" }こうすると例えばpages/以下にindex.jsとabout.jsという2つのファイルがある場合、
pages/index.js
=>.next/serverless/pages/index.js
pages/about.js
=>.next/serverless/pages/about.js
こんなふうにビルドが行われます。
ファイルの中身はexpressでおなじみの引数にリクエストとレスポンスのオブジェクトを受けてページの内容を返す単一のrender()関数をexportする形になっています。
export function render(req: http.IncomingMessage, res: http.ServerResponse) => void例えばデプロイ先のサーバーレス環境がNode.jsのhttpモジュールをサポートしている場合、以下のようにすることでレンダリングを行うことが出来ます。
const http = require("http"); const page = require("./.next/serverless/about.js"); const server = new http.Server((req, res) => page.render(req, res)); server.listen(3000, () => console.log("Listening on http://localhost:3000"))良い感じですね!ちょっとLambdaにデプロイしたくなってきました。
ビルド時の環境変数注入
サーバサイドで動くWebアプリケーションを開発する時、実行時に環境変数を渡して参照することが多々あるかと思います。
Next.jsはサーバ・クライアント両方で動作するユニバーサルなフレームワークなので実行時に渡した環境変数は当然サーバサイドでしか参照できず、クライアントサイドと処理を分ける必要があるなど少し不便でした。
これまではこれに対するワークアラウンドとして
babel-plugin-transform-define
やwebpack.DefinePlugin
を用いて、ビルド時に渡された環境変数をスクリプト内部に直接注入しサーバ・クライアント両方から参照可能にするということがよく行われてきました。バージョン8ではNext.js自体にこの機能が取り込まれています。上記のモジュールを追加インストールすることなくデフォルトで設定ファイルに注入する環境変数を定義することが可能になりました。
next.config.jsmodule.exports = { env: { customKey: 'MyValue' } }このように書いておくとアプリケーションスクリプト内部の
process.env.customKey
がビルド時に'MyValue'
に置きかわり、サーバ・クライアント両者で実行時に参照することが出来ます。自分もこれまでは
babel-plugin-transform-define
を利用していました。デフォルトでこういうのがあると少しすっきりしていいですね。crossOrigin設定の追加
Next.jsはビルドしたアプリケーションをブラウザで実行する時、page単位でjsを配信する仕組みになっています。
クライアントサイドルーティングは別pageへの遷移時にそのpageに対応したjsファイルを動的に生成した
<script>
タグを用いて注入することで実現しています。今回のリリースではこの注入される<script>タグへcross-origin属性を付与する設定が追加されました。
これは単純に同一のドメインから全てのスクリプトを配信する場合は気にする必要のないものなのですが、スクリプトをCDNなど別のドメインから配信する時に効果的な設定です。
別ドメインからのスクリプトを読み込んだ際にcross-origin属性が付与されていないと
- エラー発生時にエラーの内容がコンソールに出力されず、全てScript Errorと出力される
- CORSのリクエストを行う時にCookieなどの認証情報が付与されない
といった不都合があります。
これを回避するために注入される<script>タグのcrossorigin属性に'anonymous'または'use-credentials'を指定しておく必要がありますが、今回それが設定ファイルから指定出来るようになりました。next.config.jsmodule.exports = { crossOrigin: 'anonymous' }ちなみにNext.jsにはスクリプトの読み込み先をCDNなど別のドメインに変更する
assetPrefix
という設定があります。
多分これとセットで使うことが想定されていると思います。改善点・変更点
ビルド時のメモリ使用量の大幅な削減
速度の低下など全く無しにアプリケーションのビルドに必要なメモリを従来の16分の1に削減し、なおかつメモリの解放も早くなったようです。
これにより大規模なアプリのビルドが不安定でクラッシュしたりすることもなくなるでしょう…とのこと。すごいですね。
これはNext.jsの改善というよりはwebpack自体のパフォーマンスが向上したためのようで、そのためにwebpackにめっちゃcontributionしたって書いてありました。
どのように実現したのか詳しくはここには書かないけどそのうちまとめるからブログ見てね、とのことです。
Prefetchのパフォーマンス向上
クライアントサイドルーティングを簡単に実現するLinkコンポーネントのprefetch属性に関する変更です。
これまではページ内にprefetchが指定されたLinkがある場合、遷移先のURLで使うスクリプトを
<script>
タグを使って注入することで遷移前の先読みを行なっていました。しかしこれではスクリプトの読み込みが終わるまでページの読み込みも完了しなくなってしまいブラウザに不必要な待ち時間を与えてしまいます。
今回の変更では
<script>
タグの注入による先読みを廃止し代わりに<link rel="preload">
を用いることでページの読み込みが完了してはじめてスクリプトの先読みが始まるようになりました。加えてブラウザの
navigator.connection.saveData
の値を参照して自動的に先読みが無効になるようになったようです。
<link rel="preload">
を用いた実装だと先読みの振る舞いがブラウザ依存になるので以前の強制的にスクリプトを読み込ませる方式と比べるとお行儀が良くなった感がありますね。ちなみにこのprefetchを有効にしてみたらChromeでこんなWarningが出てしまいました。
preloadしてから3秒以内に当該のスクリプトを利用しないと不要な先読みだと捉えられて怒られてしまうようです。The resource was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.
next/router
の提供するprefetch()を利用しても同じことが出来るので、自分はリンク要素にマウスカーソルがのった時点でprefetchが行われるようにしています。sample.jsximport Router from 'next/router' import Link from 'next/link' export default props => ( <Link href='/about'> <a onMouseEnter={() => Router.prefetch('/about')}>About</a> </Link> )このPrefetchの挙動を確認してみたい方は僕が運営しているtechbooksという技術書籍のレビュー・ランキングサイトで実際に実装されているのでよかったら見てみて下さい。
生成するHTMLのサイズ削減
サーバサイドでレンダリングするhtmlのサイズが
1.50KB
→1.16KB
と23%削減されました。エラーページ表示用のスクリプトを初期描画時に含めないようにしたことと、後述するインラインスクリプトの廃止の影響によるものとのことです。
開発時のオンデマンドコンパイルの改善
Next.jsは開発サーバの起動時に全てのスクリプトをコンパイルせず、どこかのページにリクエストがあってはじめてそのページに関するスクリプトをコンパイルして画面を描画することで開発時のパフォーマンスを向上させています。
また最初にページをコンパイルした時点でその結果をキャッシュとしてメモリに保持し、25秒間そのページにリクエストがなければそれを破棄することによって不要なメモリの解放もよしなにやってくれています。
これまでは現在開いているページのキャッシュを破棄しないよう滞在検知のために5秒おきに
window.fetch
によるポーリングを行なっていましたが、これが今回WebSocketによる実装に変更されました。従来の方法だと5秒毎に開発者ツールのNetworkタブにポーリングの結果がどんどん表示されてしまって不便だから、というのが理由みたいです。
これによって開発サーバがListenするポートがWebSocketサーバ用に1つ追加されました。
(自分はDocker環境で開発サーバを起動していた上にこのことを知らず少しはまりました)デフォルトではWebSocketサーバは適当に空いているポートを探してListenするみたいですが任意のポートに固定する設定も追加されています。
間に何らかのプロキシをかませていてWebSocketサーバにListenして欲しいポートとブラウザにリクエストして欲しいポート/パスが異なる場合はそれ用の設定も出来るみたいです。
next.config.jsmodule.exports = { onDemandEntries: { websocketPort: 3001, websocketProxyPort: 7001, websocketProxyPath: '/hmr' } }開発用Webサーバの起動時間短縮
開発サーバの起動時、これまでは
初期リソースのコンパイル
→Webサーバ起動、ポートのListen
という流れだったので
next
コマンド実行直後にブラウザでアクセスしてもThis site can’t be reached
などのエラーが表示されてしまっていました。バージョン8ではこれが逆になって
Webサーバ起動、ポートのListen
→初期リソースのコンパイル
になりました。
開発用Webサーバ自体は
next
コマンド実行直後に立ち上がり、すぐにアクセスしてもエラーが表示されないようになりました。
ちゃんとコンパイルの完了まで読み込み待ちになるみたいです。Static Exportの速度向上
サーバサイドのレンダリング結果を静的ファイルとして出力する
export
コマンドがマルチコアに対応しました。4コアのMacBookで試したところ
25ページ/秒
→75ページ/秒
と3倍も高速になったとのことです。Static Exportを利用してブログサイトを構築している場合などは出力するページ数が多くなることが想定されるのでこれが速くなるのは良いですね。
Head要素の重複排除
どんなコンポーネントからでも
next/head
を用いるとページの<head>
内に任意のタグ/コンポーネントを注入することが出来ますが、これまでは例えば<title>
など重複して追加されるのではなく上書きをしてほしい要素の重複をコントロールする方法がありませんでした。今回、
<Head>
内の要素に付与する任意のkey属性でこれをコントロールすることが出来るようになりました。以下のコードはこれまでなら
<head>
内に<meta name="viewport" ... />
の要素が2つ重複して注入されてしまっていましたが、今回の変更では同一のkeyを持つ要素は上書きされるようになっています。sample.jsximport Head from 'next/head' export default function IndexPage() { return <> <Head> <title>My page title</title> <meta name="viewport" content="initial-scale=1.0, width=device-width" key="viewport" /> </Head> <Head> <meta name="viewport" content="initial-scale=1.2, width=device-width" key="viewport" /> </Head> </> }インラインJSの廃止
これまではページ内にインラインjsとして埋め込むことでサーバからクライアントへデータの受け渡しを行っていましたが、
<script type="application/json">
を利用した埋め込みに変更されました。これによりNext.jsによるページへのインラインJS埋め込みは完全に無くなったとのことです。
外部APIへAuthenticationするサンプルの公開
これはNext.js自体のアップデートというわけではないですが、ユーザが外部APIに対してCookieを利用した認証を行うケースのサンプルコードが公開されました。
https://github.com/zeit/next.js/tree/canary/examples/with-cookie-auth
サイトにSNS連携やOAuth認証の機能を追加する場合などもこれに当てはまりますね。
どうやって実現すればいいのか質問が多かったそうです。
- サーバサイドレンダリング時にもブラウザが送信してきたCookieと一緒にAPIへリクエストを行う
- Proxyサーバを使ってCORS関係なくリクエスト出来るようにする
この2つを実装すればクライアントサイド・サーバサイドで振る舞いを気にしなくて良くなるよ、との回答を示した形のサンプルコードになっています。
まとめ
たくさんの改善が含まれたメジャーアップデートでした。
実際に使ってみたところ確かに体感的にも開発用サーバのパフォーマンスがすごく向上していると感じました。
ビルド後のアプリケーションのパフォーマンスはもちろん、こうしたDXの改善にも意欲的なのはとても嬉しいですね。
- 投稿日:2019-02-15T09:51:24+09:00
Google App Engine(GAE) スタンダード環境でSequelizeを使ってCloud SQL for MySQLへつなぐ
GAEやNode.jsを初めて触ってサービスを制作してみたが、
Cloud SQL for MySQLへの接続にはまった為、メモとして残したいと思います。前提条件
- Node.js v10.x
- Sequelize v4.42.0
- Cloud SQL for MySQL v5.7
- GAEとCloud SQL for MySQLは同じプロジェクトであること
Sequelizeの設定例
const sequelize = new Sequelize('database', 'username', 'password', { dialect: 'mysql', host: 'localhost', dialectOptions: { socketPath: `/cloudsql/${process.env.INSTANCE_CONNECTION_NAME}`, }, })GAEからCloud SQLに接続する際は基本的にCloud SQL Proxyを使用して接続するみたいです。。
その為、デフォルトのTCPソケット接続ではなくUNIXソケット接続に切り替えます。
重要なのはhostとdialectOptions内のsocketPathです。
hostはデフォルトがlocalhostなので未設定でもいいです。
dialectOptions内のsocketPathには「/cloudsql/」という文字列の後に
Cloud SQLのインスタンス接続名を入れます。
インスタンス接続名はCloud SQLの [概要] ページのプロパティに記載されています。