- 投稿日:2020-07-13T22:23:01+09:00
簡単レシート印刷 receiptline を導入してみた
街のお店で iPad のレジをよく見かけるようになりましたね。
一般的にタブレット POS と呼ばれています。おかげで?レシートプリンターがネットオークションやフリマアプリに出品されるようになりました。
業務用ってワクワクしませんか?個人でも利用できる業務用スーパーも人気がありますよね。ネットには Raspberry Pi でレシートプリンターの制御にチャレンジしたブログもあって楽しそうです。
レシートプリンターの落札を試みつつ、レシート印刷にトライしてみようと思います。レシートプリンターで印刷するには
レシートプリンターで印刷する手段はいろいろあるので、独断で整理してみました。
- デスクトップアプリ向け
- Windows プリンタードライバー
- Linux や Mac の CUPS ドライバー
- スマートフォン・タブレットアプリ向け
- iOS 用 SDK ライブラリ
- Android 用 SDK ライブラリ
- コンソールとエスケープシーケンスが好きな人向け
- StarPRNT コマンド
- ESC/POS コマンド
- 玄人向け
- OPOS (Win32, .NET)
- JavaPOS
- オープンソース
- GitHub に多数
- Python, JavaScript, Java, PHP, Ruby, Go, ...
メーカーさんが提供しているものは、ドキュメントもサポートも充実しています。
ここで記事にする意味があるのは、オープンソース一択と言えると思います。多種多様なオープンソースの中に、日本発のプロジェクトもありました。
https://github.com/receiptline/receiptlineJavaScript / Node.js の変換ライブラリです。
テキストを入力すると、SVG 画像やレシートプリンターのコマンドを出力します。
アスキーアート的に文字を並べると清書してくれるイメージですね。おまけにプレビューできる開発ツールが付いています。
プレビューに対応する印刷手段は意外に少ないかもしれません。
これならレシートプリンターを持っていなくても試すことができます。receiptline をセットアップ
開発する人
npm でインストール・実行して、
http://localhost:10080/
を開きます。
https://www.npmjs.com/package/receiptline$ npm i receiptline $ cd node_modules/receiptline $ npm start一般の人
GitHub からダウンロード・展開して、
designer/index.html
を開きます。
https://github.com/receiptline/receiptlinehello, world!
開発ツールを使ってみましょう。
左側の黒い編集エリアに文字を入力してみます。
編集エリアの文字の大きさは Zoom スライダーで適当に調節。ReceiptLinehello, world!入力すると、右側の白いレシート用紙にプレビューが表示されます。
文字列はレシート用紙の中央に配置されました。レシート用紙の幅は Width スライダーで変更することができます。
単位はインチ・ミリではなく文字数 (桁数) となっています。財布の中に入っていたレシートの多くは、1 行あたり漢字 16 文字 (32 桁) でした。
ところが、文字数が違うレシートや、幅広のレシートも・・・混沌のレシート世界
昔の明和電機社長ブログから引用。
“レシートの印刷の大混乱ぶり、どうにかならんものか・・・”
https://www.maywadenki.com/blog/2011/05/17/post-bbf8/これは今でも変わっていないと思います。
果たして混沌のレシート世界に秩序をもたらすことができるのか?次回は文字装飾を試してみようと思います。
- 投稿日:2020-07-13T20:08:40+09:00
JavaScriptで+++は許されない+ ++は許される
+++,---とは
これらは一つの演算子ではなく、それぞれ+と++または++と+の組み合わせ、それの-番です。
わかりやすくいえば一つずつ増やして足していくということですね。var a=0; var b=13; console.log(a+ ++b) // 14 a--; console.log(a++ +b) // 13
これがスペースを開けずに+++にするとエラーが出ます。もちろん理由は解析できないからです。
ちなみに++-や--+は使えます。なんか書いてたらごっちゃになってました。私が書きたかったことはこちらになります。
var b=13; console.log(1+++b) // Uncaught SyntaxError: Invalid left-hand side expression in postfix operation console.log(b+++1) // 14 console.log(1+ ++b) // 15 console.log(++b+1) // 15つまり、+++は++と+という解釈になるということですね。なのでインクリメントをする際はスペースを開けるか変数を左に持っていく必要があります。
- 投稿日:2020-07-13T10:54:27+09:00
Node.jsとMongoDBを連携
今回はnode.jsとMongoDBの連携方法について簡単に解説していきます。
MongoDBの特徴
まず初めにMongoDBの特徴について解説します。
MongoDBの特徴として,以下のようなものが挙げられます。
(1)スキーマレスであるドキュメント指向データベースであること
・データはスキーマレスなドキュメントで格納され,任意のフィールドを好きなときに追加できる
・KVSでは苦手なValueを検索の条件としたり,ソート・集計を実現できる(2)スケーラビリティに関する機能を標準機能として備えていること
・レプリケーション機能,オートフェールオーバー機能を備えている
・レンジパーティション機能,オートバランシング機能を備えている(3)RDBと比較してRead/Writeの性能が高い
・トランザクション・リレーションを制限した結果,KVSに近いパフォーマンスを出せる(4)開発のしやすさ
・どのような環境でもパフォーマンスが出るように,ネイティブソケットプロトコルを使用したドライバを主要なプログラミング言語で開発元が提供している
・RESTインターフェイスを標準で備えており,Webで広く普及しているJSONを使用してデータ送受信ができる以上のような特徴があります。
MongoDBのインストール
それでは実際にMongoDBをインストールしていきましょう。
今回はHomebrewを使ってインストールしていきます。
Homebrewがインストールされていない場合はインストールしておきましょう。以下のコマンドでインストールしていきます。
brew tap mongodb/brew
続いて、以下のコマンドでソフトウェアのパッケージをインストールします。
brew install mongodb-community
これでインストールは完了です。
実際に起動できるか確認してみましょう。
起動
brew services start mongodb-community
停止
brew services stop mongodb-community
これで問題なければOKです。
詳しくはこちらの公式を確認しましょう。
Node.jsとの接続
それでは実際にNode.jsからMongoDBに接続してみましょう。
まず、Sample/index.jsを作成してください。次に、以下のコマンドでpackage.jsonを作成します。
npm init
次に、以下のコマンドでMongoDBのパッケージをインストールします。
npm install mongodb --save
これで準備はOKです。
それでは、コードを書いていきます。index.jsvar MongoClinet = require('mongodb').MongoClient;//MongoClient取得 var url = 'mongodb://localhost:27017/'; //今回はlocalhostなのでこの表記 MongoClinet.connect(url, (error, client) => { var db = client.db('sample');//どのDBを使用するか client.close();//操作を行った後に切断 });異常が最低限必要なコードになります。
これでMongoDBの中のsampleというDBを操作する準備ができました。しかしこのままでは接続できているのかよくわかりません。
なので実際に何か指示を書いてみましょう。index.jsvar MongoClinet = require('mongodb').MongoClient; var url = 'mongodb://localhost:27017/'; MongoClinet.connect(url, (error, client) => { var db = client.db('sample'); db.createCollection('test', (error, collection) => { client.close(); }); });上記のコードはsampleというDBに対してtestというcollectionを作成するという指示です。
それでは実行してみましょう。
node index.js
※実行前にローカル上でMongoDBが起動していることを確認しましょう
(起動していないと"TypeError: Cannot read property 'db' of undefined"というエラーが出ます)次に実行結果の確認をします。
ターミナル上でMongoDBに接続し、確認します。
[手順]
1.mongo
でMongoに接続
2.show dbs
でDBのリストを確認
3.use sample
でsampleというDBにアクセス
4.show collection
で中身を確認"test"というcollectionが作成されていれば成功です。
これでNode.jsをMongoDBの接続し、collectionの作成に成功しました。
- 投稿日:2020-07-13T10:28:01+09:00
Expressのルーティング
これは何?
この記事はNode.jsのフレームワークのexpressのルーティングの自分がよく使う物を公式から抜粋したメモです。
基本的なルーティング
app.METHOD(PATH, HANDLER)例:
app.get('/', (req, res) => { res.send('Hello World!'); }); app.post('/', (req, res) => { res.send('Got a POST request'); }); app.put('/target', (req, res) => { res.send('Got a PUT request at /target'); }); app.delete('/target', (req, res) => { res.send('Got a DELETE request at /target'); });ルート・パス
正規表現などで引っかかっているパスにアクセスすることができる。(リクエストを実行できるエンドポイントを定義することができる)
例:
app.get('/random.text', (req, res) => { res.send('random.text') }) app.get('/ab*cd', (req, res) => { res.send('ab*cd') }) app.get(/a/, (req, res) => { res.send('(Regular expression) path with "a"') }) app.get(/.*fly$/, (req, res) => { res.send('(Regular expression) /.*fly$/') })ルート・パラメータ
パスからパラメータ("key":"value")を取得ができる
app.get('/key1/:value1/key2/:value2', (req, res) => { res.send(req.params) })例:
ルート・パス: /flights/:from-:to リクエストURL: http://localhost:3000/flights/LAX-SFO req.params: { "from": "LAX", "to": "SFO" }参考資料:
- 投稿日:2020-07-13T09:28:39+09:00
そろそろlockファイルを理解するための最初のページ【composer.lock/package-lock.json】
.lockファイルって邪魔だよね。って思っている人いたら校舎裏来てください。優しく解説します。
こんにちは! @ykhirao です。最近ジョインさせていただいた案件で
composer.lock
のバージョンが本番が一番新しくて、ローカルが一番古い素敵な状況を発見しました本番環境でSSHして
composer update
かけたんだなあーー。そっかーーー、バグ起きたらどないすんねん、。。。。。。というのが私の感想で、実際にnpmパッケージを使ってバグを再現しながら
ゆっくり解説していこうと思います。どうぞ最後までよろしくお願いします。!!!このQiitaを呼んで得ること
- あーー、ほんとだ。バグが入る可能性があるんだ!
- lockファイルはちゃんとコミットするね!
というお気持ちになれると思います。
このQiitaで解説しないこと
- 詳しい依存関係の解消法
- packageの公開の仕方
- むずかしいはなし
です!
さて時系列を見てみよう!
こんな事故が起こる可能性がありますよって話をします。
時系列 OSSのmypackage.js ローカル 本番サーバー 1日目 v1.0.0公開 動いている 動いている 2日目 ローカルでmypackage.jsをinstall
動作確認OK、明後日本番に適応させる3日目 v1.0.1公開 バグあり 4日目 本番サーバーで新しいコードを反映、install。本番が動かなくなってしまった。ぴえん
もちろんソースコードはローカルと同じだし、ローカルで動いていたのになんで…?5日目 v1.0.2公開 バグ修正された 6日目 v1.0.2を適応ローカル確認OK
今度はlockファイルを本番にアップロードする予定!7日目 package-lock.jsonを使ってinstallする!今度は動いた! npmでパッケージを作りながら説明する
OSSっぽい動作をするpackageフォルダと、ローカル環境と本番環境っぽいフォルダを作る。
yk@yk ~ % cd qiita yk@yk qiita % mkdir package yk@yk qiita % mkdir local yk@yk qiita % mkdir production yk@yk qiita % ll total 0 drwxr-xr-x 5 yk staff 160 7 11 00:34 . drwxr-xr-x+ 83 yk staff 2656 7 11 00:33 .. drwxr-xr-x 2 yk staff 64 7 11 00:34 local drwxr-xr-x 2 yk staff 64 7 11 00:34 package drwxr-xr-x 2 yk staff 64 7 11 00:34 productionyk@yk qiita % cd package yk@yk package % npm init -y Wrote to /Users/yk/qiita/package/package.json: { "name": "package", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" } yk@yk package % vim package.json yk@yk package % vim index.js yk@yk package % npm publish --access=public npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN package@1.0.0 No description npm WARN package@1.0.0 No repository field. up to date in 0.429s found 0 vulnerabilities /Users/yk/.nodebrew/node/v13.8.0/lib/node_modules/package -> /Users/yk/qiita/package yk@yk package % cat index.js const text = "sample" module.exports = text;index.jsにただただ "sample" という文字列を返す動作を記述して、パッケージとして認識させる。
@y_hirao/mypackage
というパッケージをnpmに公開した。localフォルダでいろいろゴリゴリしてみる。
yk@yk local % npm init -y Wrote to /Users/yk/qiita/local/package.json: { "name": "local", "version": "1.0.0", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "@y_hirao/mypackage": "^1.0.0" }, "devDependencies": {}, "description": "" } yk@yk local % cat index.js const text = require("@y_hirao/mypackage"); console.log(text) yk@yk local % node index.js samplesampleという文字列が返却されました。!!!!!!!!!
このときpackage.jsonを見ると
^
キャレット指定なのでバージョンアップは1.系
は守られるけど残りはすべてアップデートされます。"dependencies": { "@y_hirao/mypackage": "^1.0.0" },さてパッケージの方を更新します。
v1.0.2
にしましょう!yk@yk package % cat package.json { "name": "@y_hirao/mypackage", "version": "1.0.2", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" } yk@yk package % cat index.js const text = "sample2" throw 'エラーを出したい気分'; module.exports = text; yk@yk package % npm publishこのパッケージをそのまま使うとthrowされます。
さてローカルでinstallしてみましょう!
yk@yk local % npm install npm WARN local@1.0.0 No description npm WARN local@1.0.0 No repository field. audited 1 package in 0.411s found 0 vulnerabilities yk@ykあれ、エラーが起きませんね。
これは 一度ダウンロードしたパッケージはlockファイルというものでバージョン指定されているので、新しく勝手にバージョンがあがったりしないのです。さてローカルから本番環境に package.json と index.js をコピーしてnpm installして動かしてみましょう!
yk@yk production % cp ../local/package.json package.json yk@yk production % cp ../local/index.js index.js yk@yk production % npm i npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN local@1.0.0 No description npm WARN local@1.0.0 No repository field. added 1 package and audited 1 package in 2.811s found 0 vulnerabilities yk@yk production % node index.js /Users/yk/qiita/production/node_modules/@y_hirao/mypackage/index.js:2 throw 'エラーを出したい気分'; ^ エラーを出したい気分 (Use `node --trace-uncaught ...` to show where the exception was thrown)さて、、、本番環境でinstallを走らせるとエラーがおきました。。。。
npm install
したときにpackage-lock.json
がないとpackage.json
を使って^1.0.0
が指定されているので1.系で一番新しいもの
つまり今回だとバグが混入しているv1.0.2
がインストールされたことになります。lockファイルを見てみましょう。
yk@yk production % cat package-lock.json { "name": "local", "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@y_hirao/mypackage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@y_hirao/mypackage/-/mypackage-1.0.2.tgz", "integrity": "sha512-W2RoQsC1FVnHxximVJMovEvfl/3WNI95EjGxPbMlmyuDZ+0SImS76dOII/0AiP4cVVjXZUbFzaLs9h6l8TrrFQ==" } } }まさしく
v1.0.2
が指定されていますね!localだともちろん最初にnpm install
したときに最新だった@y_hirao/mypackage
のv1.0.0
が使われています。yk@yk local % cat package-lock.json { "name": "local", "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@y_hirao/mypackage": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@y_hirao/mypackage/-/mypackage-1.0.0.tgz", "integrity": "sha512-auQ5grIpWd0IRkMR3rn6xRjIhGZqBu/Q/g1lDkS5AWakAysrZ3iQAIRngbgBGBAFlPZxQ/LCVYdAW+3VLxeSEw==" } } }更にインストールされているフォルダを確認しても
yk@yk production % cat node_modules/@y_hirao/mypackage/index.js const text = "sample2" throw 'エラーを出したい気分'; module.exports = text; yk@yk production %どう見てもエラーが起きそうです。
package-lock.jsonをlocalからコピーしてきましょう。
yk@yk production % cp ../local/package-lock.json package-lock.json yk@yk production % npm i npm WARN local@1.0.0 No description npm WARN local@1.0.0 No repository field. updated 1 package and audited 1 package in 0.45s found 0 vulnerabilities yk@yk production % cat node_modules/@y_hirao/mypackage/index.js const text = "sample" module.exports = text; yk@yk production % node index.js sample yk@yk production %lockファイルを持ってきてインストールするだけで、エラーが起きなくなりました!
まとめ
本番環境で lockファイルごと更新する
composer update
とかlockファイルの存在しない状態でのnpm install
とか、そんなことはやめましょう。ってことを主張したいです!!!!!ローカルでしっかり確認してlockファイルを作り、それを本番にアップロードして、lockファイルの状態で依存パッケージをインストールしちゃってください。。
インストールする時期によって最新のバージョンが使われるので、もしそのバージョンにバグがあるのなら本番死んじゃいますよ。。
終わりに
新しい会社に入って色々根本的に変えたいところがあるので、最近はdevopsの領域をごりごり触らせていただいてます。環境構築、開発フローの策定とかもろもろやらせてもらっているのでかなり楽しいです
読んでいただきありがとうございました。lockファイル入門したい方、事故りそうな不安があるかたは同僚と一緒に「弊社のパッケージ依存関係の運用どうする…?」と一度話し合ってみてください。
ありがとうございました。
.
- 投稿日:2020-07-13T09:06:10+09:00
[JavaScript] express() で "express is not a function" ついでに TS の "export =" と "import = require()"
Expressを読み込んだ際に
express is not a function
と出たので原因と解決策を共有します。
あとついでにexport =
とimport = require()
についてです。環境
import側はJavaScript、トランスパイルとかは一切なし。
node: v14.1.0package.json{ ... "type": "module", "dependencies": { "express": "^4.17.1", ... }, ... }再現VTR
index.jsimport * as express from "express"; const app = express();node ./index.js実行すると
const app = express(); ^ TypeError: express is not a functionエラー発生。
因みに、USAGEに従っていた。 1@types/express/index.d.ts/* =================== USAGE =================== import * as express from "express"; var app = express(); =============================================== */
原因
CommonJSとESModulesdでの返却される値に違いがあった。
import * as express from "express"; console.log(typeof express); // => objectconst express = require("express"); console.log(typeof express); // => functionimportdefault: [Function: createApplication] { ... }require[Function: createApplication] { ... }つまり、返却値がdefault exportとなっているため参照エラーを起こしていた。
対応策
こうする。
import express from "express"; const app = express();または、
import * as express from "express"; const app = express.default();そもそもトランスパイルもせずに使うなら、CommonJSモジュールならCommonJSのインポート (
const express = require("express");
) で読み込むのがベターっていうツッコミは覚悟してます!以降おまけ
export =
名前は「エクスポート代入」。
Expressの型定義ファイルを覗くとこうなっている。@types/express/index.d.ts... /** * Creates an Express application. The express() function is a top-level function exported by the express module. */ declare function e(): core.Express; ... export = e;CommonJSとAMDを考慮せずにエクスポートできる便利機能。
言い換えればこれは、CommonJSまたはAMDのモジュールだよ。っていう印。
import = require()
名前は「インポート代入」。
エクスポート代入(export =
)を使用してエクスポートされたモジュールをインポートする際に使われていたらしい。
今ではあえて使う理由はなさそう。インポート代入、インポート代入の使用例
// export側 function hoge() { return 'hoge'; } const fuga = 'fuga'; export = { hoge, fuga }; // import側 import hogefuga = require('./export'); console.log(hogefuga); // => { hoge: [Function: hoge], fuga: 'fuga' }感想
地味に時間を溶かしたため記事にしてやったぜ。。
何かご指摘等あればコメントいただけると幸いです。参考