Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all 8838 articles
Browse latest View live

Spotify Web API を Node.js で弄ってみる

$
0
0

Spotify Web API を Node.js で弄ってみる

Spotify に Web API があるのを知ったので node.js で試してみた手順まとめ。

Web API Tutorial

Web API Tutorialを参考にすすめていく事にします。

Dashboard を有効にする。

Dashboardにアクセスして Spotify アカウントでログインして Dashboard を有効にする。下のような画面が表示されるはず。
スクリーンショット 2019-10-30 9.08.08.png

アプリ作成

"CREATE AN APP" を押して各 必須 項目をうめる。
Redirect URIshttp://localhost:8888/を登録する。
スクリーンショット 2019-10-30 9.11.21.png

Client ID / Client Secret を確認する

スクリーンショット 2019-10-30 9.28.50.png

認証トークンを取得する

web-api-auth-examples
Spotifyから提供されている認証サンプルのコードで認証トークンを取得する。

  1. authorization_code
git clone https://github.com/spotify/web-api-auth-examples
cd web-api-auth-examples
npm install
  1. clone 後に authorization_code/app.js の クライアントIDなどを書き換える。
    redirect_urihttp://localhost:8888
cd authorization_code
open app.js

〜
var client_id = 'CLIENT_ID'; // Your client id
var client_secret = 'CLIENT_SECRET'; // Your secret
var redirect_uri = 'REDIRECT_URI'; // Your redirect uri
〜
  1. 実行して ブラウザで localhost:8888 にアクセスする。 node app.js

スクリーンショット 2019-10-30 10.03.40.png

  1. Log in with Spotifyにアクセスして認証トークンを取得する。 スクリーンショット 2019-10-30 10.12.54.png

認証が成功すると localhost:8888codeパラーメタ付きでリダイレクトされる。
この codeパラメータの値が 認証トークン です。

Spotify Web API Node

Spotify Web API Node
node.js から Spotify Web API に アクセスするためのライブラリがあったので試してみます。

var SpotifyWebApi = require('spotify-web-api-node');

const authorizationCode = 'AQCYDgG5bNJ_...';

// credentials are optional
var spotifyApi = new SpotifyWebApi({
  clientId: '10ca96700c...',
  clientSecret: 'e8e5940c...',
  redirectUri: 'http://localhost:8888'
});

spotifyApi
  .authorizationCodeGrant(authorizationCode)
  .then(function(data) {
    console.log('Retrieved access token', data.body['access_token']);
    spotifyApi.setAccessToken(data.body['access_token']);
    return spotifyApi.searchTracks('Love');
  })
  .then(function(data) {
    console.log('I got ' + data.body.tracks.total + ' results!');

    var firstPage = data.body.tracks.items;
    console.log(
      'The tracks in the first page are.. (popularity in parentheses)'
    );

    firstPage.forEach(function(track, index) {
      console.log(index + ': ' + track.name + ' (' + track.popularity + ')');
    });
  })
  .catch(function(err) {
    console.log('Something went wrong:', err.message);
  });

実行成功すると LOVEで検索した トラック一覧が表示されます。
スクリーンショット 2019-10-30 10.22.41.png

参考

音楽系API(主に音楽配信サービス)まとめ

水曜日 #nijuni朝活

毎週 水曜日に nijuni朝活 やってます。 この Qiita も 朝活中に 作ったものです。


1行でコールバックをawaitする簡易Promisify

$
0
0

Utilrequireするほどでもないときに使うイディオム。

constbuffer=awaitnewPromise((ok,ng)=>fs.readFile(path,(err,res)=>err?ng(err):ok(res)))

こちらを見て反射的にアウトプット^^;

~Sync使えよって話ですが非同期に統一したいもので。

EC2にyumでnodejsをインストールしようとしたらできなかった話

$
0
0

はじめに

右も左も分からない状態で、AWSにRailsアプリをデプロイする過程で躓いたときの話

epel(?)レポジトリが見つからないと言われエラーになる。

リポジトリが見つからないと言われる。

実際のコード
[tatsuki@ip-10-0-0-85 ~]$ sudo yum install nodejs npm --enablerepo=epel
[sudo] tatsuki のパスワード:
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd


Error getting repository data for epel, repository not found

epelリポジトリをインストール

epelリポジトリインストールについて調べ、以下を実行。

[tatsuki@ip-10-0-0-85 ~]$ yum -y install epel-release
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
このコマンドを実行するには root である必要があります。

このコマンドを実行するには root である必要があります。と言われ
「あー、ユーザー権限?じゃないと実行できないのか」と思ったので、以下を実行。

[tatsuki@ip-10-0-0-85 ~]$ sudo yum -y install epel-release
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                    | 2.4 kB  00:00:00
パッケージ epel-release は利用できません。
エラー: 何もしません


epel-release is available in Amazon Linux Extra topic "epel"

To use, run
# sudo amazon-linux-extras install epel

Learn more at
https://aws.amazon.com/amazon-linux-2/faqs/#Amazon_Linux_Extras

また、エラー。翻訳すると
「epel-releaseはAmazon Linux Extra epel で利用可能だから、sudo amazon-linux-extras install epelこれを使うといいよ」と言われたので。以下実行。

[tatsuki@ip-10-0-0-85 ~]$ sudo amazon-linux-extras install epel
[sudo] tatsuki のパスワード:
Installing epel-release
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
リポジトリーを清掃しています: amzn2-core amzn2extra-docker amzn2extra-epel
10 個の metadata ファイルを削除しました
4 個の sqlite ファイルを削除しました
0 個の metadata ファイルを削除しました
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                    | 2.4 kB  00:00:00
amzn2extra-docker                                                             | 1.3 kB  00:00:00
amzn2extra-epel                                                               | 1.3 kB  00:00:00
(1/5): amzn2-core/2/x86_64/group_gz                                           | 2.6 kB  00:00:00
(2/5): amzn2-core/2/x86_64/updateinfo                                         | 159 kB  00:00:00
(3/5): amzn2extra-epel/2/x86_64/primary_db                                    | 1.8 kB  00:00:00
(4/5): amzn2extra-docker/2/x86_64/primary_db                                  |  56 kB  00:00:00
(5/5): amzn2-core/2/x86_64/primary_db                                         |  34 MB  00:00:00
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ epel-release.noarch 0:7-11 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

=====================================================================================================
 Package                   アーキテクチャー    バージョン         リポジトリー                  容量
=====================================================================================================
インストール中:
 epel-release              noarch              7-11               amzn2extra-epel               15 k

トランザクションの要約
=====================================================================================================
インストール  1 パッケージ

総ダウンロード容量: 15 k
インストール容量: 24 k
Is this ok [y/d/N]: y
Downloading packages:
epel-release-7-11.noarch.rpm                                                  |  15 kB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : epel-release-7-11.noarch                                             1/1
  検証中                  : epel-release-7-11.noarch                                             1/1

インストール:
  epel-release.noarch 0:7-11

完了しました!
  0  ansible2                 available    [ =2.4.2  =2.4.6  =2.8 ]
  2  httpd_modules            available    [ =1.0 ]
  3  memcached1.5             available    [ =1.5.1  =1.5.16 ]
  5  postgresql9.6            available    [ =9.6.6  =9.6.8 ]
  6  postgresql10             available    [ =10 ]
  8  redis4.0                 available    [ =4.0.5  =4.0.10 ]
  9  R3.4                     available    [ =3.4.3 ]
 10  rust1                    available    \
        [ =1.22.1  =1.26.0  =1.26.1  =1.27.2  =1.31.0 ]
 11  vim                      available    [ =8.0 ]
 13  ruby2.4                  available    [ =2.4.2  =2.4.4  =2.4.7 ]
 15  php7.2                   available    \
        [ =7.2.0  =7.2.4  =7.2.5  =7.2.8  =7.2.11  =7.2.13  =7.2.14
          =7.2.16  =7.2.17  =7.2.19  =7.2.21  =7.2.22 ]
 16  php7.1                   available    \
        [ =7.1.22  =7.1.25  =7.1.27  =7.1.28  =7.1.30  =7.1.31
          =7.1.32 ]
 17  lamp-mariadb10.2-php7.2  available    \
        [ =10.2.10_7.2.0  =10.2.10_7.2.4  =10.2.10_7.2.5
          =10.2.10_7.2.8  =10.2.10_7.2.11  =10.2.10_7.2.13
          =10.2.10_7.2.14  =10.2.10_7.2.16  =10.2.10_7.2.17
          =10.2.10_7.2.19  =10.2.10_7.2.21  =10.2.10_7.2.22 ]
 18  libreoffice              available    [ =5.0.6.2_15  =5.3.6.1 ]
 19  gimp                     available    [ =2.8.22 ]
 20  docker=latest            enabled      \
        [ =17.12.1  =18.03.1  =18.06.1 ]
 21  mate-desktop1.x          available    [ =1.19.0  =1.20.0 ]
 22  GraphicsMagick1.3        available    [ =1.3.29  =1.3.32 ]
 23  tomcat8.5                available    \
        [ =8.5.31  =8.5.32  =8.5.38  =8.5.40  =8.5.42 ]
 24  epel=latest              enabled      [ =7.11 ]
 25  testing                  available    [ =1.0 ]
 26  ecs                      available    [ =stable ]
 27  corretto8                available    \
        [ =1.8.0_192  =1.8.0_202  =1.8.0_212  =1.8.0_222  =1.8.0_232 ]
 28  firecracker              available    [ =0.11 ]
 29  golang1.11               available    \
        [ =1.11.3  =1.11.11  =1.11.13 ]
 30  squid4                   available    [ =4 ]
 31  php7.3                   available    \
        [ =7.3.2  =7.3.3  =7.3.4  =7.3.6  =7.3.8  =7.3.9 ]
 32  lustre2.10               available    [ =2.10.5 ]
 33  java-openjdk11           available    [ =11 ]
 34  lynis                    available    [ =stable ]
 35  kernel-ng                available    [ =stable ]
 36  BCC                      available    [ =0.x ]
 37  mono                     available    [ =5.x ]
 38  nginx1                   available    [ =stable ]
 39  ruby2.6                  available    [ =2.6 ]
 40  mock                     available    [ =stable ]

とりあえず、epel-releaseをインストールすることに成功!

もう一度、nodejsをインストールしてみる。

[tatsuki@ip-10-0-0-85 ~]$ sudo yum install nodejs npm --enablerepo=epel
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
189 packages excluded due to repository priority protections
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ nodejs.x86_64 1:6.17.1-1.el7 を インストール
--> 依存性の処理をしています: libuv >= 1:1.9.1 のパッケージ: 1:nodejs-6.17.1-1.el7.x86_64
--> 依存性の処理をしています: libuv.so.1()(64bit) のパッケージ: 1:nodejs-6.17.1-1.el7.x86_64
---> パッケージ npm.x86_64 1:3.10.10-1.6.17.1.1.el7 を インストール
--> トランザクションの確認を実行しています。
---> パッケージ libuv.x86_64 1:1.23.2-1.amzn2.0.2 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

=====================================================================================================
 Package           アーキテクチャー  バージョン                          リポジトリー           容量
=====================================================================================================
インストール中:
 nodejs            x86_64            1:6.17.1-1.el7                      epel                  4.7 M
 npm               x86_64            1:3.10.10-1.6.17.1.1.el7            epel                  2.5 M
依存性関連でのインストールをします:
 libuv             x86_64            1:1.23.2-1.amzn2.0.2                amzn2-core            129 k

トランザクションの要約
=====================================================================================================
インストール  2 パッケージ (+1 個の依存関係のパッケージ)

総ダウンロード容量: 7.3 M
インストール容量: 26 M
Is this ok [y/d/N]: y
Downloading packages:
(1/3): libuv-1.23.2-1.amzn2.0.2.x86_64.rpm                                    | 129 kB  00:00:00
warning: /var/cache/yum/x86_64/2/epel/packages/nodejs-6.17.1-1.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY
nodejs-6.17.1-1.el7.x86_64.rpm の公開鍵がインストールされていません
(2/3): nodejs-6.17.1-1.el7.x86_64.rpm                                         | 4.7 MB  00:00:00
(3/3): npm-3.10.10-1.6.17.1.1.el7.x86_64.rpm                                  | 2.5 MB  00:00:00
-----------------------------------------------------------------------------------------------------
合計                                                                  24 MB/s | 7.3 MB  00:00:00
file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 から鍵を取得中です。
Importing GPG key 0x352C64E5:
 Userid     : "Fedora EPEL (7) <epel@fedoraproject.org>"
 Fingerprint: 91e9 7d7c 4a5e 96f1 7f3e 888f 6a2f aea2 352c 64e5
 Package    : epel-release-7-11.noarch (@amzn2extra-epel)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
上記の処理を行います。よろしいでしょうか? [y/N]y
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : 1:libuv-1.23.2-1.amzn2.0.2.x86_64                                    1/3
  インストール中          : 1:nodejs-6.17.1-1.el7.x86_64                                         2/3
  インストール中          : 1:npm-3.10.10-1.6.17.1.1.el7.x86_64                                  3/3
  検証中                  : 1:npm-3.10.10-1.6.17.1.1.el7.x86_64                                  1/3
  検証中                  : 1:nodejs-6.17.1-1.el7.x86_64                                         2/3
  検証中                  : 1:libuv-1.23.2-1.amzn2.0.2.x86_64                                    3/3

インストール:
  nodejs.x86_64 1:6.17.1-1.el7                  npm.x86_64 1:3.10.10-1.6.17.1.1.el7

依存性関連をインストールしました:
  libuv.x86_64 1:1.23.2-1.amzn2.0.2

完了しました!

無事通りました!

Node.jsとMeCabで漢字・ひらがな・カタカナ辞書順ソート

$
0
0

Node.js, MeCabを使用した日本語の辞書順ソート用compare関数を実装しました。
漢字、ひらがな、カタカナに対応しています。

String#localeCompare()は概ね辞書順に動きますが、濁音半濁音を無視します。
これを補完し、漢字の読みにも対応しました。

コード全体はこちらにおいてあります。

https://gist.github.com/sujoyu/b93e83596e6de9142933ce7cc9cd711b

必須環境

  • Node.js
  • MeCab
$ npm install is-windows encoding-japanese --save

使い方

constComparator=require('./japanese-comparator')constlist=['b','a','2','1','+','-','-2','あがき','','赤城']// get関数は引数なしでも動作しますが、リストを渡してキャッシュを作ったほうが早くなりますconstcompare=newComparator().get(list)console.log(list.sort(compare))/*
[
  '-', '-2', '+',
  '1', '2',  'a',
  'b', '赤城', 'あがき',
  '悪'
]
*/

内部の実装

functionhiraToKana(str){returnstr.replace(/[\u3041-\u3096]/g,function(match){varchr=match.charCodeAt(0)+0x60;returnString.fromCharCode(chr);});}

ひらがなをカタカナに変換します。

constdakuMap=hiraToKana('かが きぎ くぐ けげ こご さざ しじ すず せぜ そぞ ただ ちぢ つづ てで とど はばぱ ひびぴ ふぶぷ へべぺ ほぼぽ').split(/\s/g).reduce((prev,current)=>{[...current].map(c=>{prev[c]=current})returnprev},{})

濁音半濁音の文字の順序を定義しています。

functioncompareKana(a,b){if(a[0]===undefined&&b[0]===undefined){return0}elseif(a[0]===undefined){return-1}elseif(b[0]===undefined){return1}elseif(a[0]===b[0]){returncompareKana(a.substring(1),b.substring(1))}elseif(dakuMap[a[0]]&&dakuMap[b[0]]&&dakuMap[a[0]]===dakuMap[b[0]]){returndakuMap[a[0]].indexOf(a[0])-dakuMap[a[0]].indexOf(b[0])}else{returna[0].localeCompare(b[0],'ja')}}

カタカナの文字列同士を比較します。

if(isWindows()){this.detected=Encoding.detect(exec(`echo テキストエンコーディングのテスト | mecab -Oyomi`))}...Encoding.convert(exec(command),{from:this.detected,type:'string'})

Windowsでは何も考えずにmecabコマンドを叩くと出力がShift-JISになるので変換しています。

createCache(list){list=this.preprocess(list)constyomiAll=this.kanjiToKana(list.join(this.splitter),true).split(this.splitter)console.log(yomiAll)list.forEach((str,i)=>{this.cache[str]=yomiAll[i]})}

compare関数が呼ばれるたびにmecabコマンドを叩いていると日が暮れてしまうので、
ソートする文字列リストを全結合し、一回だけmecabを叩き、再度分割、結果をキャッシュする仕組みを入れました。

以上です。

Electronで作業中に使えるアプリを作っていたら残像が残った話

$
0
0

症状

displayをnoneとした要素の影がついたままになって残像が残ってしまっていた(Macのみの症状)

dom.style.display="none";

としましたが、

スクリーンショット 2019-10-30 12.18.09.png
↓dislpay:none;
スクリーンショット 2019-10-30 12.18.16.png
残像が残っている!

これは困りましたね(困惑)

調べてみるとすぐに解決できました。

解決方法

win=newBrowserWindow({width:1000,height:880,transparent:true,//ウィンドウ背景を透過alwaysOnTop:true,//常に最前面hasShadow:false,//残像が残らないようにするframe:false,//枠の無いウィンドウwebPreferences:{nodeIntegration:true}//nodeの機能つかうよ});

WindowオブジェクトのhasShadowというプロパティがデフォルトでtrueになっているのが原因で残像が現れています。
falseにすると残像がなくなります。やったね。
調べてみると、Macのみ存在するプロパティみたいです。

インスタンスが起動したら自動的にNode.jsアプリが起動するようにする

$
0
0

Node.jsアプリの自動起動をしたい

はじめに

AWSでインスタンスを再起動するたびにアプリケーションを再起動するのが非常に面倒だったため、インスタンスが起動したら自動的にアプリケーションが起動するようにしました。

今回はPM2というプロセスマネージャーを利用してアプリの自動起動を行う方法を、作業メモを兼ねて紹介します。

PM2とは

PM2はデーモンプロセスマネージャーです。

プロセスをデーモン化しておらず、シェルを抜けたらアプリケーションが終了していた、といった経験はみなさんあるのではないでしょうか。

PM2を利用するとプロセスをデーモン化することで、アプリケーションを起動した状態に保つことができます。

そのため、Node.jsアプリケーションの本番運用などに利用されているようです。

公式サイト: PM2

導入

下記コマンドでインストールできます。

Node.jsやnpmは事前にnvmなどを利用してインストールしておきましょう。

$ npm install pm2@latest -g# or$ yarn global add pm2

下記コマンドでアプリケーションを開始できます。

$ pm2 start app.js

また、PM2は.jsファイル以外でも利用できます。
実はNode.jsアプリ以外も動かせます(

$ pm2 start bashscript.sh
$ pm2 start python-app.py --watch$ pm2 start binary-file ----port 1520

引用: PM2 QUICK START

システムの起動時にアプリケーションを開始する

PM2はスタートアップスクリプトを生成することで、マシンの再起動後もプロセスリストをそのまま保持することができます。

つまり、マシンの再起動時にスクリプトやアプリケーションを自動的に開始することができます。

注意点や詳細については公式ドキュメントに記載がありますので、こちらもご覧ください。

引用: PM2 STARTUP SCRIPT

スタートアップスクリプトの生成

スタートアップスクリプトを生成するには下記コマンドを入力します。

$ pm2 startup

上記コマンドを入力すると下記のようなメッセージが表示されます。

$ pm2 startup
[PM2] You have to run this command as root. Execute the following command:
      sudo su -c"env PATH=$PATH:/home/unitech/.nvm/versions/node/v4.3/bin pm2 startup <distribution> -u <user> --hp <home-path>

メッセージに従って、コマンドをコピーして実行してください。

現在のプロセスリストの保存

マシンの再起動時に再生成したいアプリケーションをすべて起動したら、現在のプロセスリストを保存する必要があります。

$ pm2 save

ちなみに、プロセスリストは下記コマンドで確認できます。

$ pm2 list
┌────┬───────────┬─────────┬─────────┬──────────┬────────┬──────┬──────────┬──────────┬──────────┬──────────┬──────────┐
│ id│ name      │ version │ mode    │ pid      │ uptime│ ↺    │ status   │ cpu      │ mem      │ user     │ watching │
├────┼───────────┼─────────┼─────────┼──────────┼────────┼──────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ 0  │ server    │ 1.0.0   │ fork    │ 2476     │ 1h     │ 1    │ online   │ 0.3%     │ 192.8mb  │ foobar   │ disabled │
└────┴───────────┴─────────┴─────────┴──────────┴────────┴──────┴──────────┴──────────┴──────────┴──────────┴──────────┘

以上です。

EC2インスタンスや仮想環境を再起動したら、自動的にスクリプトが実行されているはずです。

.tsファイルって実行できる?

TypeScriptでアプリケーションを作成していたので、下記コマンドを試してみたところ、エラーを吐きました。

$ pm2 start app.ts # ts-nodeが入っていないとエラー

どうやら、トランスパイル後のjsファイルを実行するか、別途ts-nodeのインストールが必要なようです。

$ pm2 install typescript ts-node
$ pm2 start app.ts # OK

PM2とts-nodeの細々としたことについては、このIssueが参考になりそう。

さいごに

今回はアプリケーションの自動起動のためにPM2を利用してみました。

systemdを利用する方法(具体例)など他にもやり方はあります。foreverもよく紹介されていましたしね。
例:Expressアプリケーション用のプロセス・マネージャー

PM2はアプリケーションを管理する機能が豊富で、もっといろいろなことができるようです。例えばログを見たり、アプリをモニタリングしたり。
私もいろいろ触ってみようと思います。

公式: PM2

Docker & Node.js & Socket.io & NGINXでよくあるエラー

$
0
0

エラー内容

タイトルの構成でアプリケーションを作っていた時に以下のエラーが出てつまずいた

socket io failed: Error during WebSocket handshake: Unexpected response code: 400

何故起きたか

WebSocket接続のハンドシェイク時に HTTP/1.1 101 (Switching Procotols)というステータスコードと Hop-by-Hopヘッダを使用してWebSocket通信への切り替えを行う仕様に Nginx v1.3.13から変更されたらしい。

Since version 1.3.13, nginx implements special mode of operation that allows setting up a tunnel between a client and proxied server if the proxied server returned a response with the code 101 (Switching Protocols), and the client asked for a protocol switch via the "Upgrade" header in a request.

解決策

Upgrade ヘッダConnection ヘッダを明示的にバックエンドに渡すようにする必要がある
以下がNGINXのdefault.confです
/にきたアクセスは nodeコンテナの3000番ポートに飛ばしています
/socket.io/も明示的に設定することでフロントで呼び出す際に /socket.io/socket.io.jsで呼び出す事が出来ます

default.conf
server {
    listen  80;
    server_name  localhost;

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Host $host;
        proxy_pass http://node:3000;
    }

    location /socket.io/ {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Host $host;
        proxy_pass http://node:3000;
    }
}

docker-compose環境で構築している場合は NGINXの設定をした際に必ずbuildし直すことを忘れずに

HTML to PDF 変換コマンド・ライブラリの比較 : 結論 headless Chrome の直接利用が最強では? ( #HTML #PDF #node #GoogleChrome )

$
0
0

環境

Mac

Web: 変換元

https://yahoo.comを変換してみる。

image
image

Chrome の headless モード

OSのGoogleChromeを直接利用する。

ヘッドレス Chrome ことはじめ
https://developers.google.com/web/updates/2017/04/headless-chrome

alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"

chrome --headless --disable-gpu --print-to-pdf https://www.yahoo.com

open output.pdf

image

完璧じゃないか!

なんかエラーは出たけども。

$ chrome --headless --disable-gpu --print-to-pdf https://www.yahoo.com
[1030/134817.172348:ERROR:xattr.cc(63)] setxattr org.chromium.crashpad.database.initialized on file /var/folders/nt/brt3bhdn50v57vqgz5t6xqc40000gn/T/: Operation not permitted (1)
[1030/134817.173787:ERROR:file_io.cc(89)] ReadExactly: expected 8, observed 0
[1030/134817.176145:ERROR:xattr.cc(63)] setxattr org.chromium.crashpad.database.initialized on file /var/folders/nt/brt3bhdn50v57vqgz5t6xqc40000gn/T/: Operation not permitted (1)
[1030/134823.138892:INFO:headless_shell.cc(620)] Written to file output.pdf.```

node chrome-headless-render-pdf

npm install -g chrome-headless-render-pdf
chrome-headless-render-pdf --url https://yahoo.com --pdf ./yahoo-chrome-headless-render.pdf && open ./yahoo-chrome-headless-render.pdf
$ chrome-headless-render-pdf --url https://yahoo.com --pdf ./yahoo-chrome-headless-render.pdf && open ./yahoo-chrome-headless-render.pdf
Using /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
Waiting for chrome to became available
Chrome port open!
Chrome port open!
Chrome port open!
Chrome port open!
Chrome port open!
Connected to HeadlessChrome/78.0.3904.70, protocol 1.3
Opening https://yahoo.com
Wait for load took 4543ms
Wait for js execution took 1785ms
Wait for animations took 105ms
Saved ./yahoo-chrome-headless-render.pdf

image

chrome を使っているはずなのに何故かヘッダが白い。

node html-pdf

サポート終了している phantomjs を使っている
URLを直接指定できないのでlocalにいちどダウンロードしてから試した
ページを解析する最中のjsエラーか何かでエラーで落ちた
別件で変換成功したケースはあるが、CSSの扱いが古かったりでレイアウトに苦労した

npm install -g html-pdf
$ html-pdf ~/Downloads/Yahoo.htm ~/yahoo.html-pdf.pdf
fs.js:114
    throw err;
    ^

Error: ENOENT: no such file or directory, open '/Users/yumainaura/Downloads/Yahoo.htm'
    at Object.openSync (fs.js:443:3)
    at Object.readFileSync (fs.js:343:35)
    at htmlpdf (/usr/local/lib/node_modules/html-pdf/bin/index.js:25:17)
    at Object.<anonymous> (/usr/local/lib/node_modules/html-pdf/bin/index.js:10:3)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)

Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2638


【Node.js+Express+PostgreSQL】async/await使ってPostgreSQLに接続

$
0
0

はじめに

本記事では、コールバックではなく、async/awaitを使ってExpressでPostgreSQLに接続する方法をまとめる。
async/await部分以外は、以下の記事を参考にしていただければ。

環境

  • Windows 10
  • Express 4.17.1
  • PostgreSQL 11.3
  • pg 7.12.1

サンプルコード

sever.js
constexpress=require("express");constapp=express();constpg=require('pg');constpool=pg.Pool({host:hoge,database:hogehoge,user:huga,port:5432,password:hugahuga});app.get("/",(req,res)=>{pool.connect(async(err,client)=>{if(err){console.log(err);}else{//同期っぽい処理try{varresult=awaitclient.query("SELECT * FROM users WHERE age = $1",[24]);console.log(result.rows);}catch(err){console.log(err.stack);}//非同期処理try{varresult=client.query("SELECT * FROM classes WHERE id = $1",[1]);console.log(result.rows);}catch(err){console.log(err.stack);}res.json({msg:"Hello, world!"});}});});

参考サイト

What's "Node.js" ?

$
0
0

よく使い方を忘れるので、必要な時にサッと読み返せるように超完結にまとめておきます。

関連記事
What's "Git" ?
What's "nvm" ?
What's "Node.js" ?
What's "npm" ?
What's "React" ?
What's "Next.js" ?

Node.jsとは

スケーラブルなネットワークアプリケーションを構築するために設計された非同期型のイベント駆動の JavaScript 環境

  • サーバーサイドJavaScript
  • 非同期
  • イベントドリブン
  • シングルスレッド

参考文献
Node.js を5分で大雑把に理解する

人気のあるNode.jsのフレームワーク

  • Express
  • Backbone.js
  • Sails
  • Meteor

CentOSにnvmインストールしたnodeが再起動時には扱えなくなる現象の解決

$
0
0

概要

普段はReact NativeでIOSアプリを開発してます
今回は、CentOS内でnvmでインストールしたnodeコマンド利用ができなくなった現象を解決した流れのメモを共有します

[vagrant@localhost ~]$ node
node: /lib64/libc.so.6: version `GLIBC_2.16' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.17' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by node)
[vagrant@localhost ~]$ 

上記のようなエラーが吐かれnodeが利用できません

解決策

nvmでインストールしたnodeをデフォルトでの利用をさせるようにします

[vagrant@localhost ~]$ which node
/usr/bin/node


[vagrant@localhost ~]$ nvm alias default v6.14.4
default -> v6.14.4
#ここで重要なのは上記のように、対象nodeバージョンの値にvをつけることです

[vagrant@localhost ~]$ which node
~/.nvm/versions/node/v6.14.4/bin/node

これで再起動してもnvmからのnode利用が行えるようになりました

Node.js(express)を用いたハッシュ化の仕方

$
0
0

はじめに

 会員登録の際に、ユーザーから送られてきたパスワードをハッシュ化する方法について解説します。
また、ログインの際にユーザーが入力したパスワードとハッシュ化されたパスワードが一致しているのか確認する必要があると思います。それについても解説します。

実装

事前準備

 まずはNodeにハッシュ化するためのモジュールをインストールします。

npm install --save bcrypt -s

パスワードをハッシュ化する

hash.js
constbcrypt=require('bcrypt');//モジュールの読み込みconstpassword="hoge";lethashed_password=bcrypt.hashSync(password,10);

以上でパスワードのハッシュ化が行えます。

ハッシュ化された値とパスワードの値の一致の確認

hash.js
bcrypt.compareSync("hoge",hashed_password)// =>ture

第一引数に確認文字列、第二引数にハッシュ化したパスワードを入れることで、真偽値が返ってきます。

参考

2019年 #HTML #PDF 変換の情勢とは? ( phantomjs -> wkhtmlpdf -> headless Chrome + #node + puppeteer )

$
0
0

https://www.paperplane.app/blog/modern-html-to-pdf-conversion-2019/

古い手法とは

PhantomJSのかわりにwkhtmltopdfが重宝されてきたけどモダンブラウザの仕組み、 HTML5やjsに対応しきれてないよーって書かれてる気がする。

The traditional approaches
Until 2017, there were two common ways to convert HTML to PDF. The first was to use wkhtmltopdf — an open source command line tool specifically designed for the task. A second alternative was PhantomJS, an open source “headless” web browser which can be controlled with JavaScript.

Although these tools have served many people extremely well, they do have some downsides. Support for the latest HTML5 and JavaScript features lags a long way behind the modern browsers we’re used to such as Chrome, Firefox or Safari.

Chrome を直接利用する

凝ったことをやろうとすると、色々大変だよって書いてるような気がする。

Using the Chrome devtools API
If you’d like to use Chrome directly yourself, you can get started by using the “print-to-pdf” command line option, but for more control over the PDF you’ll need to communicate with Chrome’s devtools API.

Puppeteer

Chrome / chromium と dev-tool を上手に使うための仕組み、 node の Puppeteer が良さげって書かれているような気がする。

Controlling Chrome with Puppeteer

You could use Puppeteer to automate a Headless Chrome browser instance in almost any way. Here we’ll just be focusing on how it can be used to create PDFs.

Google cloud function

サーバーレスで使う方法があるらしい。

Using Puppeteer via Google Cloud Functions
One interesting new option is the ability to run headless Chrome on Google Cloud’s “serverless” platform — Cloud Functions. This feature was added to Cloud Functions in August 2018 and should provide a low-cost and highly scalable way of generating PDFs. Google’s announcement post has a good walk-through that explains how to set it all up.

比較

headless Chrome がエクセレント!

image

typesettingってなんだろうな

参考

強い!

仕組み
puppeteerは、WebdriverIOのようなクロスブラウザ対応のツールとは異なり、Chrome DevTools Protocol2 を利用してNode.jsからChromeの開発者ツールへ接続して操作を行います。

puppeteerがこれらのライブラリと一線を画すのは、なんと言っても本家ChromeのDevTool開発チームが作成・メンテナンスしている、という点でしょう。

--headless時代の本命? Chrome を Node.jsから操作するライブラリ puppeteer について - Qiita

Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2642

Nuxt.jsチートシート

$
0
0

関連:
- Vue.jsチートシート(基礎編)
- Vue.jsチートシート(コンポーネントと構成編)

Vueチートシートに引き続き公式チュートリアルの抜粋です。

参照

概要

  • Nuxt.js = Vue.jsおよびそのプラグインに基づくサーバサイドフレームワーク

    • NuxtはVue.js, vue-router, vuex, Vue Server Render, Vue Metaなどを包含する
    • Vueと同じく部分的に利用することができる(Progressive Framework)
  • 公式によると以下のような機能を提供している:

    • Vue ファイルで記述できること(*.vue)
    • コードを自動的に分割すること
    • サーバーサイドレンダリング
    • 非同期データをハンドリングするパワフルなルーティング
    • 静的ファイルの配信
    • ES2015+ のトランスパイレーション
    • JS と CSS のバンドル及びミニファイ化
    • 要素(、 など)の管理
    • 開発モードにおけるホットリローディング
    • プリプロセッサ: Sass, Less, Stylus など
    • HTTP/2 push headers ready
    • モジュール構造で拡張できること
  • SSRの実現を主目的として導入されることが多いが、単純なSPAとして動作させることもできる

  • jekyllのようにVueコンポーネントから静的サイトをビルドすることもできる

  • Node.jsベースで動作する

    • AppフレームワークとしてExpressをはじめとした複数を選択できる
    • UIフレームワークも同様にBootstrap, Element UIなどを選択できる
    • テストフレームワークも同様

導入

  • npxを使ってNuxtプロジェクトを簡単に作成できる

    # npm5.2+はデフォルト$ npm install-g npx
    
    # インタラクティブに入力してプロジェクトを作成する# App/UI/テストフレームワークもここで選べる# yarn create nuxt-app <project-name> でも同じ$ npx create-nuxt-app <project-name>
    
    # 開発環境を起動$ npm run dev
    
  • 既存のプロジェクトに導入する場合はnpmパッケージとしてインストールする

    package.json
    // npm run devでnuxtが立ち上がるように設定しておく{"name":"my-app","scripts":{"dev":"nuxt"}}
    $ npm install--save nuxt
    

基礎

ディレクトリ構造

Nuxtのプロジェクトは以下のようなディレクトリ構成をとる:

pathincludesmemo
/assets/CSS(SASS), 画像, フォントファイルなど静的なファイル
/components/Vueコンポーネント
/layouts/アプリケーションレイアウト
/middleware/ミドルウェア(ページレンダリング以前に実行される処理)
/pages/ViewおよびRouterこれ以下のファイル構成をもとにしてRoutingを作成する
/plugins/Vueのinstanciateより前に実行したい処理
/static/サーバのroot直下に直接配置されるファイルfaviconやrobots.txtなど
/store/Vuexストアファイル
/nuxt.config.jsNuxtの設定

ディレクトリエイリアス

  • Nuxt Appにおいて ~あるいは @はソースが格納されるディレクトリ(srcDir) を示す
    • ~~, @@はrootDir
    • srcDirとrootDirはデフォルトでは等値

設定の分類

/nuxt.config.jsの設定は以下のようなトップレベルのキー以下に分類される:

categoryincludesmemo
buildwebpackを含むビルドオプション
css共有するCSSファイル/ライブラリの設定
devDev/Prodモード
env環境変数
generaterouting
headmeta-tagの設定
loadingローディングコンポーネントの設定
modulesNuxtモジュールの設定
modulesDirnode_modulesの所在
pluginsplugins/ 以下の設定
rootDirNuxtアプリケーションのroot
routerVue Router設定
serverサーバの設定
srcDirソースの所在
dirカスタムディレクトリの設定
transitionトランジションの設定

Routing

Nuxtはvue-routerを用いてページをルーティングする

ルーティングの自動生成

  • /pages/内のファイル・ディレクトリ構造に基づいて、自動的に設定を生成する

    たとえばこんなファイル構成だと
    pages/
        index.vue
        users/
            index.vue
    
    このようになる
    router:{routes:[{name:'index',path:'/',component:'pages/index.vue'},{name:'users',path:'/users',component:'pages/users/index.vue'},]}

Link

  • ページ間の遷移は <router-link>ではなく <nuxt-link>を使う

    <nuxt-linkto="/">Home</nuxt-link>

パラメータ

  • URLにパラメータを含める場合はファイル名にアンダースコアをつける

    pages/
        users/
            _id.vue
        posts/
            _id/
                index.vue
    
    router:{routes:[// こうするとパラメータが必須でなくなる(?){name:'users-id',path:'/users/:id?',component:'pages/users/_id.vue'},// 必須にしたい場合はディレクトリを切る{name:'posts-id',path:'/posts/:id',component:'pages/posts/_id/index.vue'},]}
  • パラメータを検証することができる

    • 検証失敗した場合、Nuxtサーバは404を返す
    • あるいはエラーがthrowされた場合は500を返す
    アンダースコアから始まる(パラメータを含む)ページの.vueファイル
    exportdefault{validate({params}){// 戻り地の真偽をもって検証の可否とするreturnparams.id>0}}

ネスト

  • ページをネストする場合は、リンクと同様に <router-view>ではなく <nuxt-child>を親コンポーネントに配置する

    pages/
        users/
            _id.vue
            index.vue
        users.vue
    
    // users.vueに <nuxt-child> を配置しておく必要があるrouter:{routes:[{path:'/users',component:'pages/users.vue',children:[{path:'',component:'pages/users/index.vue',name:'users'},{path:':id',component:'pages/users/_id.vue',name:'users-id'}]}]}

未知のパスをハンドルする

  • _.vueファイルを配置すると、その他にマッチしなかった全てをハンドルできる

    # / はindex.vue
    # /users/ はusers/
    # /foo などそれ以外は _.vue
    pages/
        _.vue
        index.vue
        users/
    

View

Appテンプレート

  • 全てのViewに共通するHTML(Appテンプレート)を定義できる

    • Appテンプレートは /<rootDir>/app.htmlとして配置する
    /app.html
    <!-- こんなふうに定義しておく(以下はNuxtのデフォルトのAppテンプレート --><!DOCTYPE html><html{{HTML_ATTRS}}><head{{HEAD_ATTRS}}>
        {{ HEAD }}
      </head><body{{BODY_ATTRS}}>
        {{ APP }}
      </body></html>

Layout

  • デフォルトのレイアウトは /layouts/default.vueである

    /layouts/default.vue
    <!-- nuxtタグにページがレンダリングされる --><template><nuxt/></template>
  • レイアウトをカスタムしたい場合は /layoutsにファイルを配置する

    /layouts/custom.vue
    <template><!-- ...カスタムされたレイアウト --><nuxt/></template>
  • カスタムレイアウトはページ側で指定することで利用できる

    exportdefault{layout:'custom'}
  • App内でエラーが発生した場合のエラーページは、レイアウトのひとつ(error.vue)として定義しカスタムできる

ページ

  • Nuxt上のページ(Vueコンポーネント)は、SSRのために追加の機能が提供されている

    page.vue
    <template><h1class="red">Hello {{name}}!</h1></template><script>exportdefault{// コンポーネントのロードの都度呼ばれる// 非同期で実行でき、戻り値はdataオブジェクトとマージされるasyncData(context){return...},// ページの描画前にstoreを初期化するfetch(){// ...},// <meta>を設定するhead(){// ...},// レイアウトを設定するlayout:'custom',// 遷移時のアニメーションを設定するloading:false,// 遷移時にスクロールを一番上に戻すかscrollToTop:true,// トランジションの設定//transition: ...,// ミドルウェアの設定//middleware: ...}</script><style>.red{color:red;}</style>

メタタグ

  • <meta>の内容はすべて nuxt.config.jsに定義できる

    • ページ単位でカスタムしたい場合はコンポーネントにheadプロパティを定義する
    nuxt.config.js
    head:{meta:[{charset:'utf-8'},],link:[{rel:'stylesheet',href:'https://fonts.googleapis.com/css?family=Roboto'}]}

非同期データ処理

asyncDataとコンテキスト

コンポーネントの asyncDataプロパティ(メソッド)は、ページのロードとは非同期的なデータの読み込みのために用いる。

  • asyncDataが呼ばれるたびに、その結果がdataにマージされる

    • サーバサイドでは、ページがリクエストされた際に一度だけ呼ばれる
    • クライアントサイドでは、ページ遷移のたびに呼ばれる
  • asyncDataは thisを使えない

    • コンポーネントがinstanciateされる前に、別のスコープで(非同期に)呼び出されるため
    • 代わりに引数の contextを介して必要なデータを取得できる
  • Promiseオブジェクトを返すほか、async/awaitを使って書くこともできる

    // Promiseexportdefault{asyncData({params}){returnaxios.get('https://...').then((res)=>{return{...}})}}// async/awaitexportdefault{asyncasyncData({params}){let{data}=awaitaxios.get('...')return{title:data.title}}}
  • Promiseによってエラーの制御もできる

    exportdefault{asyncData({params,error}){returnaxios.get('...').then((res)=>{return{...}}).catch((e)=>{error({statusCode:404,message:'Not Found'})})}}

Asset/Static

Asset

  • assets/に配置されたファイルは vue-loader, file-loaderなどwebpackの機能を利用して「アセット」として参照できる

    • アセットはvueファイルから、 ~assets/...の形式で参照できる

      <template><imgsrc="~/assets/image.png"></template>
    • file-loaderの場合、アセットファイルはサーバ上にバージョン付きのファイル名で配置される

    • url-loaderの場合、アセットファイル(画像)はURL-encodingされてHTML上にインライン展開される

Static

  • static/に配置されたファイルは Assetの機能を利用することなく、単に静的なファイルとして配置・公開される
    • faviconなどはここに置く

Plugin

  • npmパッケージをNuxtで利用したい場合、インストールするだけでそのまま利用できる

    $ npm install--save axios
    
    <template>
      ...
    </template><script>importaxiosfrom'axios'exportdefault{asyncasyncData({params}){let{data}=awaitaxios.get('...')// ...}}</script>
  • Vueのプラグインを利用したい場合、 plugins/以下に設定を追加する必要がある

    plugins/some-vue-plugin.js
    importVuefrom'vue'importSomeVuePluginfrom'some-vue-plugin'Vue.use(SomeVuePlugin)
    nuxt.config.js
    exportdefault{// ...plugins:['~/plugins/some-vue-plugin'// クライアント/サーバサイドにそれぞれ限定のプラグインはモードを指定できる{src:'~/plugins/some-client-only-plugin',mode:'client'}]// プラグインがES6などで書かれている場合はビルドの指定も必要になるbuild:{transpile:['some-vue-plugin']}}

Module

  • Module = Nuxt自体の機能拡張

    • 例:
      • @nuxtjs/axios : Nuxtとaxiosの統合
      • @nuxtjs/auth : 認証機能を提供する
  • Moduleはnpmパッケージとして公開するほか、プロジェクトローカルに独自定義することもできる

    modules/some-module.js
    exportdefaultfunctionSomeModule(options){// ...}

ビルド/デプロイ

  • NuxtはCLIを提供しており、これによってビルドやデプロイができる

    package.json
    {// ...// グローバルインストールした場合は $ nuxt で直接呼べる// ローカルインストールした状態で利用したい場合はpackage.jsonにscriptを設定する// $ npm run dev などとして利用可能"scripts":{"dev":"nuxt","build":"nuxt build","start":"nuxt start","generate":"nuxt generate","test":"jest"},}
  • Appの提供形式によって利用するコマンドが変わってくる

    • 開発環境では nuxtでサーバを起動する
    • SSRの場合は nuxt startによって本番モードでサーバを起動する
    • 静的サイトの場合は nuxt generateでページをビルドする
    • SPAの場合も同様に nuxt generateでビルドする(SPAモード指定が必要)

Typescript: X is Declared, But Never Usedの解決方法メモ

$
0
0

X is Declared, But Never Usedというエラーが出ることがある。

以下のような例だ。

exportconstonChange=(val:string,index:number)=>{index+1}// val is Declared, But Never Used

回避するには、変数の代わりに空のオブジェクトを使えば良い。

exportconstonChange=({},index:number)=>{index+1}

エラーが消えるはずだ。

この方法は可読性を高めてくれるので、気に入った。

参考
https://www.triplet.fi/blog/typescript-getting-rid-of-error-x-is-declared-but-never-used/


express がいつのまにかバージョンアップしてた

$
0
0

なので、今新しくexpress のシステム作ろうとして WEB に出回っているコードをコピペしても 全然動いてくれません。

https://expressjs.com/ja/guide/migrating-4.html

とりあえずこれを参照すればなんとかなると思います。

cradle.js (0.7.1) が動かなかった話

$
0
0

cradle使おうとしたんです。
node.jsから驚くほど簡単に使えるNoSQLサーバ Couchbase(CouchDB)を試す!

を参考に、expressのバージョンが上がってるからちょこちょこ修正しつつ、さてDB編集だと言った時にこんなエラーが。

C:\home\minori\program\js\app4\node_modules\cradle\lib\cradle.js:316
            if (! o.__lookupGetter__(attr)) {
                    ^

TypeError: o.__lookupGetter__ is not a function
    at C:\home\minori\program\js\app4\node_modules\cradle\lib\cradle.js:316:21
    at Array.forEach (<anonymous>)
    at C:\home\minori\program\js\app4\node_modules\cradle\lib\cradle.js:315:24
    at Array.forEach (<anonymous>)
    at Object.cradle.merge (C:\home\minori\program\js\app4\node_modules\cradle\lib\cradle.js:314:10)
    at C:\home\minori\program\js\app4\node_modules\cradle\lib\cradle\database\documents.js:71:35
    at Request._onResponse [as _callback] (C:\home\minori\program\js\app4\node_modules\cradle\lib\cradle.js:244:9)
    at Request.self.callback (C:\home\minori\program\js\app4\node_modules\request\request.js:185:22)
    at Request.emit (events.js:210:5)
    at Request.<anonymous> (C:\home\minori\program\js\app4\node_modules\request\request.js:1161:10)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! app4@0.0.0 start: `node ./bin/www`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the app4@0.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Minori\AppData\Roaming\npm-cache\_logs\2019-10-30T18_04_15_163Z-debug.log

パっと見 cradle の中で起こってるエラーなので該当箇所を見てみるとこんな記述が。

cradle.js
cradle.merge=function(target){varobjs=Array.prototype.slice.call(arguments,1);objs.forEach(function(o){Object.keys(o).forEach(function(attr){if(o.__lookupGetter__(attr)){target[attr]=o[attr];}});});returntarget;};

ソースの精査をしていいないので cradle.mergeが何やってるかなんとなくしかわからないのですが、DB呼び出す度に2回ぐらい呼ばれてて最後の最後にどうも普通のJsonオブジェクトか何かになる模様。

なのでこう書き換えて動きました。

cradle.js
cradle.merge=function(target){varobjs=Array.prototype.slice.call(arguments,1);objs.forEach(function(o){Object.keys(o).forEach(function(attr){if(o.__lookupGetter__&&!o.__lookupGetter__(attr)){target[attr]=o[attr];}});});returntarget;};

プルリク送っとこうかな……でもこれでバグが取れきったかどうかわからないしな……

n でバージョン管理

Headless #GoogleChrome + #node puppeteer + #docker で Webページのスクリーンショットを作成する例

$
0
0

Dockerfile

docker で利用するには一筋縄でいくわけではないよー的なことが書かれている気がする

Getting headless Chrome up and running in Docker can be tricky. The bundled Chromium that Puppeteer installs is missing the necessary shared library dependencies.

# https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.mdFROM node:10-slim# Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others)# Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer# installs, work.RUN wget -q-O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& sh -c'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'\
&& apt-get update \
&& apt-get install-y google-chrome-unstable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf \
--no-install-recommends\
&&rm-rf /var/lib/apt/lists/*# If running Docker >= 1.13.0 use docker run's --init arg to reap zombie processes, otherwise# uncomment the following lines to have `dumb-init` as PID 1# ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 /usr/local/bin/dumb-init# RUN chmod +x /usr/local/bin/dumb-init# ENTRYPOINT ["dumb-init", "--"]# Uncomment to skip the chromium download when installing puppeteer. If you do,# you'll need to launch puppeteer with:#     browser.launch({executablePath: 'google-chrome-unstable'})# ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true# Install puppeteer so it's available in the container.RUN npm i puppeteer \
# Add user so we don't need --no-sandbox.# same layer as npm install to keep re-chowned files from using up several hundred MBs more space&& groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
    && mkdir -p /home/pptruser/Downloads \
    && chown -R pptruser:pptruser /home/pptruser \
    && chown -R pptruser:pptruser /node_modules

# Add Diff from https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.mdRUN npm i puppeteer-core

# Run everything after as non-privileged user.USER pptruserWORKDIR /home/pptruserCMD ["google-chrome-unstable"]

docker run

docker hub にアップしているのでそのまま使っていただいても

docker run -it --name=puppeter-docker yumainaura/puppeter-docker  bash

node

  • node で js スクリプトを実行して example.com のスクリーンショットを作成する
  • こちらもほぼ公式のままだが --no-sandox を指定しないとエラーで落ちる様子
const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch({args: ['--no-sandbox']});
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});
  await browser.close();
})();

e.g

pptruser@73b979b895b0:~$ node
> const puppeteer = require('puppeteer');
undefined
> (async () => {
...   const browser = await puppeteer.launch({args: ['--no-sandbox']});
...   const page = await browser.newPage();
...   await page.goto('https://example.com');
...   await page.screenshot({path: 'example.png'});
...   await browser.close();
... })();
Promise {
  <pending>,
  domain:
   Domain {
     domain: null,
     _events:
      [Object: null prototype] {
        removeListener: [Function: updateExceptionCapture],
        newListener: [Function: updateExceptionCapture],
        error: [Function: debugDomainError] },
     _eventsCount: 3,
     _maxListeners: undefined,
     members: [],
     [Symbol(kWeak)]: WeakReference {} } }

スクリーンショット

pngで保存されている

pptruser@73b979b895b0:~$ ls
Downloads  example.png

local = host でスクリーンショットを確認する

docker container から画像をコピーして mac で開いてみる

$ docker cp puppeter-docker:/home/pptruser/example.png ./ 
$ open example.png

これだよ

成功

image

Yahoo.com の変換例

  • 非同期処理なので少し時間がかかった
  • 画像が切れているが、変換時にサイズ調整とかすればええ塩梅になるはず

image

ところでスターバックスの木の椅子で、カイロで席取りをしている人がいたのですが

スクリーンショットしておきました。

image

Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2645

Deno Style Guideを読み解く

$
0
0

Deno - JavaScriptランタイムのネクストスタンダードか

Deno、いいですよねー。セキュアだし、TypeScript推しだし、標準モジュール志向だし。

v1.0のリリースについて

未だv0.2ということで本番環境での利用は推奨されていません。
作者のライアン曰く2019年中にv1.0リリースすると公言しているそうですが、コミュニティの中では恐らく来年中頃くらいまではかかるのでは?という予想です。
まぁ正式リリース前のこのタイミングで各種情報をキャッチアップしておけばJS界隈で遅れを取ることはなさそうですね。

Deno Style Guideとは

その名の通りDenoをコーディングする際の現時点でのベストプラクティスです。
リンクはコチラ

denoStyleGuide.png

それでは早速1つ1つ読み解いていきましょう

Use TypeScript

はい、いきなり言い切ってますねw
TypeScriptありきのDenoってことを肝に命じておきましょう💦

Use the term "module" instead of "library" or "package"

確かにライブラリとかパッケージとか言葉の定義が曖昧になるときがありますよね。
とくにフロントやバックエンドを横断して様々な言語で開発しているとき。
ということでDenoでは「モジュール」と徹底しましょう。

Do not use the filename index.ts nor index.js

index...というファイル名を使うなということですね。
Webサイトだとデフォルトのエントリポイントのindex.htmlに付随したindex.tsとうファイル名にするのが一般的ですが、Denoの場合はmodule名.tsとすることで紛らわしさや動作の先入観をなくすという目的があるようです。

Within deno_std, do not depend on external code

標準モジュールはDenoのベースとなるため実装するプログラム内のなにものにも依存させてはならぬということですかね。

Within deno_std, minimize dependencies; do not make circular imports.

こちらは循環インポートはするなということですが、標準モジュールを汚さないでねってことですかね。

For consistency, use underscores, not dashes in filenames.

同感です。ハイフン使うのはhtmlのattributeくらいですかね。ファイル名はアンダースコアで統一しましょう。

Format code using prettier.

具体的には、

  • コードは80文字でラップ
  • 2スペースのインデントを使用
  • キャメルケースを使用
    • 変数、関数、フィールド名はlowerCamelCase
    • class, interface名はUpperCamelCase

まぁこのあたりは他の言語と変わりないですかね。

Exported functions: max 2 args, put the rest into an options object.

引数はobjectやinterfaceに切り出しておくことでメンテナブルにしましょうってことですね。

TODO comments should include an issue or the author's github username in parentheses.

こちらはわたくしも日々Denoに限らず実践していますが、TODOコメントにはそれに関連するissue番号なり、Redmine等のチケット駆動であればチケット番号を記載しておくと
着手まで日が空いてしまったり別の開発者が対応することになった場合に便利ですね。

Copyright headers

コピーライトは漏れなく記載しましょうねってことですね。Denoは MITBSDApache licensedのに許容しているそうです。

Top level functions should not use arrow syntax

アロー構文はクロージャーでプライベートメソッドを模倣する場合に関数スコープ内でのみ使いましょうってことですね。
個人的にも基本は function...で書いたほうがコードを読んだときに直感的に関数と視認できるのでそうしてます。

Meta-programming is discouraged. Including the use of Proxy.

ですよね!メタプログラミング、わたくしは生理的に受け付けないですね💦

If a filename starts with underscore, do not link to it: _foo.ts

内部モジュールのファイル名prefixにはアンダースコアを付けて明示化しましょうってやつですね。

Use JSDoc to document exported machinery

こちらはリーダブルなコードとするための一般的なお約束ですね。

Each module should come with tests

はい、テストは必ず行いましょう。その際にファイル名は modulename_test.tsとするという規則で。

Unit Tests should be explicit

テスト関数には ...TestFunctionと明示しておきましょうってことですね。

まとめ

はい、ということで読み終わりました。ふうー疲れたw
まぁ特別トリッキーなものはなく、他の言語でも言われている一般的な決まりが多かったように思います。

それでは予習はバッチリということで、これからDenoコーディングを楽しみたいと思います。
何か出来ましたらまた共有させていただきます。

以上です。

Viewing all 8838 articles
Browse latest View live