- 投稿日:2019-02-03T21:59:28+09:00
Docker で Node.js 開発環境を簡単に用意する
概要
Docker を使って、ローカルを汚すことなく Node.js の開発環境を作る方法です。数行の
docker-compose.ymlを書いて、あとは随時コンテナを起動してコマンドを実行するだけです。環境
- macOS Mojave v10.14.2
- Docker Desktop Community v2.0.0.2
手順
- Docker Desktop をインストールします。
- 開発用ディレクトリ(Git リポジトリ等)を用意します。
docker-compose.ymlを書きます。手順 1、2 については特に説明は不要だと思うので省略します。
docker-compose.ymlを書く以下を書きます。
docker-compose.ymlversion: '3' services: app: image: node:11.8.0 ports: - $PORT:$PORT volumes: - ./:/src working_dir: /src.envPORT=8080
app— サービス名。好きな名前を付けます。- image — Docker の公式イメージを使います。バージョンは開発する目的に合わせて指定してください。
- ports — Express を使って Web サーバを立てる場合など、ホスト・ゲスト間で通信が必要な場合はポートを指定します。今回は環境変数で指定できるようにしました。
- volumes — ホスト側のディレクトリをゲストにマウントします。
- working_dir — コンテナ起動後のカレントディレクトリを指定します。
npm installを実行するpackage.jsonがあるディレクトリを指定するとよいでしょう。以上で準備完了です!
必要な場合はビルドを
パッケージマネージャに Yarn を使用するなど、Node.js のイメージに何かをインストールする必要がある場合は、
Dockerfileを書いてビルドしておきます。実行
あとは
docker-compose run --rm <サービス名> <コマンド>で Node.js を使った何かを随時実行するだけです(以下、サービス名をappとします)。--rmオプションは、コマンド終了後にコンテナを自動的に削除してくれます。npm で任意のライブラリをインストールする
docker-compose run --rm app npm install <パッケージ名>
package.jsonの依存ライブラリをインストールする開発環境を他の人に提供するときなど。
docker-compose run --rm app npm install
package.jsonで定義したスクリプトを実行するExpress で Web サーバを起動するなど、
package.jsonで定義したスクリプトを実行する場合。package.json{ "scripts": { "start": "node --experimental-modules index.mjs" } }
docker-compose.ymlの ports で指定したポートを通すには--service-portsオプションを付けます。docker-compose run --rm --service-ports app npm startよく使うコマンドはシェルスクリプトで
毎回
docker-compose run --rm app ...と打つのは面倒なので、よく使うコマンドはシェルスクリプトにしておくとよいです。例えば、開発環境を構築するためのコマンドを一つのシェルスクリプトに書いておくことで、他の人が開発環境を簡単に準備できるようになります。
prepare.sh#!/bin/bash echo 'PORT=8080' >> .env && \ docker-compose run --rm app npm installまとめ
docker-compose.ymlで Node.js のイメージとボリューム、ワーキングディレクトリ等を定義します。docker-compose run --rm <サービス名> <コマンド>で随時コンテナ作成、コマンド実行、コンテナ削除を行います。それでは、快適な Docker ライフを!
- 投稿日:2019-02-03T19:04:07+09:00
【Terser】Nuxt.jsで突然ビルドエラーが発生したときの対応法
はじめに
現在、Nuxt.jsとNetlifyを使用して個人で開発を行なっています。
その際にNetlifyでビルドを行なったときに突然エラーが発生するようになりました。
本記事では、そのときの対処法について、備忘録として記したいと思います。エラー内容
ビルドを行なったときに、以下のようなエラーが発生するようになりました。
5:39:27 PM: ERROR in 6f8075b97658f08b5126.js from Terser 5:39:27 PM: TypeError: Cannot read property 'minify' of undefined 5:39:27 PM: at minify (/opt/build/repo/node_modules/terser-webpack-plugin/dist/minify.js:175:23) 5:39:27 PM: at module.exports (/opt/build/repo/node_modules/terser-webpack-plugin/dist/worker.js:13:40) 5:39:27 PM: at handle (/opt/build/repo/node_modules/worker-farm/lib/child/index.js:44:8) 5:39:27 PM: at process.<anonymous> (/opt/build/repo/node_modules/worker-farm/lib/child/index.js:51:3) 5:39:27 PM: at emitTwo (events.js:126:13) 5:39:27 PM: at process.emit (events.js:214:7) 5:39:27 PM: at emit (internal/child_process.js:762:12) 5:39:27 PM: at _combinedTickCallback (internal/process/next_tick.js:142:11) 5:39:27 PM: at process._tickCallback (internal/process/next_tick.js:181:9)対処法
package.jsonに下記の記述を追記するとビルドが正常に行われるようになりました。
package.json"resolutions": { "terser": "3.14.1" }4.参考
- 投稿日:2019-02-03T18:04:30+09:00
サブライムテキストでJavascript の予測変換機能を追加してみた①
WEBサイト制作で使っているsublimeText(サブライムテキスト)で、Javascriptの予測変換機能を追加してみた。
これで、querySelectorといった長ったらしいメソッドも楽に入力できるに違いない。
でも、どうやらそのためには、「jshint」というプラグインがあるらしいが、前提としてNode.jsをインストールしておく必要があるとのこと。
Node.jsというのは、「サーバーサイドで動くJavascript」のこと。詳細を調べると、複雑すぎて(⁰▿⁰)だったので、とりあえずは左のような浅い理解で今はOKとさせてください。
参照サイト
後々、ドットインストール等で勉強します。
以下に、Node.jsインストール・jshint追加までの手順を記します。参考にした記事
- https://qiita.com/akakuro43/items/600e7e4695588ab2958d)
- https://qiita.com/omega999/items/6f65217b81ad3fffe7e6
- JavaScriptのためのSublime Textプラグイン① homebrewのインストール
homebrewというのは、Mac用のパッケージマネージャ。→公式サイト
パッケージマネージャーというのは、OSという一つの環境で各種のソフトウェアの管理、ソフトウェア同士やライブラリとの依存関係を管理するシステム。(Wikipediaから引用)
⬇︎
Macターミナルを起動して、以下のコマンドを実行。
※homebrew公式サイトの「インストール」項目を参照/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"インストールできたか確認するために、「brew doctor」と打ち込んだら、変な表示がされた。
「brew doctor」というのは、インストールされたhomebrewの問題をチェックしてくれるコマンド。Please note that these warnings are just used to help the Homebrew maintainers with debugging if you file an issue. If everything you use Homebrew for is working fine: please don't worry or file an issue; just ignore this. Thanks! Warning: "config" scripts exist outside your system or Homebrew directories. `./configure` scripts often look for *-config scripts to determine if software packages are installed, and what additional flags to use when compiling and linking. Having additional scripts in your path can confuse software installed via Homebrew if the config script overrides a system or Homebrew provided script of the same name. We found the following "config" scripts: /anaconda3/bin/icu-config /anaconda3/bin/freetype-config /anaconda3/bin/xslt-config /anaconda3/bin/libpng16-config /anaconda3/bin/python3.7-config /anaconda3/bin/libpng-config /anaconda3/bin/xml2-config /anaconda3/bin/python3.7m-config /anaconda3/bin/python3-config /anaconda3/bin/curl-config /anaconda3/bin/ncursesw6-config /anaconda3/bin/pcre-config Warning: Broken symlinks were found. Remove them with `brew cleanup`: /usr/local/bin/mono-boehm /usr/local/bin/prj2makeWarningということは「警告」ってこと?
一つ目の警告から、調べてみた。
①. 「Warning: "config" scripts exist outside your system or Homebrew directories.」
(警告: "config"スクリプトはあなたのシステムまたは自作ディレクトリの外にあります。)
解決方法はここを参考にしたけどうまくできませんでした。そもそもbashなどといったシェルの知識を持ち合わせていないから、参考記事のコードをコピペしても何をしているのかさっぱり分かりません。
とりあえず致命的な警告ではないので、ここは飛ばします。
シェルスクリプトは、後々ドットインストール等で勉強します。
https://dotinstall.com/lessons/basic_shellscript_v2二つ目の警告は、
②. 「Warning: Broken symlinks were found. Remove them withbrew cleanup」
(壊れたシンボリックリンクが見つかりました。brew cleanupでそれらを削除してください。)
これは、メッセージ通りに、MyMac:~ takawaki$ brew cleanupを実行した後は、警告が出なくなった。
シンボリックリンク
OSのファイルシステムの機能の一つで、特定のファイルやディレクトリを指し示す別のファイルを作成し、それを通じて本体を参照できるようにする仕組み。UNIX系OSでよく用いられるもので、Windowsでも利用することができる。
ショートカットと同じじゃないの?と思ったが厳密には違うみたいです。→参考サイト②nodebrewのインストール
nodebrewとは、node.jsを自分のマシン内でversion管理するためのツール。
プロジェクトごとにnode.jsのversionが違っていたりすると、不具合が起こるのでそれを解決してくれる。参考記事
以下のコマンドを実行して、確認のためバージョン確認。
brew install nodebrew nodebrew -v⬇︎
実行結果nodebrew 1.0.1 Usage: nodebrew help Show this message nodebrew install <version> Download and install <version> (from binary) nodebrew compile <version> Download and install <version> (from source) nodebrew install-binary <version> Alias of `install` (For backword compatibility) nodebrew uninstall <version> Uninstall <version> nodebrew use <version> Use <version> nodebrew list List installed versions nodebrew ls Alias for `list` nodebrew ls-remote List remote versions nodebrew ls-all List remote and installed versions nodebrew alias <key> <value> Set alias nodebrew unalias <key> Remove alias nodebrew clean <version> | all Remove source file nodebrew selfupdate Update nodebrew nodebrew migrate-package <version> Install global NPM packages contained in <version> to current version nodebrew exec <version> -- <command> Execute <command> using specified <version> Example: # install nodebrew install v8.9.4 # use a specific version number nodebrew use v8.9.4③Node.jsのインストール
以下のコマンドを実行
nodebrew innstall-binary latest
そしたら
以下のエラーが返ってきたMyMac:~ takawaki$ nodebrew install-binary latest Fetching: https://nodejs.org/dist/v11.9.0/node-v11.9.0-darwin-x64.tar.gz Warning: Failed to create the file Warning: /Users/takafumi/.nodebrew/src/v11.9.0/node-v11.9.0-darwin-x64.tar.gz: Warning: No such file or directory 0.0% curl: (23) Failed writing body (0 != 846) download failed: https://nodejs.org/dist/v11.9.0/node-v11.9.0-darwin-x64.tar.gz解決策を調べた。
Node.jsのインストールに失敗する時の解決策(No such file or directory)
No such file or directoryは、「こんなファイルを知りません」というメッセージ。
だから以下のコマンドで非表示ディレクトリを作成mkdir -p ~/.nodebrew/srcmkidirはディレクトリを作成するコマンド
-pはparentオプションで、エラーを表示せず記述したディレクトリが存在しなければ作成することができる。
ディレクトリ名の最初に、「.」をつけるのは非表示ディレクトリにするため。
作成したら、nodebrew innstall-binary latestを再実行。MyMac:~ takawaki$ nodebrew install-binary latest Fetching: https://nodejs.org/dist/v11.9.0/node-v11.9.0-darwin-x64.tar.gz ######################################################################### 100.0% Installed successfullyインストールが成功した!念のため確認。
「nodebrew list」は、インストールされているバージョンを確認できる。
以下のコマンドでは、version11.9.0を使っていることが分かる。
```
MyMac:~ takawaki$ nodebrew list
v11.9.0current: v11.9.0
```④実行パスを通す
以下のコマンドでnodeコマンドへパスをbashrcへ保存。
$ echo 'export PATH=$PATH:/Users/takafumi/.nodebrew/current/bin' >> ~/.bashrcだが、インストール確認したら次のメッセージが出た
node -v -bash: node: command not foundなので、参考記事通りに「.bash_profile」に以下を記述
参考記事①そして、再度確認したら、node.jsが使えるようになった!
MyMac:~ takawaki$ node -v v11.9.0⑤npmを使えるか確認
npmは、Node.jsのパッケージ管理システム。
MyMac:~ takawaki$ npm -v 6.5.0インストールされていることを確認。
今回、なんどもパスを通すためにファイルをいじったけど、そもそもパスを通すということはどういうことなのかも調べた。
→参考記事:PATHを通す方法
- 投稿日:2019-02-03T18:04:30+09:00
サブライムテキストでJavascriptの予測変換機能を追加してみた①
WEBサイト制作で使っているsublimeText(サブライムテキスト)で、Javascriptの予測変換機能を追加してみた。
これで、querySelectorといった長ったらしいメソッドも楽に入力できるに違いない。
でも、どうやらそのためには、「jshint」というプラグインがあるらしいが、前提としてNode.jsをインストールしておく必要があるとのこと。
Node.jsというのは、「サーバーサイドで動くJavascript」のこと。詳細を調べると、複雑すぎて(⁰▿⁰)だったので、とりあえずは左のような浅い理解で今はOKとさせてください。
参照サイト
後々、ドットインストール等で勉強します。
以下に、Node.jsインストール・jshint追加までの手順を記します。参考にした記事
- https://qiita.com/akakuro43/items/600e7e4695588ab2958d)
- https://qiita.com/omega999/items/6f65217b81ad3fffe7e6
- JavaScriptのためのSublime Textプラグイン①homebrewのインストール
homebrewというのは、Mac用のパッケージマネージャ。→公式サイト
パッケージマネージャーというのは、OSという一つの環境で各種のソフトウェアの管理、ソフトウェア同士やライブラリとの依存関係を管理するシステム。(Wikipediaから引用)
⬇︎
Macターミナルを起動して、以下のコマンドを実行。
※homebrew公式サイトの「インストール」項目を参照/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"インストールできたか確認するために、「brew doctor」と打ち込んだら、変な表示がされた。
「brew doctor」というのは、インストールされたhomebrewの問題をチェックしてくれるコマンド。Please note that these warnings are just used to help the Homebrew maintainers with debugging if you file an issue. If everything you use Homebrew for is working fine: please don't worry or file an issue; just ignore this. Thanks! Warning: "config" scripts exist outside your system or Homebrew directories. `./configure` scripts often look for *-config scripts to determine if software packages are installed, and what additional flags to use when compiling and linking. Having additional scripts in your path can confuse software installed via Homebrew if the config script overrides a system or Homebrew provided script of the same name. We found the following "config" scripts: /anaconda3/bin/icu-config /anaconda3/bin/freetype-config /anaconda3/bin/xslt-config /anaconda3/bin/libpng16-config /anaconda3/bin/python3.7-config /anaconda3/bin/libpng-config /anaconda3/bin/xml2-config /anaconda3/bin/python3.7m-config /anaconda3/bin/python3-config /anaconda3/bin/curl-config /anaconda3/bin/ncursesw6-config /anaconda3/bin/pcre-config Warning: Broken symlinks were found. Remove them with `brew cleanup`: /usr/local/bin/mono-boehm /usr/local/bin/prj2makeWarningということは「警告」ってこと?
一つ目の警告から、調べてみた。
①. 「Warning: "config" scripts exist outside your system or Homebrew directories.」
(警告: "config"スクリプトはあなたのシステムまたは自作ディレクトリの外にあります。)
解決方法はここを参考にしたけどうまくできませんでした。そもそもbashなどといったシェルの知識を持ち合わせていないから、参考記事のコードをコピペしても何をしているのかさっぱり分かりません。
とりあえず致命的な警告ではないので、ここは飛ばします。
シェルスクリプトは、後々ドットインストール等で勉強します。
https://dotinstall.com/lessons/basic_shellscript_v2二つ目の警告は、
②. 「Warning: Broken symlinks were found. Remove them withbrew cleanup」
(壊れたシンボリックリンクが見つかりました。brew cleanupでそれらを削除してください。)
これは、メッセージ通りに、MyMac:~ takawaki$ brew cleanupを実行した後は、警告が出なくなった。
シンボリックリンク
OSのファイルシステムの機能の一つで、特定のファイルやディレクトリを指し示す別のファイルを作成し、それを通じて本体を参照できるようにする仕組み。UNIX系OSでよく用いられるもので、Windowsでも利用することができる。
ショートカットと同じじゃないの?と思ったが厳密には違うみたいです。→参考サイト②nodebrewのインストール
nodebrewとは、node.jsを自分のマシン内でversion管理するためのツール。
プロジェクトごとにnode.jsのversionが違っていたりすると、不具合が起こるのでそれを解決してくれる。参考記事
以下のコマンドを実行して、確認のためバージョン確認。
brew install nodebrew nodebrew -v⬇︎
実行結果nodebrew 1.0.1 Usage: nodebrew help Show this message nodebrew install <version> Download and install <version> (from binary) nodebrew compile <version> Download and install <version> (from source) nodebrew install-binary <version> Alias of `install` (For backword compatibility) nodebrew uninstall <version> Uninstall <version> nodebrew use <version> Use <version> nodebrew list List installed versions nodebrew ls Alias for `list` nodebrew ls-remote List remote versions nodebrew ls-all List remote and installed versions nodebrew alias <key> <value> Set alias nodebrew unalias <key> Remove alias nodebrew clean <version> | all Remove source file nodebrew selfupdate Update nodebrew nodebrew migrate-package <version> Install global NPM packages contained in <version> to current version nodebrew exec <version> -- <command> Execute <command> using specified <version> Example: # install nodebrew install v8.9.4 # use a specific version number nodebrew use v8.9.4③Node.jsのインストール
以下のコマンドを実行
nodebrew innstall-binary latest
そしたら
以下のエラーが返ってきたMyMac:~ takawaki$ nodebrew install-binary latest Fetching: https://nodejs.org/dist/v11.9.0/node-v11.9.0-darwin-x64.tar.gz Warning: Failed to create the file Warning: /Users/takafumi/.nodebrew/src/v11.9.0/node-v11.9.0-darwin-x64.tar.gz: Warning: No such file or directory 0.0% curl: (23) Failed writing body (0 != 846) download failed: https://nodejs.org/dist/v11.9.0/node-v11.9.0-darwin-x64.tar.gz解決策を調べた。
Node.jsのインストールに失敗する時の解決策(No such file or directory)
No such file or directoryは、「こんなファイルを知りません」というメッセージ。
だから以下のコマンドで非表示ディレクトリを作成mkdir -p ~/.nodebrew/srcmkidirはディレクトリを作成するコマンド
-pはparentオプションで、エラーを表示せず記述したディレクトリが存在しなければ作成することができる。
ディレクトリ名の最初に、「.」をつけるのは非表示ディレクトリにするため。
作成したら、nodebrew install-binary latestを再実行。MyMac:~ takawaki$ nodebrew install-binary latest Fetching: https://nodejs.org/dist/v11.9.0/node-v11.9.0-darwin-x64.tar.gz ######################################################################### 100.0% Installed successfullyインストールが成功した!念のため確認。
「nodebrew list」は、インストールされているバージョンを確認できる。
以下のコマンドでは、version11.9.0を使っていることが分かる。MyMac:~ takawaki$ nodebrew list v11.9.0 current: v11.9.0④実行パスを通す
以下のコマンドでnodeコマンドへパスをbashrcへ保存。
$ echo 'export PATH=$PATH:/Users/takafumi/.nodebrew/current/bin' >> ~/.bashrcだが、インストール確認したら次のメッセージが出た
node -v -bash: node: command not foundなので、参考記事通りに「.bash_profile」に以下を記述
参考記事①そして、再度確認したら、node.jsが使えるようになった!
MyMac:~ takawaki$ node -v v11.9.0⑤npmを使えるか確認
npmは、Node.jsのパッケージ管理システム。
MyMac:~ takawaki$ npm -v 6.5.0インストールされていることを確認。
今回、なんどもパスを通すためにファイルをいじったけど、そもそもパスを通すということはどういうことなのかも調べた。
→参考記事:PATHを通す方法
- 投稿日:2019-02-03T16:25:26+09:00
S3へのアウトプット
こんにちは。AWS lambdaのAPIでS3のアウトプットについて簡単ながら書いていきます。
内容は言語はNode.jsで書いてますが、どの言語でもエッセンスは関係ない基礎的なところかなと思います。
参考文献:
https://www.amazon.co.jp/AWS%E3%81%AB%E3%82%88%E3%82%8B%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%83%AC%E3%82%B9%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3-Peter-Sbarski/dp/4798155160/ref=sr_1_1?ie=UTF8&qid=1549178089&sr=8-1&keywords=%E3%82%B5%E3%83%BC%E3%83%90%E3%83%AC%E3%82%B9%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3ではAWS LambdaのAPIで「バケット1」から、バケット内のファイルをアウトプットしましょう!!
例
Outputs: [ Key: "任意のファイル名"+ '.mp4等、ファイルの種類' ]でlanbdaの中でアウトプットを作ることが出来ます。
ファイルだけじゃなくてフォルダを作りたい!という方は
ファイル名の前にOutputs: [ Key: "任意のフォルダ名" + "/" + "任意のファイル名" + '.mp4等、ファイルの種類' ]のように "/" を付けるとフォルダが出来上がって、ファイルが格納されている状態になっちゃいます。
複数のファイルをアウトプットに入れたい場合は
Outputs: [ {Key: "任意のフォルダ名" + "/" + "任意のファイル名" + '.mp4等、ファイルの種類'}, {.............}, {.............}・・・ ]と続けていけばいいです。
ここで、フォルダ名を同一のものにすると、同一フォルダに複数ファイルが格納された状態になります。
以上です。
読んでくださってありがとうございました!
- 投稿日:2019-02-03T14:47:02+09:00
CLIでMapを確認する方法
CLIでlocation情報であるlat, locを指定してMap上で表示するツールを探していたのですが、なかなか見つからなかったので、なにか良いものがあったら教えてください。
一応、見つかったものを紹介します。できれば、(1)lat,locでqueryできること、(2)google mapで拡大、縮小できることが条件なんですけど、一方しか見つかりませんでした。
blessed-contrib:map
# とりあえずサーバー情報を引き出してみる $ whois example.com $ nslookup exmaple.com 8.8.8.8 # 仮にipが8.8.8.8だったとする, サーバーのおおよその位置をblessed-contribを使って世界地図上で表示してみる # https://github.com/yaronn/blessed-contrib $ git clone https://github.com/yaronn/blessed-contrib.git $ cd blessed-contrib $ vim examples/map-query-location.jsblessed-contrib/examples/map-query-location.jsvar blessed = require('blessed') , contrib = require('../') , screen = blessed.screen() , map = contrib.map({label: 'World Map'}) , loc = process.argv[2] , rLoc = loc.split(",") screen.append(map) map.addMarker({"lat" : rLoc[0], "lon" : rLoc[1], color: "red", char: "X" }) screen.render()nodeのblessed-contribに触発され、golangやrustで書かれたものもあるみたいです。これらを使ってcli toolを書くと便利そう。
https://github.com/gizak/termui
https://github.com/fdehau/tui-rs
mapscii
# https://github.com/rastapasta/mapscii $ sudo npm install -g mapscii $ mapscii...こちらはqueryできない
- 投稿日:2019-02-03T06:05:23+09:00
JavaScriptでお手軽にランダム文字列の生成
お手軽さを重視しているため、作り方に偏りがある事が分かっている物もある。
以下の環境で確認
- Node: v10.15.0
- ブラウザ: Chrome 71.0.3578.98, Firefox 64.0.2
Edgeやモバイルの動作確認はしてない。
Node/ブラウザ共通
短いコードで
[a-v]と[0-9]の32文字で12桁以下なら、これでそれっぽいのが作れる。StackOverflowで知った。しかし、末端の0がくると省略されるため、任意の桁数が得られるとは限らない。以下のコードでも100万回ぐらい生成を繰り返すと6桁のものがでてきたりする。
Math.random().toString(32).substring(2) // 'a6dpgjqlq8g' 等任意の桁数・任意の文字で
var S="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" var N=16 Array.from(Array(N)).map(()=>S[Math.floor(Math.random()*S.length)]).join('')一番最初に考えたやり方がこれだった。
なお、
Array(N)だけでは長さNの配列になっているが要素が無い状態のため、mapが機能しないらしい。
そのため、Array.from(Array(N))としてやることで、undefinedな要素が入りmapが機能するようになる。(ES6以降なら、Array.fromの代わりに[...Array(N)]が使える。以降はES6/ES5ごちゃまぜになっている。)ブラウザ
よりセキュアな乱数生成器で
「Math.randomはセキュアではないのでは?」という
難癖をつける場合、crypto.getRandomValuesがあるのでこちらを使う。結構古いブラウザもサポートしてる模様。IE11もmsCryptoから使える。以下の方法は除算を使うので特定の文字に偏りが起きる。なのでセキュア志向なら使ったらダメ。(以下の例だと
[a-h]が出やすい)var S="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" var N=16 Array.from(crypto.getRandomValues(new Uint8Array(N))).map((n)=>S[n%S.length]).join('')なお、
Uint8ArrayからUint32Arrayにすると偏りは少しはマシになる。後述。これよりも任意の文字を偏りなく出す方法を他のAPIで出来ないか考えたけど、すぐに思い浮かばなかったので諦めてます。
Base64で
文字を用意するのが面倒な場合、
String.fromCharCodeで変換してからbtoaでBase64変換を使う手がある。複雑な記号は使えないが、除算を使わない分こっちのほうが偏りも少ない気がする。(未調査)
var N=16 btoa(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(N)))).substring(0,N)Nodeのみ
よりセキュアな乱数生成器で
Nodeにはブラウザとは異なるAPIを持つ
cryptoモジュールがある。ブラウザの
crypto.getRandomValuesと同じ動作をするcrypto.randomFillSyncがあるのでこれで。以下の方法も同じように除算を使ってるので偏ります。
const crypto = require('crypto') const S="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" const N=16 Array.from(crypto.randomFillSync(new Uint8Array(N))).map((n)=>S[n%S.length]).join('')Base64で
Base64も同じ要領で...と思ったが、btoaがないので、ブラウザのようには行えない。
代わりにNodeには
crypto.randomBytesがある。これはN個のランダムなバイト列を作り、Node固有のBufferという型で返す。(crypto.randomFillSync(new Uint8Array(N))に似ているが、戻り値の型が違う。)そして、このBufferがBase64変換に対応している。なので、もう少し短く書ける。
const crypto = retuire('crypto') const N = 16 crypto.randomBytes(N).toString('base64').substring(0, N)Nodeはこれが一番スマートな気がする。
おまけ:剰余計算による偏り
質の良い乱数生成期を使ったとしても、剰余を求めるやり方を行ってしまうと、偏りが起きる場合がある。
const S="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" // 62文字 let p=Array(S.length).fill(0) // 100個づつ乱数を取り出し集計する処理を6200回繰り返す(620000回行う) for(let i=0;i<100*S.length; ++i){ const arr = crypto.randomFillSync(new Uint8Array(100)) for(let j=0; j<arr.length; ++j){ p[arr[j]%S.length]++; } } p // => 均等にばらければ全部が10000前後になるはずだが、あきらかに0-7番目の要素のカウントが大きいことが分かる。これは、0~255(256個)がランダムで得られたとしても、剰余計算によって0~61(62個)のいずれかになる。
すると、0~61,62~123, 124~185,186~247の間は均等に出現するが、残りの248~255は0~7しか出現しえないため、この分が他と比べて多く出る。これで偏りが起きる。
逆に256を割り切れる数(2,4,8...64,128)で割れば計算による偏りは起きない。もし偏る場合は元の乱数の問題。また、ランダムで得られる範囲0-255と狭いせいというのもあるので、この範囲を十分に大きくすると剰余計算による偏りは減らすことができる。
上記のコードなら、Uint8Array=>Uint32Arrayにしてみると、偏りが目立たなくなることがわかる。
- 投稿日:2019-02-03T03:29:45+09:00
【JS】setTimeoutを用いた、非同期処理入門
概要
setTimeoutを用いて、非同期処理の処理順をまとめました。
コールバック -> Promise -> async/await の順に説明する。setTimeout
基本構文
setTimeout('コールバック関数', 'タイムアウト時間')1秒後に
hogeを出力する。function callback(){ console.log('hoge') } setTimeout(callback, 1000)出力結果hoge無名関数を用いて書く。
setTimeout(function(){ console.log('hoge') }, 1000)アロー演算子を用いて書く。
setTimeout(() => { console.log('hoge') }, 1000)アロー演算子を用いて書く。(中括弧を省略)
setTimeout(() => console.log('hoge'), 1000)処理順
非同期処理の処理順を確認する。
console.log(1) setTimeout(() => console.log(2), 1000) console.log(3)出力結果1 3 2timeout時間
0秒でも、処理順は変わらない。console.log(1) setTimeout(() => console.log(2), 0) console.log(3)出力結果1 3 2コールバック地獄
非同期処理が複数重なると、コールバック地獄に陥る。
setTimeout(() => { console.log(1) setTimeout(() => { console.log(2) setTimeout(() => { console.log(3) }, 1000) }, 1000) }, 1000)出力結果1 2 3コールバック地獄の回避方法
Promise化すると、thenを用いたメソッドチェーンで処理を繋げられる。
new Promise(function(resolve) { resolve('Hello') }).then(function(value) { console.log(value) // Hello return 'World' }).then(function(value) { console.log(value) // World })出力結果Hello Worldresolve、returnの値が、コールバック関数の引数になる。
アロー演算子を用いて書き換えてみる。new Promise(resolve => resolve('Hello')) .then(value => { console.log(value) // Hello return 'World' }).then(value => { console.log(value) // World })出力結果Hello Worldコールバック地獄を、Promiseで書き直してみる。
function sleep(ms) { return new Promise(function(resolve) { setTimeout(function() { resolve() }, ms) }) } sleep(1000) .then(function() { console.log(1) return sleep(1000) }).then(function() { console.log(2) return sleep(1000) }).then(function() { console.log(3) })出力結果1 2 3Promiseとアロー演算子を用いて書き換えてみる。
const sleep = ms => new Promise(resolve => setTimeout(() => resolve(), ms)) sleep(1000) .then(() => { console.log(1) return sleep(1000) }).then(() => { console.log(2) return sleep(1000) }).then(() => { console.log(3) })出力結果1 2 3async関数内で、Promise関数にawaitを用いると、同期的に処理できる。
function sleep(ms) { return new Promise(function(resolve) { setTimeout(resolve, ms) }) } async function asyncFunc() { await sleep(1000) console.log(1) await sleep(1000) console.log(2) await sleep(1000) console.log(3) } asyncFunc()出力結果1 2 3async/await とアロー演算子を用いた場合
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) const asyncFunc = async () => { await sleep(1000) console.log(1) await sleep(1000) console.log(2) await sleep(1000) console.log(3) } asyncFunc()出力結果1 2 3更に、即時関数を用いて書くと、簡潔に書ける。
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) !(async () => { await sleep(1000) console.log(1) await sleep(1000) console.log(2) await sleep(1000) console.log(3) })()出力結果1 2 3まとめ
非同期処理の処理順をまとめました。
async/await を用いることで、とても簡潔に書けます。
間違い・指摘等があればコメントお願いします。参考文献
- 投稿日:2019-02-03T03:29:45+09:00
setTimeoutを用いた、非同期処理入門
概要
setTimeoutを用いて、非同期処理の処理順をまとめました。
コールバック -> Promise -> async/await の順に説明する。setTimeout
基本構文
setTimeout(コールバック関数, タイムアウト時間)1秒後に
hogeを出力するfunction callback(){ console.log('hoge') } setTimeout(callback, 1000)無名関数を用いて書く
setTimeout(function(){ console.log('hoge') }, 1000)アロー演算子を用いて書く
setTimeout(() => { console.log('hoge') }, 1000)アロー演算子を用いて書く(中括弧を省略)
setTimeout(() => console.log('hoge'), 1000)処理順
非同期処理の処理順を確認する
console.log(1) setTimeout(() => console.log(2), 1000) console.log(3) // 1 -> 3 -> 2timeout時間
0秒でも、処理順は変わらないconsole.log(1) setTimeout(() => console.log(2), 0) console.log(3) // 1 -> 3 -> 2同期的に処理したい場合
Promise化すると、thenを用いたメソッドチェーンで処理を繋げられる
const promiseTimeout = new Promise(function(resolve) { setTimeout(function() { console.log(2) resolve() }, 1000) }) console.log(1) promiseTimeout.then(function() { console.log(3) }) // 1 -> 2 -> 3Promiseとアロー演算子を用いた場合
const promiseTimeout = new Promise(resolve => setTimeout(() => { console.log(2) resolve() }, 1000) ) console.log(1) promiseTimeout.then(() => console.log(3)) // 1 -> 2 -> 3async関数内で、Promise関数にawaitを用いると、同期的に処理できる
function promiseTimeout() { return new Promise(function(resolve) { setTimeout(function() { console.log(2) resolve() }, 1000) }) } async function asyncFunc() { console.log(1) await promiseTimeout() console.log(3) } asyncFunc()async/await とアロー演算子を用いた場合
const promiseTimeout = () => new Promise(resolve => setTimeout(() => { console.log(2) resolve() }, 1000) ) const asyncFunc = async () => { console.log(1) await promiseTimeout() console.log(3) } asyncFunc()まとめ
非同期処理の処理順をまとめました。
async/await を用いることで、とても簡潔に書けます。
- 投稿日:2019-02-03T03:29:45+09:00
setTimeoutを用いた非同期処理入門
概要
setTimeoutを用いて、非同期処理の処理順をまとめました。
コールバック -> Promise -> async/await の順に説明する。setTimeout
基本構文
setTimeout(コールバック関数, タイムアウト時間)1秒後に
hogeを出力するfunction callback(){ console.log('hoge') } setTimeout(callback, 1000)無名関数を用いて書く
setTimeout(function(){ console.log('hoge') }, 1000)アロー演算子を用いて書く
setTimeout(() => { console.log('hoge') }, 1000)アロー演算子を用いて書く(中括弧を省略)
setTimeout(() => console.log('hoge'), 1000)処理順
非同期処理の処理順を確認する
console.log(1) setTimeout(() => console.log(2), 1000) console.log(3) // 1 -> 3 -> 2timeout時間
0秒でも、処理順は変わらないconsole.log(1) setTimeout(() => console.log(2), 0) console.log(3) // 1 -> 3 -> 2コールバック地獄
非同期処理が複数重なると、コールバック地獄に陥る
setTimeout(() => { console.log(1) setTimeout(() => { console.log(2) setTimeout(() => { console.log(3) }, 1000) }, 1000) }, 1000) // 1 -> 2 -> 3コールバック地獄の回避方法
Promise化すると、thenを用いたメソッドチェーンで処理を繋げられる
const promiseTimeout = new Promise(function(resolve) { setTimeout(function() { console.log(2) resolve() }, 1000) }) console.log(1) promiseTimeout.then(function() { console.log(3) }) // 1 -> 2 -> 3Promiseとアロー演算子を用いた場合
const promiseTimeout = new Promise(resolve => setTimeout(() => { console.log(2) resolve() }, 1000) ) console.log(1) promiseTimeout.then(() => console.log(3)) // 1 -> 2 -> 3async関数内で、Promise関数にawaitを用いると、同期的に処理できる
function promiseTimeout() { return new Promise(function(resolve) { setTimeout(function() { console.log(2) resolve() }, 1000) }) } async function asyncFunc() { console.log(1) await promiseTimeout() console.log(3) } asyncFunc() // 1 -> 2 -> 3async/await とアロー演算子を用いた場合
const promiseTimeout = () => new Promise(resolve => setTimeout(() => { console.log(2) resolve() }, 1000) ) const asyncFunc = async () => { console.log(1) await promiseTimeout() console.log(3) } asyncFunc() // 1 -> 2 -> 3まとめ
非同期処理の処理順をまとめました。
async/await を用いることで、とても簡潔に書けます。
- 投稿日:2019-02-03T03:29:45+09:00
【JavaScript】setTimeoutを用いた、非同期処理入門
概要
setTimeoutを用いて、非同期処理の処理順をまとめました。
コールバック -> Promise -> async/await の順に説明する。setTimeout
基本構文
setTimeout('コールバック関数', 'タイムアウト時間')1秒後に
hogeを出力する。function callback(){ console.log('hoge') } setTimeout(callback, 1000)無名関数を用いて書く。
setTimeout(function(){ console.log('hoge') }, 1000)アロー演算子を用いて書く。
setTimeout(() => { console.log('hoge') }, 1000)アロー演算子を用いて書く。(中括弧を省略)
setTimeout(() => console.log('hoge'), 1000)処理順
非同期処理の処理順を確認する。
console.log(1) setTimeout(() => console.log(2), 1000) console.log(3) // 1 -> 3 -> 2timeout時間
0秒でも、処理順は変わらない。console.log(1) setTimeout(() => console.log(2), 0) console.log(3) // 1 -> 3 -> 2コールバック地獄
非同期処理が複数重なると、コールバック地獄に陥る。
setTimeout(() => { console.log(1) setTimeout(() => { console.log(2) setTimeout(() => { console.log(3) }, 1000) }, 1000) }, 1000) // 1 -> 2 -> 3コールバック地獄の回避方法
Promise化すると、thenを用いたメソッドチェーンで処理を繋げられる。
new Promise(function(resolve) { resolve('Hello') }).then(function(value) { console.log(value) // Hello return 'World' }).then(function(value) { console.log(value) // World }) // Hello // Worldresolve、returnの値が、コールバック関数の引数になる。
アロー演算子を用いて書き換えてみる。new Promise(resolve => resolve('Hello')) .then(value => { console.log(value) // Hello return 'World' }).then(value => console.log(value)) // World // Hello // Worldコールバック地獄を、Promiseで書き直してみる。
function sleep(ms) { return new Promise(function(resolve) { setTimeout(function() { resolve() }, ms) }) } sleep(1000) .then(function() { console.log(1) return sleep(1000) }).then(function() { console.log(2) return sleep(1000) }).then(function() { console.log(3) }) // 1 -> 2 -> 3Promiseとアロー演算子を用いて書き換えてみる。
const sleep = ms => new Promise(resolve => setTimeout(() => resolve(), ms)) sleep(1000) .then(() => { console.log(1) return sleep(1000) }).then(() => { console.log(2) return sleep(1000) }).then(() => { console.log(3) }) // 1 -> 2 -> 3async関数内で、Promise関数にawaitを用いると、同期的に処理できる。
function sleep(ms) { return new Promise(function(resolve) { setTimeout(resolve, ms) }) } async function asyncFunc() { await sleep(1000) console.log(1) await sleep(1000) console.log(2) await sleep(1000) console.log(3) } asyncFunc() // 1 -> 2 -> 3async/await とアロー演算子を用いた場合
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) const asyncFunc = async () => { await sleep(1000) console.log(1) await sleep(1000) console.log(2) await sleep(1000) console.log(3) } asyncFunc() // 1 -> 2 -> 3更に、即時関数を用いて書くと、簡潔に書ける。
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) !(async () => { await sleep(1000) console.log(1) await sleep(1000) console.log(2) await sleep(1000) console.log(3) })() // 1 -> 2 -> 3まとめ
非同期処理の処理順をまとめました。
async/await を用いることで、とても簡潔に書けます。
間違い・指摘等があればコメントお願いします。参考文献
