ちょっとしたことだけど、JavaScriptにはsleepがないので。
awaitnewPromise(resolve=>setTimeout(resolve,1000));
ちょっとしたことだけど、JavaScriptにはsleepがないので。
awaitnewPromise(resolve=>setTimeout(resolve,1000));
公式サイトのインストールコマンドを打ったのにインストールできない。
環境 : Mac OS Catalina 10.15.6
シェル : ZSH
nodenv : 1.3.2
node : v8.11.3
インストールコマンド
% npm install -g @vue/cli
エラーメッセージ
npm ERR! code E404
npm ERR! 404 Not Found: @vue/cli-ui@^4.4.6
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/whoami/.npm/_logs/2020-08-06T07_59_42_517Z-debug.log
以前インストールした(インストール失敗した?)すべてのvue cliを削除します。
sudo npm uninstall --global vue-cli
sudo npm uninstall --global @vue/cli
最新バージョンをインストールします。
sudo npm install --global @vue/cli@latest
バージョンを確認
vue -V
$ docker -v
Docker version 18.09.0, build 4d60db472b
$docker-composerun--rm/bin/bash
$ npm i --no-bin-links$ npm run eslint
みたいなコマンドを使いたい。
sh: 1: eslint: not found
こんな感じで怒られる。
node_modules/.bin
にコマンドのリンクが置かれていないため。
Mac では自動で作成されていたため、Windows ではシンボリックリンクがはれない問題が原因なのかもしれない。
node_modules を一度全て削除し、docker を介さずに npm i
を実行すると node_modules/.bin
が作成される。
>npmi>docker-composerun--rm/bin/bash
$ npm run eslint
とおった。
http://minatooe.hatenablog.jp/entry/2017/12/15/234418
あとは、Win は管理者権限なら symlink を作れるようになるらしいので、vagrant を動かすコマンドプロンプトを管理者権限で起動すると--no-bin-links をつけなくても大丈夫になるらしい。
とあったのでやってみたができなかった…。
【実装環境】
* Node.jsのStable版をインストール
* 実装が便利になるということで、Expressを導入。
* Vagrant上で8001のポートを空けて作業
Nodeでログイン処理を行うにあたり、
機能を追加した結果が以下の通り。
"dependencies": {
"body-parser": "^1.19.0",
"ejs": "^3.1.3",
"express": "^4.17.1",
"express-session": "^1.17.1",
"request": "^2.88.2"
}
処理のスクリプトを書いているファイル内の処理。
ブラウザで/loginが叩かれた際、login.htmlをレンダリング。
// /loginが開かれた場合の処理
app.get('/login', function (req, res) {
res.render('login.html', {err:""});
req.session.name = "";
})
この画面で「ログイン」ボタンを押すと、/loginSend
にPOSTする。
<form action="/loginSend" method="POST">
メールアドレス:<input type="text" name="mail" >
<br>
パスワード :<input type="text" name="password">
<br>
<br>
<input type="submit" value="ログイン" >
</form>
・ここで入力されたID/パスワードを、データベースに取得する
(その際にパスワードはハッシュ化してID/ハッシュ化されたパスワードの組み合わせを取得する)
・正常なログインができた際、セッション情報を付与する。
`//アイパス一致すれば、Main画面をレンダリングする。
if (result["結果"] === "OK"){
res.render('main.html');
req.session.mail = result["user_id"];
req.session.name = result["user_name"];
}`
執筆中..
Node.jsアプリケーションからJDBCでSQL Server、Oracle、DB2、Postgres、MongoDBなどのDBや、Salesforce、Eloqua、Oracle Sales Cloud、Oracle Service CloudなどのSaaSアプリケーションにJDBCで接続する必要性があるならば、DataDirect JDBCドライバを利用すると楽勝です。
この記事では、DataDirect JDBC ドライバを使用して Node.js から Salesforce データに接続してみます。
事前準備
Node.js
1,こちらよりDataDirect JDBCドライバをダウンロードします(お試し版が15日使えます)。
2,jarファイルのダウンロードが終了したら、パッケージを実行してJDBCドライバをインストールします。
1)Windowsの場合、インストーラを実行し、JDBCドライバをインストールします。
2)Unix/Linuxの場合、以下のコマンドでドライバをインストールします。
java -jar PROGRESS_DATADIRECT_JDBC_INSTALL.jar
1,Node.jsでは、JDBCドライバを利用するためにnode-jdbcパッケージをインストールする必要があります。
2,以下のコマンドでパッケージをインストールします。
npm i jdbc
3,DataDirect JDBCドライバを/install_dir/Progress/JDBC_XX/libからプロジェクトライブラリにコピーします。
今回はSalesforceで試すので、Salesforce JDBCドライバであるsforce.jarをコピーしました。
1,DataDirect JDBCドライバを経由し、Salesforceに接続。テーブルにクエリするサンプルコードを以下に記述します。必要に応じて変更くださいね!
var JDBC = require('jdbc');var jinst = require('jdbc/lib/jinst');var asyncjs = require('async');if (!jinst.isJvmCreated()) {
jinst.addOption("-Xrs"); jinst.setupClasspath(['./drivers/sforce.jar']); }
var config = {
// SparkSQL configuration to your server
url: 'jdbc:datadirect:sforce://login.salesforce.com;DatabaseName=default;SecurityToken=stoken',
drivername: 'com.ddtek.jdbc.sforce.SForceDriver',
minpoolsize: 1,
maxpoolsize: 100,
user: 'saiteja09@gmail.com',
password: 'password',
properties: {}
}; var sforcesqldb = new JDBC(config);//initialize
sforcesqldb.initialize(function(err) {
if (err) {
console.log(err); }
});
sforcesqldb.reserve(function(err, connObj) {
if (connObj) {
console.log("Using connection: " + connObj.uuid); var conn = connObj.conn;
// Query the database.
asyncjs.series([
function(callback) {
// Select statement example.
conn.createStatement(function(err, statement) {
if (err) {
callback(err); } else {
statement.setFetchSize(100, function(err) {
if (err) {
callback(err); } else {
//Execute a query
statement.executeQuery("SELECT * FROM SFORCE.Account;",
function(err, resultset) {
if (err) {
callback(err)
} else {
resultset.toObjArray(function(err, results) {
//Printing number of records
if (results.length >0){ console.log("Record count: " + results.length); console.log(results); }
callback(null, resultset); }); }
}); }
}); }
}); },
], function(err, results) {
// Results can also be processed here.
// Release the connection back to the pool.
sforcesqldb.release(connObj, function(err) {
if (err) {
console.log(err.message); }
}); }); }
});
2,setupClasspath メソッドに注意です。DataDirect Salesforce JDBC ドライバへのパスを指定する必要があります。
上記のコードを実行すると、レコード数とテーブルデータがコンソールに表示されます。
簡単ですね!
自分windowsユーザーなのにMacで入れたいとのことで、人に教えないといけない感じになり、自分のMacで試してみてできたので備忘録残します。
ターミナルMac便利ですね。。
基本的には
NodebrewでNodeをインストールする - Qiita
こちらの記事を参考にさせてもらいましたが、自分の環境だとちょっと出来ない箇所もあったので出来なかった分ここに残しておく感じです。
Homebrew
こちらからいれましょう/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
ターミナルで叩いてインストール
基本的にはnpm使わないので削除します。
https://nabewakashi.com/how-to-switch-to-nodebrew
こちらの記事を参考にしました。
sudo使うときは気を付けましょう。
ですが、nodeが削除できてなかったのでおそらくゴミが残っている感じだったので、
$ which node
/usr/local/bin/node
$ rm -rf /usr/local/bin/node \
> node_modules
こちらで削除したらnodeが消えました。
インストールbrew install nodebrew
確認nodebrew -v
バージョンが表示されればOK。
最初、MACですと.bash_profileがないそうなので、作成します。
https://qiita.com/k3ntar0/items/eb8cdbd8eba9da388def
こちら非常に助かりました。
.bash_profileを開いたらexport PATH=$HOME/.nodebrew/current/bin:$PATH
こちらでパスを通します
保存したらsource ~/.bash_profile
で更新して反映します。
nodebrew setup
これやらないとインストールできないらしいです
・バージョン確認nodebrew ls-remote
・指定したバージョンのインストールnodebrew install-binary <version>
・インストールしたバージョンのリストnodebrew ls
・指定したバージョンを指定nodebrew use <version>
node -v
で入ってればOK
今日JavaScript(Node.js)を書いていたときに遭遇した出来事を備忘録がてら書き残しておく。
下記のコードはエラーになる。
constfs=require('fs')(async()=>{console.log(fs)})()
実行結果
(async ()=>{
^
TypeError: require(...) is not a function
JavaScriptは;
を書こうが書かまいがが動く、と思っていたが、1行目の末尾に ;
をつけることで、今回のコードは問題なく動くようになる。
constfs=require('fs');(async()=>{console.log(fs)})()
※実行結果は長くなるので省略。サンプルコードが悪かった...
これはどういうことかなと思ったけど、考えてみれば単純なことだった。
JavaScriptは文末にセミコロンを付けなかった場合、その後の文が構文的に解釈可能な場合、解釈しようとする。
自分もここらへんは自信がないので、JavaScript Primerの記述も引用させていただく。
JavaScriptには、特殊なルールに基づき、セミコロンがない文も行末に自動でセミコロンが挿入されるという仕組みがあります。 しかし、この仕組みは構文を正しく解析できない場合に、セミコロンを足すという挙動を持っています。 これにより、意図しない挙動を生むことがあります。そのため、必ず文の末尾にはセミコロンを書くようにします。
引用元のページ: https://jsprimer.net/basic/statement-expression/#statement-expression-summary
つまり先ほど私が書いたコードは下記のように解釈された形となる。
// require('fs')(/* ~ */) 的な解釈となっていたconstfs=require('fs')(async()=>{console.log(fs)})()
気になったので試してみた。
prettier
の設定で semi: false
にしたとき、;
はどこにつくのか?
結果は下記の通り。
constfs=require('fs');(async()=>{console.log(fs)})()
普段 ;
は付ける派なのだが、なんとなくプロトタイプのコードを書いていてつけないでいた。後から prettier
かければ済む話だとか考えていたら、思わぬエラーに引っかかった。
おかげでJavaScriptのことを少し知ることができたので結果的に良かったと思う。
Reactでデータグリッドを実装したいときにおすすめしたいコンポーネント集です。
Material UIが好きなので、Material UIを使っている私の目線でのコメントが多いですが、ご容赦ください。
まだ実装お試ししていないけど良さそうなものがいくつかあるので、少しづつ追加しますよ :D
データを見せることに向いている系です。
Table React component - Material-UI
MaterialUI純正のテーブルコンポーネントです。ソートやフィルタは自分で実装してイベントで差し込んでいく感じですね。仮想テーブルもできますが、他のライブラリとのあわせ技なので、このコンポーネントの特徴ってことでもないですね。なにより、Material UIの純正なので、Material UIをアプリの全体荷適用しているなら第一候補ですね。見た目もスッキリ統一感が出ますしね。あとはなんて言ったって、Material UIはデモページもAPIのページもとっても詳しい。ありがたい。
Reactのテーブルといえばこれですね。名前もそのままReact-Table。いろいろな方がコントリビュートしてくれているので、やりたいことはなんだってできるような印象です。デモページもとっても豊富でわかりやすいですね。Material UIにこだわらないなら、第一候補ではないでしょうか?ちょっと見た目の調整は頑張らないといけないかもしれないですね。Style差し込んで行きましょう。
Grid.js - Advanced table plugin
比較的新しいライブラリです。TypeScriptで実装されているのがいいですね!新しい割にGitHubスター数が結構多いので、これからグイグイくるんじゃないかなぁ、という期待と、TypeScriptを採用しているので仲良くなれそうだなぁという理由から、序盤で紹介させていただきました。見た目もかっこいいですね。
Materialデザインを踏襲して実装されたテーブルコンポーネントですね。Material UIのサイトでも紹介されているので、公式もその良さを認めているのかな?テーブル自体の操作感はよく、いいコンポーネントだと思います。
Material-table と対を成すのが、mui-datatablesです。テーブル自体の操作感はかなり良いです。デモページも結構見やすくて、見ているだけでも楽しくなるので、おすすめです。gregnb/mui-datatables
データを見ながらちょちょっと修正したいときに便利なコンポーネントです。ほとんどExcelじゃん、ってのもあります。
React Data Grid · Excel-like data grid component built with React
Excelライクな感じになっているが、それなりにWeb感も残しています。Excelほど自由自在にコピペできる感じではないのがちょっと惜しい。
かなりExcelライクな感じですね。テーブルのほとんどの要素を編集可能にしないといけないケースには向いていそうですね!
金の力は偉大だ!!!
なにもいうことはないです。すげーよ。
参考にしたサイト
https://reffect.co.jp/node-js/express-js-connect-mysql#MySQL-3
こちらのサイトがとても解説が丁寧でわかりやすかった。
実装方法は上記記事を参照
やってみて分かったことは感想に記述
・node.jsのCRUDはphpと動きが似ている
・mysqlのDBとtableはjsファイル内で記述してサーバーが更新されると自動で作成される。
その後も更新のたびに新しく同じDBとtableを作成しようとしてエラーになるので、一度作ったDBとtableのjsファイル内の記述はコメントオフか削除が必要でした。
・table plusはやはり便利
参考
https://reffect.co.jp/windows/tableplus-connect-mysql-sqlite
初期設定のパスワードやuserはmysqlのことなので、自分のユーザー名やパスワードではなく、
user:root(mysqlの場合)
パスワード:なし(mysqlの場合)
記述の保存は基本comand + s
基本クリックして登録、更新、削除をする
Data:データの登録、更新、削除
Structure: VARCHARやIDなどの編集
get_redirect.js というファイル名で以下の内容を保存する。
'use strict'consthttps=require('https')consthttp=require('http')// リダイレクト先 URL を取得する関数functionget_redirect_url(src_url){returnnewPromise((resolve,reject)=>{try{// https と http で使うモジュールを変えるconstclient=src_url.startsWith('https')?https:http// 4xx や 5xx ではエラーが発生しないので注意client.get(src_url,(res)=>{// HTTP レスポンスから Location ヘッダを取得 (ヘッダ名は小文字)resolve(res.headers['location'])}).on('error',(err)=>{reject(err)})}catch(err){reject(err)}})}(async()=>{// コマンドライン引数を取得constsrc_url=process.argv[2]// リダイレクト先URLを取得constredirect_url=awaitget_redirect_url(src_url).catch(err=>{console.log(err)})// リダイレクト先URLを出力if(redirect_url){console.log(redirect_url)}})()
実行例。
$ node get_redirect.js https://bit.ly/3kmTOkc
https://t.co/yITSBp4ino
$ node get_redirect.js https://t.co/yITSBp4ino
https://qiita.com/niwasawa
$ node get_redirect.js https://qiita.com/niwasawa
■HOMEBREWとは基礎
■mysqlを自身のMacへ
■node.jsでの開発途中で、mysqlが無く、先に進めなかった為
■ Mac OS catalina
■ Homebrew 2.4.9
■ mysql Ver 8.0.21
*Xcodeも自動的にインストールされます。便利
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
.
.
.
// 5分くらい待ちます。下記の文は自動で出てきます。
$ Downloaded Command Line Tools for Xcode
$ brew install mysql
$ brew -v
Homebrew 2.4.9
Homebrew/homebrew-core (git revision b32b4; last commit 2020-08-08)
$ mysql --version
mysql Ver 8.0.21 for osx10.15 on x86_64 (Homebrew)
以上。
■HOMEBREWとはMACのOSを動かす、パッケージマネージャー
■mysqlはDBの種類
例
パッケージマネージャー = app store
パッケージ = app
みたいな感じでしょうか。。
appstoreがあるからappがダウンロードできる。
■ 【node.js】 node.jsインストール 芋っていたけど、簡単だった件...
https://qiita.com/tanaka-yu3/items/739db5ffed24a8d9ae4b
■ 【comandLine】 一言で コマンドライン 各種コマンド ターミナル
https://qiita.com/tanaka-yu3/items/b32e353bd6d7c9ebd4fb
■作業環境を整えるMacOSXのパッケージマネージャ「Homebrew」のインストール方法と使い方
https://liginc.co.jp/web/tool/mac-iphone/151069
自作のSPAをスクラップ&ビルドするので今度はDIを使ってみようと思ったけどinverify はなんだか面倒くさそうなので bottlejs を使う。
Webpackとnpm install --save bottlejs とかやっておいた。
<!DOCTYPE html><htmllang="ja"><head><metacharset="UTF-8"><title>Kamishibai framework</title></head><body><!-- IE11 promise --><script src="https://www.promisejs.org/polyfills/promise-7.0.4.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.4/fetch.min.js"></script><script src="/js/bundle.js"></script></body></html>
importBottlefrom'bottlejs'window.kms=window.kms||{};window.kms.Unko=function(){this.color="brown";}window.kms.rootBottle=newBottle();window.kms.rootBottle.service("💩",window.kms.Unko);window.kms.unko=window.kms.rootBottle.container["💩"];alert("💩の色は"+window.kms.unko.color);
見事にボトルに💩を詰めておくことができた。
これで何ができるかってことだけど、処理の流れとオブジェクトの作られ方が分離できるってことかなと思う。
例えば、その💩に🐝がついていたとしても、ロジック側でその設計を考える必要がなくなるというか。あらかじめ🐝付きの💩をボトルに詰めときゃいいじゃんっていう。
その用途だったらかなり古いけど bottlejs で十分機能するかなと思って実験中。
30代未経験からエンジニア転職をめざすコーディング初学者のYNと申します。お読みいただきありがとうございます。
コーディング初学者にとってのAWS入門といえばLambda
!、サーバレスアプリを作ろう!、ということでメッセージをオウム返ししてくるLINEのbotをつくりました。
下記参考記事をそのままコピーした内容になってしまったのですが、学習ログとして投稿させていただきました。
下記のように、こちらが送ったテキストメッセージをそのまま返答してくれる、オウム返しbotを作ります。
下記のサーバレス構造を構築します。(こちらの記事から図を拝借させていただきました。)
Lambda
の設定$ cd ~
$ mkdir line-bot
$ cd line-bot
$ npm install @line/bot-sdk
"use strict";constline=require("@line/bot-sdk");constclient=newline.Client({channelAccessToken:process.env.ACCESSTOKEN});// ①SDKをインポートconstcrypto=require("crypto");exports.handler=function(event,context){letbody=JSON.parse(event.body);letsignature=crypto.createHmac("sha256",process.env.CHANNELSECRET).update(event.body).digest("base64");letcheckHeader=(event.headers||{})["X-Line-Signature"];if(signature===checkHeader){// ②cryptoを使ってユーザーからのメッセージの署名を検証するif(body.events[0].replyToken==="00000000000000000000000000000000"){letlambdaResponse={statusCode:200,headers:{"X-Line-Status":"OK"},body:'{"result":"connect check"}',};context.succeed(lambdaResponse);// ③接続確認エラーを確認する。}else{lettext=body.events[0].message.text;constmessage={type:"text",text,};client.replyMessage(body.events[0].replyToken,message).then((response)=>{letlambdaResponse={statusCode:200,headers:{"X-Line-Status":"OK"},body:'{"result":"completed"}',};context.succeed(lambdaResponse);}).catch((err)=>console.log(err));// ④リクエストとして受け取ったテキストをそのまま返す}}else{console.log("署名認証エラー");}};
下記、index.jsにおける処理を解説します。
①SDKをインポートする
constline=require("@line/bot-sdk");constclient=newline.Client({channelAccessToken:process.env.ACCESSTOKEN});githubのexampleでSDKの使い方が参照できます。
②cryptoを使ってユーザーからのメッセージの署名を検証する
constcrypto=require("crypto");exports.handler=function(event,context){letbody=JSON.parse(event.body);letsignature=crypto.createHmac("sha256",process.env.CHANNELSECRET).update(event.body).digest("base64");letcheckHeader=(event.headers||{})["X-Line-Signature"];if(signature===checkHeader){// ここでlambdaの処理を記載}cryptoはnode.jsに標準で組み込まれている暗号化に関するライブラリで、botにおける実装の詳細についてはLINE公式ドキュメントに書いてあります。
(暗号化についてはこちらの記事が分かりやすかったです)ここでは、下記2点が一致するかを検証しています。
signature
: ユーザーから送られてきたリクエスト(event.body
)を、秘密鍵(CHANNELSECRET
)を使って暗号化したもの
event.headers["X-Line-Signature"]
:リクエストヘッダーに含まれる署名
③接続確認の場合の処理を実装する
botが接続確認を行う場合、
replyToken="000..."
のリクエストが来ます。letbody=JSON.parse(event.body);if(body.events[0].replyToken==="00000000000000000000000000000000"){letlambdaResponse={statusCode:200,headers:{"X-Line-Status":"OK"},body:'{"result":"connect check"}',};context.succeed(lambdaResponse);}
④リクエストとして受け取ったテキストをそのまま返す
ユーザーから送られてきたリクエストの中身(イベントオブジェクト)はLINE公式ドキュメントにまとめられています。
リクエストに含まれるメッセージがテキストの場合、body.events[0].message.text
に含まれます。
また、client.replyMessage(replyToken, message)
のメソッドを使うことで、ユーザーにメッセージを返信することが出来ます。lettext=body.events[0].message.text;constmessage={type:"text",text,};client.replyMessage(body.events[0].replyToken,message).then((response)=>{letlambdaResponse={statusCode:200,headers:{"X-Line-Status":"OK"},body:'{"result":"completed"}',};context.succeed(lambdaResponse);})
LINE Official Account Manager
からユーザーからのメッセージに対するあいさつや応答の設定をすることができます。
Lambda
を使うことで、簡単にLINEのbotを作ることができます。
初学者でも1時間弱でつくることができました。
機械学習や外部のAPIを組み合わせれば、面白いことができそうです。
ご覧いただきありがとうございました。
/bin/bash -c"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
途中でXCodeのインストール確認があるのでEnterを押す
nodebrewでバージョンを管理したい
brew install nodebrew
途中経過
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).==> New Formulae
osm
==> Updated Formulae
Updated 10 formulae.
==> Downloading https://github.com/hokaccha/nodebrew/archive/v1.0.1.tar.gz
==> Downloading from https://codeload.github.com/hokaccha/nodebrew/tar.gz/v1.0.1
######################################################################## 100.0%==> Caveats
You need to manually run setup_dirs to create directories required by nodebrew:
/usr/local/opt/nodebrew/bin/nodebrew setup_dirs
Add path:
export PATH=$HOME/.nodebrew/current/bin:$PATH
To use Homebrew's directories rather than ~/.nodebrew add to your profile:
export NODEBREW_ROOT=/usr/local/var/nodebrew
Bash completion has been installed to:
/usr/local/etc/bash_completion.d
zsh completions have been installed to:
/usr/local/share/zsh/site-functions
==> Summary
🍺 /usr/local/Cellar/nodebrew/1.0.1: 8 files, 38.6KB, built in 2 seconds
インストールできたか確認
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
zshにパスを追加
vi ~/.zsh_profile
以下を追加
export PATH=$HOME/.nodebrew/current/bin:$PATH
セットアップをしてnodebrewのインストールを完了する
nodebrew setup
結果
Fetching nodebrew...
Installed nodebrew in$HOME/.nodebrew
========================================
Export a path to nodebrew:
export PATH=$HOME/.nodebrew/current/bin:$PATH========================================
v10.22.0が最新なので以下のコマンドでインストールする
nodebrew install-binary v10.22.0
結果
Fetching: https://nodejs.org/dist/v10.22.0/node-v10.22.0-darwin-x64.tar.gz
############################################################################################################################################################################################### 100.0%
Installed successfully
rouc@roucnombp ~ %
インストールできたか確認
nodebrew ls
結果
v10.22.0
current: none
スイッチする
nodebrew use v10.22.0
スイッチされたか確認
nodebrew ls
結果
v10.22.0
current: v10.22.0 ## <<<--- 現在どのバージョンが使われているかが表示されている
いろんな Linux 環境に Node.js をインストールした記録
「Ubuntuに最新のNode.jsを難なくインストールする」
https://qiita.com/seibe/items/36cef7df85fe2cefa3ea
を参考に、以下の方法を採ることにした。
$ sudo apt update
$ sudo apt install nodejs npm
$ sudo node -v
ここで、 RaspberryPi だと v10.21.0
Ubuntu18.04 だとv8.10.0 だった。
$ sudo npm install n -g
ここで Ubuntu14.04 でエラーが出た。
npm http GET https://registry.npmjs.org/n
npm http GET https://registry.npmjs.org/n
npm http GET https://registry.npmjs.org/n
npm ERR! Error: CERT_UNTRUSTED
npm ERR! at SecurePair.<anonymous> (tls.js:1370:32)
npm ERR! at SecurePair.EventEmitter.emit (events.js:92:17)
npm ERR! at SecurePair.maybeInitFinished (tls.js:982:10)
.
.
.
「npm install で SSL Error になった時の対処法。」
https://blog.yug1224.com/archives/563d9b67bf652a600632d01e/
を参考にして、SSL鍵のバリデーションを一旦OFFしたらうまくいった。
# sudo npm config set strict-ssl false
# sudo npm install n -g
その後設定を元に戻す。
# sudo npm config set strict-ssl true
node をインストールした後、aptでインストールしたものを削除、ログオン。
$ sudo n stable
$ sudo apt purge -y nodejs npm
$ exec $SHELL -l
バージョン確認。
$ node -v
v12.18.2
WebSocketを使ったものをテスト実行するために、モジュールをインストール
# npm install -g ws
実行
# node index.js
Ubuntu14.04では以下のようにエラーが出た
Error: Cannot find module 'ws'
Require stack:
「Node.jsで、存在するはずのmoduleがrequireでエラーになることについて」
https://qiita.com/DNA1980/items/11fdb7233fc288ac3502
を読んで、
echo $NOTE_PATH
で設定されていなかったので以下のように実行すればエラー解消した
export NODE_PATH=`npm root -g`
Nodeがおかしくなった
$ node
Illegal instruction
2020-02-13-raspbian-buster-lite
「Linux 環境に Node.js インストール」
https://qiita.com/nanbuwks/items/ed8adb2d4324c939a349
の通り、以下のようにインストール
1.Linux ディストリビューションの公式パッケージで Node.js と npm を入れる
2.npm install で最新の Node.js を入れる
3.古い Node.js を削除する
node のインストール先を調べる
```
$ which node
/usr/local/bin/node
```
ファイル削除
$ sudo rm -rf /usr/local/bin/node
sudo rm -rf ~/.npm
削除できたかな?
$ npm
/usr/bin/env: ‘node’: No such file or directory
このあと、先の資料「Linux 環境に Node.js インストール」をもう一度実行して入れ直します。
こちらのイメージを使用します。
https://hub.docker.com/r/hayd/deno
FROM hayd/alpine-deno:1.2.2# Prefer not to run as root.USER deno# Cache the dependencies as a layer (the following two steps are re-run only when deps.ts is modified).# Ideally cache deps.ts will download and compile _all_ external files used in main.ts.COPY deps.ts .RUN deno cache deps.ts
# These steps will be re-run upon each file change in your working directory:ADD . .# Compile the main app so that it doesn't need to be compiled each startup/entry.RUN deno cache main.ts
version:'3'services:app:build:.command:"run--allow-net--allow-readmain.ts"ports:-"8000:8000"volumes:-.:/appworking_dir:"/app"
import{serve}from"./deps.ts";constPORT=8000;consts=serve(`0.0.0.0:${PORT}`);constbody=newTextEncoder().encode("Hello World\n");console.log(`Server started on port ${PORT}`);forawait(constreqofs){req.respond({body});}
$ docker-compose up -d
Servestを使用
https://github.com/keroxp/servest
import{createApp}from"https://servestjs.org/@v1.0.0/mod.ts";constapp=createApp();app.handle("/",async(req)=>{awaitreq.respond({status:200,headers:newHeaders({"content-type":"text/plain",}),body:"hello World!",});});app.listen({port:8000});
Dockerコンテナ内の環境にて、npm run serve
を実行すると、下記のようなエラーが発生していました。
ERROR Failed to compile with 2 errors
This relative module was not found:
* ./src/main.js in multi (webpack)-dev-server/client/index.js (webpack)/hot/dev-server.js ./src/main.js, multi (webpack)/hot/dev-server.js (webpack)-dev-server/client/index.js ./src/main.js
筆者の場合、npm install
を実行してもpackage.json
内に含まれているdevDependencies
がインストールされておらず、必要なライブラリ(ここでは@vue/cli-service
)が存在していなかったというのが原因でした。
node.js側の環境変数であるNODE_ENV
をdevelopment
(あるいはdev
)にしてからnpm install
を実行する必要がありました。
NODE_ENV
を設定する方法は、①.コマンドラインからexport
する方法と、docker-composeを使っている場合は②.docker-compose.xml
に記載する方法があります。
export
コマンドで設定する下記のコマンドでNODE_ENV
に環境値を設定できます。
# NODE_ENVを設定$ export NODE_ENV=development
# 設定した値を確認する$ echo$NODE_ENV
development
docker-compose.xml
のenvironmentキーに設定するdocker-composeでコンテナを立ち上げている場合、environment
キーを使って設定することができます。
version:'3'services:web:build:.ports:-"8080:8080"environment:-NODE_ENV=developmenttty:true
export
で設定したときと同様に、$NODE_ENV
をechoすると設定値を確認すると、development
が設定されているのが確認できるはずです。
今回の場合、package.json
に記載されているパッケージが正しくインストールできていると早とちりし、「パスが通っていない」か「windowsでシンボリックリンクが使えないのが悪さしている」と思い込んでいたのが、原因の特定が遅れてしまった原因でした。
ちなみに、パッケージが正しくインストールされているかは、npm list --depth=0
で確認することができます。
# インストールされているパッケージの一覧(一階層のみ)を表示$ npm list --depth=0
project@0.1.0 /app
+-- core-js@3.6.5
`-- vue@2.6.11
# core-js と vue しか入ってないやん!
もし、筆者と同様にnpm run serve
が正しく動作しない場合は、このコマンドで確認してみるといいかもしれません。
この記事は株式会社富士通システムズウェブテクノロジーが企画するいのべこ夏休みアドベントカレンダー 2020の10日目の記事です。本記事の掲載内容は私自身の見解であり、所属する組織を代表するものではありません。
Vue.jsとNode.jsを使い、MongoDBに登録された今までに読んだ本の名前をブラウザで確認できるアプリケーションを作りました。
どんな本を読んだか把握しやすくすることで今後の勉強に役立てたいと思います。
以下は使用するソフトウェアのバージョンです。
OSはWindows10 Enterprise バージョン1809です。
$ node -v
v12.16.1
$ npm -v
6.13.4
$ vue -V
@vue/cli 4.4.6
$ mongo
>db.version()
4.2.8
$ node -v
$ npm -v
C:\Program Files\MongoDB\Server\4.4\bin\
$ mongo
> db.version();
$ mongo
> use mydb
switched to db mydb
> db.createCollection('mylist');
{ "ok" : 1 }
> show collections
mylist
$ mongo
> use mydb
switched to db mydb
> db.mylist.insert({name:'アジャイルサムライ'});
WriteResult({ "nInserted" : 1 })
> db.mylist.insert({name:'エクストリームプログラミング'});
WriteResult({ "nInserted" : 1 })
> db.mylist.insert({name:'テスト駆動開発'});
WriteResult({ "nInserted" : 1 })
> db.mylist.insert({name:'スクラム現場ガイド'});
WriteResult({ "nInserted" : 1 })
$ mkdir my_project
$ cd my_project
$ vue init webpack frontend
$ cd frontend
$ npm run dev
http://localhost:8080
に接続すると、Welcome to Your Vue.js Appと出力された画面を確認できます。$ cd my_project
$ mkdir backend
$ cd backend
$ npm init
$ npm install --save express body-parser cors mongoose
{"name":"backend","version":"1.0.0","description":"","main":"index.js","scripts":{"start":"node index.js"},"author":"","license":"ISC","dependencies":{"body-parser":"^1.19.0","cors":"^2.8.5","express":"^4.17.1","mongoose":"^5.9.27"}}
constexpress=require("express");constbodyParser=require("body-parser");constcors=require("cors");constmongoose=require("mongoose");constBooksList=require("./models/module");constconnectOption={useNewUrlParser:true,useUnifiedTopology:true,};mongoose.connect("mongodb://localhost/mydb",connectOption);constapp=express();app.use(bodyParser.urlencoded({extended:false}));app.use(bodyParser.json());app.use(cors());app.get("/mydb",(req,res)=>{BooksList.find(function(err,result){if(!err){returnres.json(result);}else{returnres.status(500).send("post mylist faild");}});});app.listen(process.env.PORT||3000);
constmongoose=require("mongoose");constSchema=mongoose.Schema;constBooksListSchema=Schema({name:String},{collection:"mylist"});module.exports=mongoose.model("BooksList",BooksListSchema);
$ cd backend
$ npm start
$ cd frontend
$ npm install --save axios
importaxiosfrom"axios";exportdefault()=>{returnaxios.create({baseURL:`http://localhost:3000/`});};
importApifrom"./index";exportdefault{getBooksData(){returnApi().get("/mydb");}};
<template><divclass="bookslist"><h1class="title">読んだ本リスト</h1><divclass="books"><liv-for="book in books":key="book.index">{{book.name}}</li></div></div></template><script>importMethodsfrom"@/api/methods";exportdefault{name:"BooksList",data(){return{books:""};},created(){this.getData();},methods:{asyncgetData(){letbooks_data=awaitMethods.getBooksData();this.books=books_data.data;},},};</script><style>.bookslist{max-width:300px;margin:0auto;text-align:center;font-family:Century;}.books{display:inline-block;text-align:left;}.title{color:#5b5b5b;background:linear-gradient(transparent70%,#6088c670%);}</style>
importVuefrom"vue";importRouterfrom"vue-router";importBooksListfrom"../components/BooksList";Vue.use(Router);exportdefaultnewRouter({routes:[{path:"/",name:"BooksList",component:BooksList}]});
npm start
とコマンド入力をします。$ cd backend
$ npm start
$ cd frontend
$ npm start
今回はMongoDBに直接データを入力し、画面上に表示するアプリケーションを作成しました。
今後は画面上からデータを入力できるようにする機能や、本のカテゴリー別の表を作って表示するなどの機能も追加していきたいと思っています。
会員(友人)制のMinecraftの鯖管をやっている筆者であるが、稼働率が高くすぐ負荷に耐えられなくなり、よくサーバの再起動を命ぜられる👍
以前はPHPでAPIとWebサイトを簡易的に作り、ログイン式のWebサイトから再起動やバックアップの作成を行えるようにして鯖管をサボっていたわけですが、今回そのAPI部分をNode.js
+TypeScript
+Express
で新規機能を追加しながら作成してみたいと思います✨
このソースコードはGitHubに公開しているので、修正点やアドバイス等があれば是非プルリクをお願いします。またMITライセンスにしておりますので、どうぞご自由にお使いください!
基本的には以下のことができるAPIサーバを作成する。(予定)
importexpressfrom'express'import{pingAsync,pingOnlineAsync}from"./ping"constapp:express.Express=express()constrouter:express.Router=express.Router()app.use((req,res,next)=>{res.header("Access-Control-Allow-Origin","*")res.header("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept")next()})app.use(express.json())app.use(express.urlencoded({extended:true}))// --- Get Operational Status --------------------------------------------------router.get('/api/state',(req:express.Request,res:express.Response)=>{pingAsync().then((json)=>{res.send(json)}).catch((err)=>{res.send(err)})})// -----------------------------------------------------------------------------// --- Get Online Member -------------------------------------------------------router.get('/api/state/online',(req:express.Request,res:express.Response)=>{pingOnlineAsync().then((json)=>{res.send(json)}).catch((err)=>{res.send(err)})})// -----------------------------------------------------------------------------app.use(router)app.listen(3000,()=>{console.log('Listening on port 3000...')})
require('dotenv').config()constmc_ping=require('mc-ping-updated')exportfunctionpingAsync():Promise<any>{returnnewPromise((resolve,reject)=>{mc_ping(process.env.SERVER_URL,process.env.SERVER_PORT,function(err:any,res:any){if(err)reject('stop')elseresolve(res)})})}exportfunctionpingOnlineAsync():Promise<any>{returnnewPromise((resolve,reject)=>{mc_ping(process.env.SERVER_URL,process.env.SERVER_PORT,function(err:any,res:any){if(err)reject('stop')elseif(res.players.sample)resolve(res.players.sample)elseresolve('nobody')})})}
Minecraftサーバとの通信は、mc-ping-updatedを使用させていただきました。api/state
にGETメゾットを送ることで このようなフォーマットのJSONを返し、api/state/online
にGETメゾットを送ることで、オンラインメンバーの一覧を取得できます。
SERVER_URL='example.com'
SERVER_PORT=25565
.env
ファイルにまとめてサーバアドレスやポート番号など(随時追加)を記述してあるので、お好みの値に書き換えることで自由にお使えいただけます。
次回はサーバの起動・停止・再起動の追加と、その際のDiscordへのエラー通知とDBへのログの保存機能を搭載したいと思います。ぜひご覧ください!
https://qiita.com/notakaos/items/3bbd2293e2ff286d9f49
https://qiita.com/pochopocho13/items/79a4735031ce11a91df7
https://www.npmjs.com/package/mc-ping-updated
https://wiki.vg/Server_List_Ping