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

初心者がReact+FirebaseでWebアプリを作成する⑤ ~React Routerを使ったら認証機能の間違いに気付いた~

$
0
0

④の続きです。

一枚板では画面もコードも見づらいので、
React Routerでページ遷移できるようにします。

↓React Router公式ページのquickstartを参考にしました。
https://reacttraining.com/react-router/web/guides/quick-start

ひとまずコマンドでreact-router-domをインストール。

npm install react-router-dom

インストールが完了したらimportします。

App.js
import{BrowserRouterasRouter,Switch,Route,Link}from"react-router-dom";

あとは公式ページのBasicにならってページ遷移してみました。

App.js
//色々省略<div><Router><AppBarposition="static"><Toolbar><Linkto="/"><Typographyvariant="h6"style={{color:'white',padding:'5px'}}>マイページ</Typography></Link><Linkto="/form"><Typographyvariant="h6"style={{color:'white',padding:'5px'}}>投稿フォーム</Typography></Link><Linkto="/show"><Typographyvariant="h6"style={{color:'white',padding:'5px'}}>投稿一覧</Typography></Link><Buttonvariant="contained"color="secondary"onClick={this.logOut}style={{color:'white',padding:'10px'}}>ログアウト</Button></Toolbar>
</AppBar>
<Switch><Routeexactpath="/"><Mypage/></Route>
<Routepath="/form"><Form/></Route><Routepath="/show"><Show/></Route>
</Switch>
</Router>
</div>

でこんなページができました。
リアクトルーター ショウ.png
ちゃんとshowのページへ移動できるようになりました。
しかしひとつ問題が発生しました。

本来、認証機能を経てログインし、ログアウトを押せば認証画面に戻るというページにしたかったのですが、ログアウトした後もhttp:localhost:3000/〇〇〇のURLを入力すればダイレクトにページに入れてしまいました。
リアクトルーター 誤り.png

原因を探ったらこれはログイン、ログアウトを自分で作成したstateで管理しようとしたためでした。↓今までのコード

App.js
//これでは正式にログインとログアウトができないcomponentDidMount(){firebase.auth().onAuthStateChanged(user=>{this.setState({isLogin:true,});});}logOut(){this.setState({isLogin:false,});}render(){if(this.state.isLogin){/}

これでは正しいログイン、ログアウトができていない様子。isLoginではなくuserを値としてsetし、firebase関数できちんとログアウトすべく、コードを訂正しました。

App.js
classAppextendsReact.Component{constructor(props){super(props);this.state={user:null,}this.logOut=this.logOut.bind(this);}componentDidMount(){firebase.auth().onAuthStateChanged(user=>{this.setState({user:user,});});}logOut(){firebase.auth().signOut();}render(){letsuccessfulUser;if(this.state.user){/}

これでURLに直接入ろうとしても、認証画面が表示されます。

リアクトルーター ショウ ブロック.png

とりあえず今回の全体のコードはこんな感じです。

App.js
importReactfrom'react';import'./App.css';importfirebasefrom"firebase/app";import"firebase/auth";import"firebase/firestore";importAppBarfrom'@material-ui/core/AppBar';importButtonfrom'@material-ui/core/Button';importToolbarfrom'@material-ui/core/Toolbar';importTypographyfrom'@material-ui/core/Typography';import{BrowserRouterasRouter,Switch,Route,Link}from"react-router-dom";importFormfrom'./Form';importShowfrom'./Show';importMypagefrom'./Mypage';importAuthenticationfrom'./Authentication';classAppextendsReact.Component{constructor(props){super(props);this.state={name:'',address:'',image:'',user:null,}this.logOut=this.logOut.bind(this);}componentDidMount(){firebase.auth().onAuthStateChanged(user=>{this.setState({user:user,});});}logOut(){firebase.auth().signOut();}render(){letsuccessfulUser;if(this.state.user){successfulUser=(<div><Router><AppBarposition="static"><Toolbar><Linkto="/"><Typographyvariant="h6"style={{color:'white',padding:'5px'}}>マイページ</Typography></Link><Linkto="/form"><Typographyvariant="h6"style={{color:'white',padding:'5px'}}>投稿フォーム</Typography></Link><Linkto="/show"><Typographyvariant="h6"style={{color:'white',padding:'5px'}}>投稿一覧</Typography></Link><Buttonvariant="contained"color="secondary"onClick={this.logOut}style={{color:'white',padding:'10px'}}>ログアウト</Button></Toolbar>
</AppBar>
<Switch><Routeexactpath="/"><Mypage/></Route>
<Routepath="/form"><Form/></Route><Routepath="/show"><Show/></Route>
</Switch>
</Router>
</div>
);}else{successfulUser=(<Authentication/>);}return(<div>{successfulUser}</div>     );}}exportdefaultApp;
Authetication.js
importReactfrom'react';importfirebasefrom"firebase/app";importStyledFirebaseAuthfrom'react-firebaseui/StyledFirebaseAuth';constuiConfig={signInFlow:'popup',signInSuccessUrl:"/",signInOptions:[firebase.auth.GoogleAuthProvider.PROVIDER_ID,firebase.auth.EmailAuthProvider.PROVIDER_ID,],}constAuthentication=(props)=>{return(<div><p>Pleasesign-in:</p>
<StyledFirebaseAuthuiConfig={uiConfig}firebaseAuth={firebase.auth()}/>
</div>
);}exportdefaultAuthentication;
Show.js
importReactfrom'react';import'./App.css';import"firebase/auth";import"firebase/firestore";constShow=(props)=>{return(<h1>Hello</h1>
);}exportdefaultShow;

MypageとFormとShowの中身はなんでも良しです。

また誤りがあれば、都度訂正していきます。


renovate-config レポジトリを作成して renovate の設定を共通化する

$
0
0

はじめに

NPM パッケージの更新管理といえば renovate か dependabot かの二択な近頃。dependabot はクリティカルなセキュリティイシューだけ管理したら良いものに、renovate は全部クリーンにしておきたいものに適用している人も多いかと思います。

そのシチュエーションにおいて困ってくるのが renovate の柔軟な設定を以下に楽にまとめて管理するか。大量のパッケージを管理している場合、renovate設定を一つ変えるために全部書き換えていくのはそれなりに手間のかかる作業になってきます。

例えば、 renovate からの PR に特定のラベルをつけたい、パッケージのメンテナが変わったからデフォルトのレビュー assignee を変更したい……などのたびに、20や30のレポジトリの設定を手動でやるのはあまり良いやり方とは言えません。

そんなときは、 renovate の設定をレポジトリに切り出して共通化しておくと便利です。

renovate の設定共通化について

renovate には、 tsconfig.json や jest.config.js や .eslintrc などの NPM ベースのエコシステムの設定ファイルと同じように、 extends が存在します。

renovate をとりあえず導入するとデフォルトで作られる renovate.json でも、 extends が利用されていますね。

{"extends":["config:base"]}

この設定、他の設定ファイルの感覚でいると yarn addして設定して……という手順を踏まないといけないように見えて少し煩雑に映るのですが、実は renovate.json は、自身の dependencies にいない設定をフェッチしてくるように作られています。

フェッチのルールは公式サイトに書かれていますが、特に頻出する設定は以下でしょうか。

  • abc: renovate-config-abcパッケージの default設定を取得
  • @abc: @abc/renovate-configパッケージの default設定を取得
  • abc:xyz: renovate-config-abcパッケージの xyz設定を取得
  • @abc:xyz: @abc/renovate-configパッケージの xyz設定を取得

つまりはデフォルトで出てくる config:baseは、 renovate-config-configの base 設定を取得してきているという意味です。

つまりは、適当なパッケージを作成してやったあと、ここを書き換えるだけで、 deps の更新なしに、一つのパッケージの publish 状況に応じて連携する全てのレポジトリの renovate 設定を書き換えることができるようになります。

実際にレポジトリを作成して呼び出す

適当に名前空間を持った renovate-config 用のレポジトリを作成します。
私の場合は https://github.com/elevenback/renovate-configを作成し、 @elevenback/renovate-configとしました。

多くの場合、個人や組織用の renovate 設定となるはずですので、 renovate-config-xxxよりは @xxx/renovate-configのほうが行儀が良いかなと思います。

作った後は package.json 内に renovate-configというプロパティを追加、更にその下に defaultを用意し、普段のように記述するだけです。例えば renovate のデフォルト設定を引き継ぐだけの場合、以下のような設定になります。

package.json
{"name":"@name/renovate-config","version""0.0.1","renovate-config":{"default":{"extends":["config:base"]}}}

これでパッケージ自体は作成完了。npm publishしてやると設定は公開されます。

公開されたら、次は利用する側の設定に移ります。今回は default を利用してやるだけなので、 renovate.jsonに以下のように記述するだけで OK です。

renovate.json
{"extends":["@name"]//私の場合だと"@elevenback"}

先述の通り、 @abc@abc/renovate-config:defaultに対応していることを覚えておいてください。
@abc/renovate-configでも @abc/renovate-config:defaultでもなければ、 @abc/defaultでもありません。ただの @abcで OK です。

これの設定が終わってしまえば、あとは renovate が動き出すまで放置で OK です。

お疲れさまでした。

CI による設定の自動テストを行う

ついでに、せっかく設定を記述したなら CI 環境も整えておくと便利です。renovate は、公式に renovate-config-validator というツールを提供しているので、これを共通化したレポジトリに導入しておきましょう。

renovate-config-validator は、renovate パッケージに付随してきます。NPM あるいは Yarn でインストールしてしまいます。

$ yarn add -D renovate

どのみち renovate の設定で Jest なりの出番はないはずなので、npm testの枠をもらってしまいましょう。

package.json
{//..."scripts":{"test":"renovate-config-validator"}//...}

この状態で、間違った設定で実行すると、きちんと exit code 1 を出力してくれます。試しに午前13時という現実的でない時間を設定するとこうなります。

スクリーンショット 2019-11-09 14.22.35.png

ここまでできたら CI 環境を整えて終わりです。最近だと GitHub Actions がファイルを配置するだけで手軽で高速なので、ここでは GitHub Actions のサンプルコードを置いておきます。

.github/workflows/test.ymlに以下を配置すると OK です。

test.yml
name:Renovate Validateon:[push]jobs:build:runs-on:ubuntu-lateststrategy:matrix:node-version:[10.x,12.x]steps:-uses:actions/checkout@v1-name:Use Node.js ${{ matrix.node-version }}uses:actions/setup-node@v1with:node-version:${{ matrix.node-version }}-name:yarn install and testrun:|yarn yarn test

あとは GitHub に載せてしまうと、自動でテストが走るようになってくれます。

スクリーンショット 2019-11-09 14.25.24.png

おわりに

renovate の設定を共通化すると、レポジトリの環境に依存せず管理できたり、 CI を回す手間が省けたりと、非常に多くのメリットがあります。

一方で、実際に共通化してみると Organization の renovate 設定はまだ共通化しやすくても、fork される頻度が比較的多いレポジトリまで共通化することは個人的にまだ抵抗があります。

どのみち私が関係することは無いとはいえ、fork先にまで assignee の設定が私になっている config が生まれるのはあまり気持ちの良いものではないかなと思ったり。結果として、現状共通化先は最低限の設定のみになっていたりします。

個人用設定と Organization 設定を分けてみたり、default 以外にも複数の config を利用し始めてみたり。私自身共通化をはじめたところなので、何か学びがあれば随時共有しようと思います。

AWS Lambdaのアプリケーション作成を使ってCI/CDパイプラインを一気に構築

$
0
0

Source-Build-Deploy

AWS Lambdaのアプリケーション作成とは

AWS Lambdaのアプリケーション作成機能を利用してLambda関数を作成すると、Lambda関数自体の他に

  • Lambda関数のソースコード等を管理するGitリポジトリとしてCodeCommit

  • CodeCommitのmasterブランチの更新を契機にLambda関数へのデプロイを行うCodePipeline

等々、CI/CDパイプライン実現のためのAWSリソースが同時に作成されます。

Lambda関数自体は手軽に作ったものの、次のステップとしてCI/CI環境を構築するのは腰が重く、ソースの更新はマネジメントコンソール上で実施している・・・といったケースを改善するアプローチとして、このようなCI/CD環境をセットで構築する機能がリリースされたそうです。

Lambdaのマネジメントコンソール画面では、これらAWSリソースをアプリケーションという単位で取り扱います。

(実際には、CloudFormation(以下、CFn)によって作成されており、CFnの画面からも作成されたスタックが確認できます)

なお、利用可能なランタイムは現時点ではNode.js 10.xに限定されており、GoやPython等は使えません。

実際に使ってみる

本記事では、このアプリケーション作成機能を使い、Lambda関数とCI/CDパイプラインを構築します。

そしてLambda関数に対して、簡単な機能(今回はオウム返しLINE Botとします)を、CI/CDパイプラインを通じてデプロイしてみます。

アプリケーションの作成へ進む

マネジメントコンソールのLambdaの画面から、アプリケーションの作成を押します。

Lambda画面

サンプルアプリケーションを選択するか、一から作る

すると、いくつかのサンプルアプリケーションが表示されます。

サンプルアプリケーションの選択画面

例えば、一番左上のServerless API Backendの場合、API Gateway + Lambda * 3 + Dynamo DBで構成されるサンプルアプリケーションとなります。

今回は、Lambda + API Gatewayのシンプルな構成を作成したかったので、一番右下にある一から作成を選択しました。

一から作成

アプリケーションの設定

続いて、アプリケーションの設定を行います。

今回は、LineBotを作成しようと思うので、アプリケーション名はnodejs-linebotにします。

ランタイムは、Node.js 10.xしか選択できないので、これを選択します。

アプリケーションの詳細と関数の設定

また、ソース管理を行うGitリポジトリをCodeCommitとGitHubから選択します。

今回はシンプルにAWSで完結可能となるよう、GitHubではなくCodeCommitを選択しました。

リポジトリ名入力後、最後にアクセス権限に関するチェックボックスにチェックを入れて、作成を押します。

Lambdaアプリケーション作成のための操作としては、たったこれだけです。

アプリケーションの作成開始

作成を押した後は、作成中のアプリケーション画面へ遷移します。

裏では、CFnにより各リソースが作成されています。

作成完了まで数分かかるので、その間はEric Johnsonさんの解説動画を見るなどして完了を待ちましょう。

アプリケーションの作成完了

CFnによる各リソースの作成が完了すると、Lambdaアプリケーション画面の下の方に作成されたAWSリソースが表示されます。

Lambdaアプリケーションでは、リソースとインフラストラクチャという2つのカテゴリに分けてAWSリソースが作成されています。

一方、CFnの画面を見ると、2つのスタックが作成されています。

  • 前述のリソースは、Lambdaアプリケーション名そのままのnodejs-linebotスタック

  • 前述のインフラストラクチャは、もうひとつのerverlessrepo-nodejs-linebot-toolchainスタック

によって作成されたものとなります。

Lambda関数を確認する

Lambda関数も画面から確認してみます。

ディレクトリ、ファイル構成は以下の通りとなっています。

サンプルのJavaScriptのhello-from-lambda.jsのほか、CodeBuildに必要なbuildspec.ymlなどが作られていることがわかります。

.
├── LICENSE
├── README.md
├── __tests__
│   └── unit
│       └── handlers
│           └── hello-from-lambda.test.js
├── buildspec.yml
├── package.json
├── src
│   └── handlers
│       └── hello-from-lambda.js
└── template.yml

Lambda関数名については、

  • nodejs-linebot-helloFromLambdaFunction-...

といった具合に、サンプルソースのhello-from-lambda.jsを引きずった名前になりました。

CodePipelineを通してデプロイする

では、このLambda関数にLINE Botの機能をデプロイしてみます。

LINE Botを動かすための準備

LINE Botを動かすための準備を先に行います。

デプロイそのものとは関係が無いので、折りたたみセクション化しておきます。

API Gatewayの作成 〜 LINEチャネルの作成 〜 Lambda関数の環境変数設定

API Gatewayの作成

Lamda関数の画面からトリガーの作成を押し、以下の通りAPI Gatewayを作成します。

LINEチャネルの作成

LINEチャネルの作成方法の詳細は本記事では割愛しますので、以下記事、サイトなどを参考にしてください。

その際、先ほど作成したAPI Gatewayのエンドポイントを、LINEチャネルのWebhook URLに設定してください。

Lambda関数への環境変数の設定

LINEチャネルの基本設定画面で表示されているアクセストークンとChannel SecretをそれぞれLamdaの環境変数ACCESS_TOKEN, CHANNEL_SECRETに設定します。

折りたたみセクションここまで

CodeCommitのリポジトリをローカルにgit cloneする

今回、CodeCommitにはSSHで接続して、git cloneすることにします。

SSH接続のための準備は以下を参照してください。こちらもデプロイそのものとは関係無いので、折りたたみセクション化しておきます。

git cloneするまでのSSH接続の準備

SSH接続の準備を行う

SSHの公開鍵、秘密鍵を作成します。

$ cd ~/.ssh
$ ssh-keygen -t rsa -b 2048 -f code-commit-key -m pem

作成された公開鍵をIAMユーザーのAWS CodeCommitのSSHキーに対してアップロードします。

SSHのconfigファイルを編集します。

$ vi ~/.ssh/config
Host git-codecommit.*.amazonaws.com
  User APxxxxxxxxxxxxxxxxxx
  IdentityFile ~/.ssh/code-commit-key

折りたたみセクションここまで

git cloneする

ソースコードを編集するため、CodeCommitのリポジトリをローカルにgit cloneします。

$ cd (ローカルでソース管理するディレクトリ)
$ git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/nodejs-linebot

ローカルで必要なライブラリをインストールしてソースを編集する

Line BotのSDKをインストールし、オウム返しを行うindex.jsを作成します。

$cd nodejs-linebot
$ npm install @line/bot-sdk
nodejs-linebot/index.js
constcrypto=require('crypto');constline=require('@line/bot-sdk');constclient=newline.Client({channelAccessToken:process.env.ACCESS_TOKEN,channelSecret:process.env.CHANNEL_SECRET,});exports.handler=function(event,context,callback){// 署名の検証constsignature=crypto.createHmac('sha256',process.env.CHANNEL_SECRET).update(event.body).digest('base64');if(signature!==event.headers['X-Line-Signature']){callback(null,{statusCode:404,body:'{"Error": "Invalid Signature"}'},);return;}// オウム返しconstbody=JSON.parse(event.body);client.replyMessage(body.events[0].replyToken,{type:'text',text:body.events[0].message.text,},);};

CodeCommitにpushしてCI/CDパイプラインを開始する

$ git add .$ git commit -m"feature/Line Bot"$ git push

CodePipelineの画面を確認すると、CodeCommitの更新、CodeBuildによるビルドが順次完了していくことが確認できます。

さらに、しばらく待つとデプロイも完了しました。

Lambda関数を確認する

Lambda関数を見ると、index.jsを含むファイルがデプロイされていることが確認できます。

ハンドラをindex.handlerに変更して、保存を押します。

Lambda関数を確認する

LINE Botの動作確認を行う

LINE Botにメッセージを送ります。無事、オウム返しでメッセージが返ってきました!

LINE Botの動作確認を行う

最後に

非常に簡単にLambda関数とセットでCI/CDパイプラインが構築できてしまいました。

今回は取り扱いませんでしたが、GitHubでソースは管理し、CircleCI経由でCodePipelineに連携してデプロイする、といったパイプラインも構築できるかと思います。

今後、Node.js以外にも対応してくれることを期待したいと思います。

補足:Lambdaアプリケーションを削除するには

さて、このLambdaアプリケーションを削除する場合はどうするかというと、少しクセがあります。

マネジメントコンソールのLambdaアプリケーション画面から、該当のアプリケーションを選択、削除すればCFnのように関連する全てのAWSリソースを削除してくれる・・・というわけではありません。

Lambdaアプリケーション画面

削除を選択すると、以下のダイアログが表示されます。

Lambdaアプリケーションを削除

これによると、以下の手順でAWSリソースを削除する必要があります。

  1. アプリケーションスタックを削除する
  2. デプロイパッケージを保存しているS3バケットを削除する
  3. 1の削除完了後にツールチェーンスタックを削除する(先に3を実施すると1を実施できなくなる)

アプリケーションスタックというのは、今回の記事で言うと、CFnの画面に表示されていたnodejs-linebotスタックのことで、ツールチェーンスタックはもうひとつのerverlessrepo-nodejs-linebot-toolchainスタックのことになります。

アプリケーションの削除については、このような制約事項があるので注意してください。

参考

dbpediaの研究 その29

$
0
0

概要

dbpediaが難解なので、手出してみる。
node.jsで、取得してみた。

サンプルコード

process.stdin.resume();
process.stdin.setEncoding('utf8');

var http = require('http');
const querystring = require('querystring');

const HOST = 'ja.dbpedia.org';
const PATH = '/sparql';
let postData = {
    'query': 'SELECT DISTINCT * WHERE { dbpedia-ja:デ・トマソ dbpedia-owl:abstract ?abstract .}'
};
let postDataStr = querystring.stringify(postData);
let options = {
    host: HOST,
    port: 80,
    path: PATH,
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': postDataStr.length
    }
};
let req = http.request(options, (res) => {
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    console.log(chunk);
  });
});
req.on('error', (e) => {
  console.log('problem with request: ' + e.message);
});
req.write(postDataStr);
req.end();


成果物

https://paiza.io/projects/5UX0bQUGTI0Ao7rD9wEyPA

以上。

「たった30秒でREST APIのモックが作れ」なかった話

$
0
0

こんにちは、wattak777です。

必要に迫られREST APIを受け付けられるダミーサーバを作ることになりまして、出来るだけ手抜きで効率よく構築する手段はないものか、と構築しようとして手抜きの目論見がバレたのか少々ハマった話を展開しておきます。

当初LinuxをDockerかVirtualBoxに入れてやるか、と考えていたのですが、手持ちのPCがWindows 10だったためそれも使わずに出来ないものか、と色々探して出てきたのがこれ(google先生は本当に便利ですね)。

JSON ServerでRestAPIのモックを作成した話

手持ちのPCがWindows 10が入っていたので、ここに書いてあるように、Node.jsをインストールし、npmでjson-serverを入れ、

db.json
{"API_test":{"param1":"Apple","param2":"Orange"}}
route.json
{"/api/test/mock/v1/API_test":"/API_test"}

これらを組み、

C:\work\Dummy_Rest> json-server db.json --routes route.json -p 12345

とすることで別途DOSプロンプトより

C:\test> curl http://localhost:12345/API_test

コールすると無事取れたのですが、問題はここから。
本来はLAN上の別のPCから取ってくる仕組みが欲しかったので、このページに書いてあったserver.jsをくみ上げ、

server.js
constjsonServer=require('json-server');constserver=jsonServer.create();constrouter=jsonServer.router('db.json');constmiddlewares=jsonServer.defaults();server.use(jsonServer.rewriter({"/api/test/mock/v1/API_test":"/API_test"}))server.use(middlewares);server.use(router);server.listen(12345,'192.168.1.1',()=>{console.log('Dummy REST API is running.');});

とやっていざ実行。

C:\work\Dummy_Rest> node server.js
module.js:472
    throw err;
    ^

Error: Cannot find module 'json-server'
    at Function.Module._resolveFilename (module.js:440:15)
    at Function.Module._load (module.js:388:25)
    at Module.require (module.js:468:17)
        :(以下略)

ん?あれ?
で、色々調べてたら、コレがヒントに。

Cannot find module 'json-server' #454

要はnpmで取ってきたjson-serverのパスがNODE_PATHに当たっていなかったってことか。
ってことで、改めて環境変数を取ることに。

C:\work\Dummy_Rest> npm root -g
C:\Users\wattak\AppData\Roaming\npm\node_modules
C:\work\Dummy_Rest> set NODE_PATH=C:\Users\wattak\AppData\Roaming\npm\node_modules

その後 nodeコマンドによる global.module.pathsで上記設定されたパスが入っていることを確認すると。。。

C:\work\Dummy_Rest> node server.js
Dummy REST API is running.

と、無事起動しましたとさ。

もちろん、node.exeに対してのファイアウォール設定は大丈夫ですよね?
これがないと、他のPCからC:\ClientPC> curl http://192.168.1.1:12345/API_testとやってもつながらないのでお気をつけアレ。

Node-REDのfunctionノードでjsライブラリをrequireする方法(備忘録)

$
0
0

概要

 Node-REDのfunctionノードで、jsライブラリ(node-module)を読み込んで使いたい場面が出てきました。

functionノードで直接”require”できないので苦戦し、なんとか利用できたので備忘録として残します。

方法

1. ターミナルを開き利用したいライブラリをnpmでインストール

このとき、Node-REDのシステムファイルがある「.node-red」にインストールします。
 

cd ~./.node-red
npm install インストールしたいライブラリ名

例えば、fs-extraを読み込みたい場合は次のコマンドです。

npm install fs-extra

2. settings.jsを編集

例)fs-extraモジュールを読み込む場合

settings.js
functionGlobalContext:{fs:require('fs-extra'),// <--追記   // os:require('os'),// jfive:require("johnny-five"),// j5board:require("johnny-five").Board({repl:false})},

3. functionノードに読み込み

functionノードの記述例

functionノード
varfs=newglobal.get(`fs`);returnmsg;

Macでパッケージ版Node.jsのアンインストール

$
0
0

概要

Mac OS Mojaveでパッケージ版Node.jsを。

環境

  • Mac OS Mojave 10.14.6
  • Node.js v4.5.0 (どんだけ古いねん!)

状況

  1. 色々なサイトで書かれている下記ではNo such file or directoryエラー

    lsbom -f -l -s -pf /var/db/receipts/org.nodejs.node.pkg.bom \
    | while read i; do
    sudo rm /usr/local/${i}
    done
    

手順

npm uninstall -g npm
sudo rm -rf /usr/local/lib/node_modules
sudo rm -rf ls /usr/local/include/node
sudo rm /usr/local/bin/node
sudo rm /usr/local/share/man/man1/node.1 
sudo rm /usr/local/lib/dtrace/node.d 
sudo rm -rf /usr/local/share/doc/node/
sudo rm /usr/local/share/systemtap/tapset/node.stp 

参考

https://stackoverflow.com/questions/9044788/how-do-i-uninstall-nodejs-installed-from-pkg-mac-os-x?noredirect=1&lq=1

Node.js (3)ウェブサーバー連携

$
0
0

ウェブサーバー作る

先ずはhttp要求とport設定を書き込む、そして、node.jsのウェブサーバー機能を組み立てる。

app.js
varhttp=require('http');http.createServer(function(request,response){//requestとresponseにつてデータ転送文ここに書く...}).listen(8080)

テータ転送の基本の概念はブラウザからウェブサーバーにrequest請求を届く、request請求の中身はパケットですから、いろいろな転送データをここに入れる、反対の方向はresponse請求と言われる、response請求はウェブサーバーからブラウザにデータパケットを届いてブラウザの上にデータを表示する。

螢幕快照 2019-11-10 10.17.05.png

次はrequestとreponse文を試す、先ずはrequestの情報を表示して、node.jsサーバーはreponseの内容をブラウザで示す。

app.js
varhttp=require('http');http.createServer(function(request,response){console.log(request.url);//urlの情報//writeHead関数の引数は一つ目はHTTP状態番号、二つ目は転送データ条件のオブジェクトresponse.writeHead(200,{"Content-Type":"text/plain"});//200:ok data-type:plainresponse.write('hello!!');//表示する文字response.end();//請求終わる}).listen(8080);

urlはホームページ、favicon.icoはブラウザiconの情報。

terminal
$node app.js
/
/favicon.ico

螢幕快照 2019-11-10 10.58.23.png

他の例も試す。

app.js
varhttp=require('http');http.createServer(function(request,response){console.log(request.method);//HTTPのメソッド//writeHead関数の引数は一つ目はHTTP状態番号、二つ目は転送データ条件のオブジェクトresponse.writeHead(200,{"Content-Type":"html"});//200:ok data-type:htmlresponse.write('<h2>apple!!</h2>');response.end();//請求終わる}).listen(8080);
terminal
$node app.js
GET
GET

螢幕快照 2019-11-10 14.33.13.png


#AWS ElasticBeanStalk + Amazon Linux + #node + puppteer + headless Chrome で HTML to PDF 変換・スクリーンショット撮影をする。日本語対応。

$
0
0

まとめ

  • Chrome のバイナリをインストールする
  • node API の puppeteer をインストールする
  • Chrome バイナリのパスを指定して node の変換スクリプトを実行する

以上

環境

nodejs プラットフォーム の Web環境で試す

image

ssh 接続する

eb ssh <ENV-name>

node install

なぜか入っていないのでインストールする。

curl -sL https://rpm.nodesource.com/setup_10.x | sudo bash -
sudo yum install -y nodejs

参考 https://linuxize.com/post/how-to-install-node-js-on-centos-7/

puppeteer

npm でインストールする
puppeteer は chrome 本体を操作するための node の API

echo '{}' > /home/ec2-user/package.json
npm install puppeteer

Chrome 本体のインストール

npm install puppeteer とか npm install puppeteer-core でうまく chrome がインストールできないのでこちらを試す

curl https://intoli.com/install-google-chrome.sh | bash

中身は愚直にシンプルな shell script

chrome が インストールされているのを確認する

which google-chrome-stable
/usr/bin/google-chrome-stable

変換用の node script を設置・実行する

executablePath に google-chrome-stable のパスを指定する

vim convert.js

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({executablePath: '/usr/bin/google-chrome-stable'});
  const page = await browser.newPage();

  await page.goto('https://yahoo.co.jp', {waitUntil: 'networkidle2'});
  await page.pdf({path: 'yahoo.co.jp.pdf', width: '15in', height: '11in'});
  await page.screenshot({path: 'yahoo.co.jp.png'});

  await browser.close();
})();

変換を実行する

node convert-pdf.js

ローカルにダウンロードして中身を見る

scp -i /Users/yumainaura/.ssh/pup.pem ec2-user@XXX.XXX.XXX.XXX://home/ec2-user/yahoo.co.jp.pdf ~/tmp
scp -i /Users/yumainaura/.ssh/pup.pem ec2-user@XXX.XXX.XXX.XXX://home/ec2-user/yahoo.co.jp.png ~/tmp

open ~/tmp/yahoo.co.jp.pdf
open ~/tmp/yahoo.co.jp.png

PDF変換の例

yahoo.co.jp.pdf

image

スクリーンショット撮影の例

image

*1 Chrome バイナリインストールスクリプトの中身

$ curl -s https://intoli.com/install-google-chrome.sh                                                                                 [~/tmp]
#! /bin/bash


# Copyright 2017-present: Intoli, LLC
# Source: https://intoli.com/blog/installing-google-chrome-on-centos/
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.


# What this script does is explained in detail in a blog post located at:
# https://intoli.com/blog/installing-google-chrome-on-centos/
# If you're trying to figure out how things work, then you should visit that!


# Require that this runs as root.
[ "$UID" -eq 0 ] || exec sudo "$0" "$@"


# Define some global variables.
working_directory="/tmp/google-chrome-installation"
repo_file="/etc/yum.repos.d/google-chrome.repo"


# Work in our working directory.
echo "Working in ${working_directory}"
mkdir -p ${working_directory}
rm -rf ${working_directory}/*
pushd ${working_directory}


# Add the official Google Chrome Centos 7 repo.
echo "Configuring the Google Chrome repo in ${repo_file}"
echo "[google-chrome]" > $repo_file
echo "name=google-chrome" >> $repo_file
echo "baseurl=http://dl.google.com/linux/chrome/rpm/stable/\$basearch" >> $repo_file
echo "enabled=1" >> $repo_file
echo "gpgcheck=1" >> $repo_file
echo "gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub" >> $repo_file


# Install the Google Chrome signing key.
yum install -y wget
wget https://dl.google.com/linux/linux_signing_key.pub
rpm --import linux_signing_key.pub


# A helper to make sure that Chrome is linked correctly
function installation_status() {
    google-chrome-stable --version > /dev/null 2>&1
    [ $? -eq 0 ]
}


# Try it the old fashioned way, should work on RHEL 7.X.
echo "Attempting a direction installation with yum."
yum install -y google-chrome-stable
if [ $? -eq 0 ]
then
    if installation_status; then
        # Print out the success message.
        echo "Successfully installed Google Chrome!"
        rm -rf ${working_directory}
        popd > /dev/null
        exit 0
    fi
fi


# Uninstall any existing/partially installed versions.
yum --setopt=tsflags=noscripts -y remove google-chrome-stable


# Install yumdownloader/repoquery and download the latest RPM.
echo "Downloading the Google Chrome RPM file."
yum install -y yum-utils
# There have been issues in the past with the Chrome repository, so we fall back to downloading
# the latest RPM directly if the package isn't available there. For further details:
# https://productforums.google.com/forum/#!topic/chrome/xNtfk_wAUC4;context-place=forum/chrome
yumdownloader google-chrome-stable || \
    wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
rpm_file=$(echo *.rpm)
echo "Downloaded ${rpm_file}"


# Install the RPM in a broken state.
rpm -ih --nodeps ${rpm_file}
rm ${rpm_file}


# Install font dependencies, see: https://bugs.chromium.org/p/chromium/issues/detail?id=782161
echo "Installing the required font dependencies."
yum install -y \
    fontconfig \
    fontpackages-filesystem \
    ipa-gothic-fonts \
    xorg-x11-fonts-100dpi \
    xorg-x11-fonts-75dpi \
    xorg-x11-fonts-misc \
    xorg-x11-fonts-Type1 \
    xorg-x11-utils


# Helper function to install packages in the chroot by name (as an argument).
function install_package() {
    # We'll leave the RPMs around to avoid redownloading things.
    if [ -f "$1.rpm" ]; then
        return 0
    fi

    # Find the URL for the package.
    url=$(repoquery --repofrompath=centos7,http://mirror.centos.org/centos/7/os/`arch` \
        --repoid=centos7 -q --qf="%{location}" "$1" | \
        sed s/x86_64.rpm$/`arch`.rpm/ | \
        sed s/i686.rpm$/`arch`.rpm/g | \
        sort -u
    )

    # Download the RPM.
    wget "${url}" -O "$1.rpm"

    # Extract it.
    echo "Extracting $1..."
    rpm2cpio $1.rpm | cpio -idmv > /dev/null 2>&1
}


# Install glibc/ld-linux from CentOS 7.
install_package glibc


# Make the library directory and copy over glibc/ld-linux.
lib_directory=/opt/google/chrome/lib
mkdir -p $lib_directory
cp ./lib/* $lib_directory/ 2> /dev/null
cp ./lib64/* $lib_directory/ 2> /dev/null


# Install `mount` and its mandatory dependencies from CentOS 7.
for package in "glibc" "util-linux" "libmount" "libblkid" "libuuid" "libselinux" "pcre"; do
    install_package "${package}"
done


# Create an `ldd.sh` script to mimic the behavior of `ldd` within the namespace (without bash, etc. dependencies).
echo '#!/bin/bash' > ldd.sh
echo '' >> ldd.sh
echo '# Usage: ldd.sh LIBRARY_PATH EXECUTABLE' >> ldd.sh
echo 'mount --make-rprivate /' >> ldd.sh
echo 'unshare -m bash -c "`tail -n +7 $0`" "$0" "$@"' >> ldd.sh
echo 'exit $?' >> ldd.sh
echo '' >> ldd.sh
echo 'LD=$({ ls -1 ${1}/ld-linux* | head -n1 ; } 2> /dev/null)' >> ldd.sh
echo 'mount --make-private -o remount /' >> ldd.sh
echo 'mount --bind ${1} $(dirname "$({ ls -1 /lib/ld-linux* /lib64/ld-linux* | head -n1 ; } 2> /dev/null)")' >> ldd.sh
echo 'for directory in lib lib64 usr/lib usr/lib64; do' >> ldd.sh
echo '    PATH=./:./bin:./usr/bin LD_LIBRARY_PATH=${1}:./lib64:./usr/lib64:./lib:./usr/lib mount --bind ${1} /${directory} 2> /dev/null' >> ldd.sh
echo 'done' >> ldd.sh
echo 'echo -n "$(LD_TRACE_LOADED_OBJECTS=1 LD_LIBRARY_PATH="${1}" "${LD}" "${2}")"' >> ldd.sh
chmod a+x ldd.sh


# Takes the executable as an argument and recursively installs all missing dependencies.
function install_missing_dependencies() {
    executable="${1}"
    # Loop through and install missing dependencies.
    while true
    do
        finished=true
        # Loop through each of the missing libraries for this round.
        while read -r line
        do
            # Parse the various library listing formats.
            if [[ $line == *"/"* ]]; then
                # Extract the filename when a path is present (e.g. /lib64/).
                file=`echo $line | sed 's>.*/\([^/:]*\):.*>\1>'`
            else
                # Extract the filename for missing libraries without a path.
                file=`echo $line | awk '{print $1;}'`
            fi

            if [ -z $file ]; then
                continue
            fi

            # We'll require an empty round before completing.
            finished=false

            echo "Finding dependency for ${file}"

            # Find the package name for this library.
            package=$(repoquery --repofrompath=centos7,http://mirror.centos.org/centos/7/os/`arch` \
                --repoid=centos7 -q --qf="%{name}" --whatprovides "$file" | head -n1)

            install_package "${package}"

            # Copy it over to our library directory.
            find . | grep /${file} | xargs -n1 -I{} cp {} ${lib_directory}/
        done <<< "$(./ldd.sh "${lib_directory}" "${executable}" 2>&1 | grep -e "no version information" -e "not found")"

        # Break once no new files have been copied in a loop.
        if [ "$finished" = true ]; then
            break
        fi
    done
}


# Install the missing dependencies for Chrome.
install_missing_dependencies /opt/google/chrome/chrome


if ! installation_status; then
    # Time for the big guns, we'll try to patch the executables to use our lib directory.
    yum install -y gcc gcc-c++ make autoconf automake
    echo "Linking issues were encountered, attempting to patch the `chrome` executable."
    wget https://github.com/NixOS/patchelf/archive/0.9.tar.gz -O 0.9.tar.gz
    tar zxf 0.9.tar.gz
    pushd patchelf-0.9
    ./bootstrap.sh
    ./configure
    make
    LD="$({ ls -1 ${lib_directory}/ld-linux* | head -n1 ; } 2> /dev/null)"
    ./src/patchelf --set-interpreter "${LD}" --set-rpath "${lib_directory}" /opt/google/chrome/chrome
    ./src/patchelf --set-interpreter "${LD}" --set-rpath "${lib_directory}" /opt/google/chrome/chrome-sandbox
    sed -i 's/\(.*exec cat.*\)/LD_LIBRARY_PATH="" \1/g' /opt/google/chrome/google-chrome
    popd > /dev/null
    echo "Attempted experimental patching of Chrome to use a relocated glibc version."
fi

# Clean up the directory stack.
rm -rf ${working_directory}
popd > /dev/null

# Print out the success status message and exit.
version="$(google-chrome-stable --version)"
if [ $? -eq 0 ]; then
    echo "Successfully installed google-chrome-stable, ${version}."
    exit 0
else
    echo "Installation has failed."
    echo "Please email contact@intoli.com with the details of your operating system."
    echo "If you're using using AWS, please include the AMI identifier for the instance."
    exit 1
fi

Original by Github issue

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

node UI/Server framework 調べ

headless Chrome で HTMLファイルから PDF変換したいけど 一時ファイル生成をしたくないので #node の html-pdf-chrome を使う

$
0
0

実行環境

AWS ElasticBeanStalk の nodejs プラットフォーム環境でトライした。

$ cat os-release
NAME="Amazon Linux AMI"
VERSION="2018.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2018.03"
PRETTY_NAME="Amazon Linux AMI 2018.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2018.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"

$ cat system-release
Amazon Linux AMI release 2018.03

dockerを使う場合はこちらを参照

Dockerを使ってHeadless Chromeを動かしてみる - Qiita

html-pdf-chrome

  • HTMLソースを渡すとPDF変換してくれるnodeのライブラリがある。
  • いちどHTMLファイルを生成しておく必要がないのでお手軽。内部的にはいったんファイル生成をしているのだろうけれど、たぶん。
  • 事前準備として、当たり前だがChromeのバイナリが必要だったり、中間役となるpm2が必要だったりする。

html-pdf-chrome - npm

nodejsのインストール

Centos や AWS Linux の場合

curl -sL https://rpm.nodesource.com/setup_10.x | sudo bash -
sudo yum install -y nodejs

Chrome バイナリのインストール

ユニバーサルスクリプトを実行するのが手軽

curl https://intoli.com/install-google-chrome.sh | bash

pm2のインストールと起動

PM2は、Node.js を本番環境で起動するためのもので、プロセスをデーモン化したりの起動を管理することができるツールです。
https://ajike.github.io/pm2-nodejs/

sudo npm install -g pm2
  • headless Chrome はあくまでブラウザなので、PDF変換するにもアクセス可能なURLが必要なため、pm2を中間役として利用すると理解した
  • てきとうなportを指定してpm2を起動する
pm2 start google-chrome-stable \
  --interpreter none \
  -- \
  --headless \
  --disable-gpu \
  --disable-translate \
  --disable-extensions \
  --disable-background-networking \
  --safebrowsing-disable-auto-update \
  --disable-sync \
  --metrics-recording-only \
  --disable-default-apps \
  --no-first-run \
  --mute-audio \
  --hide-scrollbars \
  --remote-debugging-port=9222
pm2 start google-chrome-stable   --interpreter none   --   --headless   --disable-gpu   --disable-translate   --disable-extensions   --disable-background-networking   --safebrowsing-disable-auto-update   --disable-sync   --metrics-recording-only   --disable-default-apps   --no-first-run   --mute-audio   --hide-scrollbars   --remote-debugging-port=9222
[PM2] Applying action restartProcessId on app [google-chrome-stable](ids: 0)
[PM2] [google-chrome-stable](0) ✓
[PM2] Process successfully started
┌────┬─────────────────────────┬─────────┬─────────┬──────────┬────────┬──────┬──────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name                    │ version │ mode    │ pid      │ uptime │ ↺    │ status   │ cpu      │ mem      │ user     │ watching │
├────┼─────────────────────────┼─────────┼─────────┼──────────┼────────┼──────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ 0  │ google-chrome-stable    │ N/A     │ fork    │ 7621     │ 0s     │ 2    │ online   │ 0%       │ 7.5mb    │ ec2-user │ disabled │
└────┴─────────────────────────┴─────────┴─────────┴──────────┴────────┴──────┴──────────┴──────────┴──────────┴──────────┴──────────┘

node で変換スクリプトを実行する

  • pm2でChromeを起動させた port を指定する
# convert.js

const htmlPdf = require('html-pdf-chrome');

const html = `
<p>
Hello, world!
</p>`
;

const options = {
  port: 9222, // port Chrome is listening on
};

htmlPdf.create(html, options).then((pdf) => pdf.toFile('test.pdf'));
htmlPdf.create(html, options).then((pdf) => pdf.toBase64());
htmlPdf.create(html, options).then((pdf) => pdf.toBuffer());
node convert.js

サイズ指定

CSS で指定すれば良さげ
options での指定方法は分からなかった ( window-size PageWidth などを指定してみたものの )

<style>
@page {
  margin: 0;
  padding: 0;
  size: 15in 11in;
}
</style>

PDFを確認する

サーバーからlocaleにダウンロードして確認

 scp -i /Users/yumainaura/.ssh/pup.pem ec2-user@XXX.XXX.XXX.XXX:/home/ec2-user/test.pdf ~/tmp
 open ~/tmp/test.pdf

image

Original by Github issue

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

Node.js(4):module PATH

$
0
0

パス確認

node.jsパスモジュールはディレクトリとファイルパスが取れる。先ずは今のパスを確認する。

app.js
console.log(__dirname);//ディレクトリパスconsole.log(__filename);//ファイルパス
terminal
$node app.js
/Users/xxxxx/node_practice/path
/Users/xxxxx/node_practice/path/app.js

パス重要な関数のまとめ

app.js
varpath=require('path');//今のディレクトリのパスconsole.log(path.dirname(__dirname));//ディレクトリを組み合わせconsole.log(path.join(__dirname,'/xx'));//ファイル名console.log(path.basename(__filename));//ファイル拡張子console.log(path.extname(__filename));//パス分析console.log(path.parse(__filename));
terminal
$node app.js

/Users/xxxxx/node_practice/path
/Users/xxxxx/node_practice/path/xx
app.js
.js
{ root: '/',
  dir: '/Users/xxxxx/node_practice/path',
  base: 'app.js',
  ext: '.js',
  name: 'app' }

新Github Actions を使って npm audit fix と PR 作成を自動化してみた

$
0
0

Security Alerts に怒られる前になんとかしたい!

やりたいこと

Node.js であればnpm audit fixで行える依存ライブラリの更新のような保守作業…。
日頃意識していないとなかなか手につかないので自動で Pull Request 作成までできるようにしたい。
欲を言えば、Approve や Merge も自動でやってほしい。(今回はやらない)

Github Actions

11月13日ごろに正式リリースとなる Github Actions のβ版を試してみました。

なぜ Github Actions なのか

Github Marketplaceで公開されているツールを使って Workflow が組めるので、他の CI/CD サービスよりも Github の操作がしやすいのではと思いました。

実装

今回は Create Pull Requestを使って PR作成までを自動化することにしました。

Github Actions は Push や Create Pull Request がトリガーできる他、スケジュール起動ができるので今回はそれを使ってみます。
(Security Alerts で発火できるようにならないですかねー)

Push トリガーや、Pull Request トリガーはそのブランチ上で Workflow が実行されますが、 スケジュール起動の場合は master ブランチ上でのみ動作します。Workflow も master ブランチ上に置いてあるものが読み込まれます。

こんな感じで Workflow を用意し、master ブランチに展開します。
スケジュール設定はなんとなくで週一としました。

Create Pull Requestは Github のアクセストークンを使うので、リポジトリの "Settings" -> "Secrets" から予め登録しておきます。

/.github/workflows/createPullRequest.yml
name:Create Security Fix Pull Requeston:schedule:-cron:'03**3'# 毎週水曜日の正午に実行 ( 12+JST = 3+UTC )jobs:patch:runs-on:ubuntu-lateststeps:-uses:actions/setup-node@v1# Node.js 環境の構築with:node-version:'10.x'-uses:actions/checkout@master# リポジトリを読み込み-run:npm audit fix-name:Check diff# package-lock.json の diff を読み更新がなければ終了run:|git diff --stat package-lock.jsonif ! git diff --stat package-lock.json | grep "changed" 2>&1; thenecho "Already up to date."exit 0fi-name:Create Pull Request# ブランチを作成して PullRequest を作成id:cpruses:peter-evans/create-pull-request@v1.7.0with:title:Security Update into master.label:Auto-PRbranch:securityFix#作成されるブランチは securityFix-xxxxxxxtoken:${{ secrets.GITHUB }}

動作確認

こんな感じに Workflow が動き、
image.png

PR が作成されています。(Approve、Merge は手動です)
image.png

感想

今回は Pull Request 作成まででしたが、Auto ApproveMerge pull requestsを組み合わせればリリース作業も完全に自動化できそうです。

RHEL 8にNode.js 12をインストール(AppStream)

$
0
0

はじめに

Application Stream(AppStream)を利用してRHEL8にNode.js 12をインストール
(https://qiita.com/witchcraze/items/df4a0baaaad9c932ea30)
参考:RHEL8のパッケージ構成 - BaseOSとApplication Stream - 赤帽エンジニアブログ

サポート

本手法で導入した場合、Red Hat Enterprise Linux 8 Application Streams Life Cycle - Red Hat Customer Portalより、202X-XXがEOLだと思われる。(2019-11-10時点で不明)
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。

LOG

インストール

#cat /etc/redhat-release
Red Hat Enterprise Linux release 8.1 (Ootpa)

# yum install-y @nodejs:12
... 略

各種確認

# which node
/usr/bin/node

# node -vv12.4.0

# yum module info nodejs:12
Updating Subscription Management repositories.
Unable to read consumer identity
Subscription Manager is operating in container mode.
Last metadata expiration check: 0:11:39 ago on Sun Nov 10 09:16:37 2019.
Name             : nodejs
Stream           : 12 [e]
Version          : 8010020190807190418
Context          : cdc1202b
Architecture     : x86_64
Profiles         : common [d] [i], development, minimal, s2i
Default profiles : common
Repo             : ubi-8-appstream
Summary          : Javascript runtime
Description      : Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
Artifacts        : nodejs-1:12.4.0-2.module+el8.1.0+3903+b7133459.src
                 : nodejs-1:12.4.0-2.module+el8.1.0+3903+b7133459.x86_64
                 : nodejs-debuginfo-1:12.4.0-2.module+el8.1.0+3903+b7133459.x86_64
                 : nodejs-debugsource-1:12.4.0-2.module+el8.1.0+3903+b7133459.x86_64
                 : nodejs-devel-1:12.4.0-2.module+el8.1.0+3903+b7133459.x86_64
                 : nodejs-devel-debuginfo-1:12.4.0-2.module+el8.1.0+3903+b7133459.x86_64
                 : nodejs-docs-1:12.4.0-2.module+el8.1.0+3903+b7133459.noarch
                 : nodejs-nodemon-0:1.18.3-1.module+el8.1.0+3369+37ae6a45.noarch
                 : nodejs-nodemon-0:1.18.3-1.module+el8.1.0+3369+37ae6a45.src
                 : nodejs-packaging-0:17-3.module+el8.1.0+3369+37ae6a45.noarch
                 : nodejs-packaging-0:17-3.module+el8.1.0+3369+37ae6a45.src
                 : npm-1:6.9.0-1.12.4.0.2.module+el8.1.0+3903+b7133459.x86_64

Name             : nodejs
Stream           : 12 [e] [a]
Version          : 8010020190807190418
Context          : cdc1202b
Architecture     : x86_64
Profiles         : common [d] [i], development, minimal, s2i
Default profiles : common
Repo             : rhel-8-for-x86_64-appstream-rpms
Summary          : Javascript runtime
Description      : Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
Artifacts        : nodejs-1:12.4.0-2.module+el8.1.0+3903+b7133459.src
                 : nodejs-1:12.4.0-2.module+el8.1.0+3903+b7133459.x86_64
                 : nodejs-debuginfo-1:12.4.0-2.module+el8.1.0+3903+b7133459.x86_64
                 : nodejs-debugsource-1:12.4.0-2.module+el8.1.0+3903+b7133459.x86_64
                 : nodejs-devel-1:12.4.0-2.module+el8.1.0+3903+b7133459.x86_64
                 : nodejs-devel-debuginfo-1:12.4.0-2.module+el8.1.0+3903+b7133459.x86_64
                 : nodejs-docs-1:12.4.0-2.module+el8.1.0+3903+b7133459.noarch
                 : nodejs-nodemon-0:1.18.3-1.module+el8.1.0+3369+37ae6a45.noarch
                 : nodejs-nodemon-0:1.18.3-1.module+el8.1.0+3369+37ae6a45.src
                 : nodejs-packaging-0:17-3.module+el8.1.0+3369+37ae6a45.noarch
                 : nodejs-packaging-0:17-3.module+el8.1.0+3369+37ae6a45.src
                 : npm-1:6.9.0-1.12.4.0.2.module+el8.1.0+3903+b7133459.x86_64

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled, [a]ctive

RHEL 8にNode.js 10をインストール(AppStream)

$
0
0

はじめに

Application Stream(AppStream)を利用してRHEL8にNode.js 10をインストール
(https://qiita.com/witchcraze/items/df4a0baaaad9c932ea30)
参考:RHEL8のパッケージ構成 - BaseOSとApplication Stream - 赤帽エンジニアブログ

サポート

本手法で導入した場合、Red Hat Enterprise Linux 8 Application Streams Life Cycle - Red Hat Customer Portalより、2021-04がEOLだと思われる。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。

LOG

インストール

#cat /etc/redhat-release
Red Hat Enterprise Linux release 8.1 (Ootpa)

# yum install-y @nodejs:10
... 略

各種確認

# which node
/usr/bin/node

# node -vv10.16.3

# yum module info nodejs:10
Updating Subscription Management repositories.
Unable to read consumer identity
Subscription Manager is operating in container mode.
Last metadata expiration check: 0:15:03 ago on Sun Nov 10 09:16:37 2019.
Name             : nodejs
Stream           : 10 [d][e]
Version          : 8000020190911085529
Context          : f8e95b4e
Architecture     : x86_64
Profiles         : common [d] [i], development, minimal, s2i
Default profiles : common
Repo             : ubi-8-appstream
Summary          : Javascript runtime
Description      : Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
Artifacts        : nodejs-1:10.16.3-2.module+el8.0.0+4214+49953fda.src
                 : nodejs-1:10.16.3-2.module+el8.0.0+4214+49953fda.x86_64
                 : nodejs-debuginfo-1:10.16.3-2.module+el8.0.0+4214+49953fda.x86_64
                 : nodejs-debugsource-1:10.16.3-2.module+el8.0.0+4214+49953fda.x86_64
                 : nodejs-devel-1:10.16.3-2.module+el8.0.0+4214+49953fda.x86_64
                 : nodejs-devel-debuginfo-1:10.16.3-2.module+el8.0.0+4214+49953fda.x86_64
                 : nodejs-docs-1:10.16.3-2.module+el8.0.0+4214+49953fda.noarch
                 : nodejs-nodemon-0:1.18.3-1.module+el8+2632+6c5111ed.noarch
                 : nodejs-nodemon-0:1.18.3-1.module+el8+2632+6c5111ed.src
                 : nodejs-packaging-0:17-3.module+el8+2873+aa7dfd9a.noarch
                 : nodejs-packaging-0:17-3.module+el8+2873+aa7dfd9a.src
                 : npm-1:6.9.0-1.10.16.3.2.module+el8.0.0+4214+49953fda.x86_64

Name             : nodejs
Stream           : 10 [d][e][a]
Version          : 8000020190911085529
Context          : f8e95b4e
Architecture     : x86_64
Profiles         : common [d] [i], development, minimal, s2i
Default profiles : common
Repo             : rhel-8-for-x86_64-appstream-rpms
Summary          : Javascript runtime
Description      : Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
Artifacts        : nodejs-1:10.16.3-2.module+el8.0.0+4214+49953fda.src
                 : nodejs-1:10.16.3-2.module+el8.0.0+4214+49953fda.x86_64
                 : nodejs-debuginfo-1:10.16.3-2.module+el8.0.0+4214+49953fda.x86_64
                 : nodejs-debugsource-1:10.16.3-2.module+el8.0.0+4214+49953fda.x86_64
                 : nodejs-devel-1:10.16.3-2.module+el8.0.0+4214+49953fda.x86_64
                 : nodejs-devel-debuginfo-1:10.16.3-2.module+el8.0.0+4214+49953fda.x86_64
                 : nodejs-docs-1:10.16.3-2.module+el8.0.0+4214+49953fda.noarch
                 : nodejs-nodemon-0:1.18.3-1.module+el8+2632+6c5111ed.noarch
                 : nodejs-nodemon-0:1.18.3-1.module+el8+2632+6c5111ed.src
                 : nodejs-packaging-0:17-3.module+el8+2873+aa7dfd9a.noarch
                 : nodejs-packaging-0:17-3.module+el8+2873+aa7dfd9a.src
                 : npm-1:6.9.0-1.10.16.3.2.module+el8.0.0+4214+49953fda.x86_64

Name             : nodejs
Stream           : 10 [d][e][a]
Version          : 820190108092226
Context          : 9edba152
Architecture     : x86_64
Profiles         : common [d] [i], development, minimal, s2i
Default profiles : common
Repo             : rhel-8-for-x86_64-appstream-rpms
Summary          : Javascript runtime
Description      : Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
Artifacts        : nodejs-1:10.14.1-1.module+el8+2632+6c5111ed.x86_64
                 : nodejs-devel-1:10.14.1-1.module+el8+2632+6c5111ed.x86_64
                 : nodejs-docs-1:10.14.1-1.module+el8+2632+6c5111ed.noarch
                 : nodejs-nodemon-0:1.18.3-1.module+el8+2632+6c5111ed.noarch
                 : nodejs-packaging-0:17-2.module+el8+2632+6c5111ed.noarch
                 : npm-1:6.4.1-1.10.14.1.1.module+el8+2632+6c5111ed.x86_64

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled, [a]ctive

Online完結!Web開発環境クッキングレシピ[ver 2019.11]-その1

$
0
0

サマリー

Web開発を学習しようとする場合、開発環境を準備したり、実行環境を準備したりするまでの流れをつかみ取るのは、実際のところハードルが高いと思います(Web系開発であればなおさら)。
初学者の方でも環境構築まで、つまづかずに行える手順の1つとして思案し、参考になる記事作成をしたいと思い、執筆してみます(ちなみに、筆者は業務ではWeb開発も、Linux系環境も専門外なので、その点はご容赦くださいませ)

GitHubリポジトリへコードを配置する方法です。この手順を参考にご自身のソースコードを追加する場合、ソースコードはGitHubを検索するすべての方に見えてしまいますので、認証情報や業務上秘匿にしなくてはいけないような内容を誤って組み込まないように強く留意しましょう。

調理の具材

Webブラウザ、Javascript、Node.js、GitHub、Gitpod、Heroku、Docker
これらを調理していきます。

具材について

  • Javascript:プログラミング言語
  • Node.js:Javascriptを実行する環境の1つ
  • GitHub:プログラミング言語で構成するプログラムのソースコード群を管理するソフトウェアのGitをCloudサービス化し、提供しているサービス名
  • Gitpod:GitHubで管理されたソースコードの開発環境をCloudサービスとして提供しているサービス名
  • Heroku:クラウドサービス基盤を提供しているサービス名
  • Docker:クラウドサービスのサーバー機能を提供する、仕組みの1つ

下準備

この記事の環境構築用に1つGoogleアカウントを作成するのがよいと思います(他のMicrosoftアカウントや、Yahooアカウントのようなものでも良いです)
また、このアカウントを利用して、GitHub、Herokuのそれぞれのアカウントも作成する流れになりますので、留意してください。

手順.1 GitHubのアカウントを準備する

GitHubへWebブラウザからアクセスして、新しいGitHubアカウントを作成します。(Sign Up)
image.png
この記事で前提にしているGoogleアカウントのメールアドレスとユーザー名、パスワードを設定してアカウントを作成完了しましょう。
image.png
プランの選択でFreeを選択します。登録したメールアドレスに認証用のメールが届いているので、リンクをクリックして認証させておきましょう。

手順.2 GitHubへ新規リポジトリを作成する

image.png
GitHubにログインした状態で左上のアイコンをクリックすると、このような表示になります。
左上にあるNewボタンを押して、新規リポジトリを作成します。
image.png
リポジトリ名を herokudev と入力してCreate repositoryボタンを押します。

手順.3 リポジトリへgitpod用のファイルを追加

後続の手順でgitpodというWeb上でオンラインで開発環境を提供するサービスを利用するので、そのgitpod用のファイルを配置します。
GitHubを設定して開発する方法をネット検索する場合、ほとんど間違いなくリポジトリを作成したら、Clone(クローン)をする説明になっていると思いますが、ここではその方法をとらず、GitHubのWebインターフェースから直接ファイル追加を行います。
image.png
手順.2の後にはこのページが表示されているので、creating a new file のリンクをクリックします。
image.png
herokudev / のところにある、ファイル名入力テキストボックスに
.gitpod.yml
Edit new fileの下のファイルの編集領域に

gitpod.yml
image:file:.gitpod.dockerfile

と入力し、ページをスクロールした一番下のCommit new fileを押して、作成完了します

同様の手順で
.gitpod.dockerfile
というファイルを

gitpod.dockerfile
FROM gitpod/workspace-full:latestUSER root# Setup Heroku CLIRUN curl https://cli-assets.heroku.com/install.sh | sh
RUN chown-R gitpod:gitpod /home/gitpod/.cache/heroku

にて作成します。

.gitignore
というファイルを

# Node build artifacts
node_modules
npm-debug.log

# Local development
*.env
*.dev
.DS_Store

にて作成します。

手順.4 gitpodのアカウント作成

GitpodはWebの開発時のソースコード編集エディタ(+デバッグやそのほかの機能も含んでいる)としてよく利用されているVisualStudioCodeというアプリケーションのWebブラウザ版のような機能を提供するサービスです。
GitHub同様、無料で利用できるアカウントが作成できるので、こちらをセットアップしていきます。
image.png

手順.3までであなたのGitHubリポジトリは
https://github.com/アカウント名/herokudev
となっているはずなので、Gitpodのトップページ中段に記載されているように
WebブラウザのURLアドレス入力欄に
gitpod.io/#!https://github.com/アカウント名/herokudev
と入力して移動します。
アカウント名、のところは各自の実際のアカウント名に変えること
image.png

移動すると下のページが表示されるので Login with GitHub & launch workspaceのボタンをクリックします。
image.png
するとGitHubアカウントで認証するかの確認を求められるので、Authorize gitpod.ioをクリックします。
image.png
今度はGitpodのアカウント作成時の確認項目と作成ボタンが表示されるので、I agree to the terms of service にはチェックを入れて、 Create free account をクリックします。
image.png
しばらく、Dockerの準備が実行されている様子が表示されていますので、待ちます。
image.png
作成が完了すると、Webブラウザには以下のような画面が表示されます。 Welcome表示はDismissで閉じましょう。
image.png
この時点でページに表示されているのは、VisualStudio Codeとそっくりな画面です。
ページの下部にLinuxのシェルが表示されています。
image.png

試しに以下のコマンドを打ってみます。

cat /etc/os-release

NAME="Ubuntu"
VERSION="19.04 (Disco Dingo)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 19.04"
VERSION_ID="19.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=disco
UBUNTU_CODENAME=disco

Gitpod上で開発環境のubuntuが稼働しました!
Gitpodの環境は、Freeプランの場合、1か月に稼働可能な時間が限られています。
[Free 100 hours / month]
開発環境の利用を一時中断するにはFileメニューからStop Workspaceを選択し、
ダイアログでStop Onlyを選択します。

image.png
image.png

再度gitpodでの作業を継続したい場合は、https://gitpod.io/へアクセスの後、
右上のGo to appのリンクをクリックして、ログインすると、前回の環境(ワークスペース)が表示されているので、スタートのリンクを押して、再開します。
image.png

長くなりましたので、続きは別の記事にしたいと思います。
その2

Online完結!Web開発環境クッキングレシピ[ver 2019.11]-その2

$
0
0

Online完結!Web開発環境クッキングレシピ[ver 2019.11]-その1、の続きです

手順.5 node.jsで実行するコードを整備する

ログインしたGitpodのページで画面下部のところが、Terminalになっています。
ここで、コマンドを入力して、node.js用のコードを整備していきます。
image.png

npm init

すべての質問にEnterとして終了させます
今の質問の中で、entry pointをデフォルトのindex.jsで回答したことになり、この情報がpackage.jsonファイルに記載されたので、index.jsという名前のJavascriptコードを用意します
ページの左上にある、Fileメニューを選択し、New Fileのメニューアイテムを選択します
image.png
ダイアログに、index.jsと入力して、OK を押します
image.png

index.jsというタブが表示され、コードが入力できますので、下記の通り、コードを入力し、Ctrl+Sで、保存します。
image.png

index.js
letport=process.env.PORT||5000;consthttp=require('http');http.createServer((req,res)=>{res.writeHead(200,{'Content-Type':'text/plain'});res.end('Hello World\n');}).listen(port,()=>console.log('Server http://localhost:'+port));

続いて、npm initで生成された package.json を編集します

  "scripts": {
    "start": "node index.js",  この行を追加
    "test": "echo \"Error: no test specified\" && exit 1"
  },

手順.6 node.jsで実行してみる

ページの下部にあるTerminalで、npm run startと入力してみます。
image.png
下記のダイアログが表示されますので、Exposeをクリックし、その次に、Open Browserをクリックします。
image.png
GoogleChromeであれば、別のタブが開き、Hello Worldと表示されます。
これはすなわち、WebServerがPort3000で起動し、かつそのサーバーにアクセスするブラウザを開いたことになります。
image.png
Terminalに戻り、Ctrl+Cを入力して、サーバーを終了させます。

手順.7 リポジトリを更新させる

npm initやindex.js追加などを行ったので、画面左のファイルの一覧がUマークが付いた状態になります。これをGitHubのリポジトリへ更新させます。

一番左側のアイコンのある列の真ん中(Source Control:Git)を選択します。
image.png
CHANGESの下に変更ファイルがリストされます。ファイルの場所へマウスを移動すると小さなアイコンが表示されるので、index.js, package.json ともに + のボタンを押します。
image.png
すると、STAGED CHANGESにindex.js, package.jsonが含まれますので、STAGED CHANGESの上にあるメッセージ入力部に、
index.js, package.json追加
と入力して、
image.png
さらにその上にあるチェックのボタンを押します。
image.png
この時点で、ローカルGITへのコミットが完了しています。

今度はページ一番右のGitHubのアイコンをクリックすると、Push、というボタンが見えますので、これをクリックします。
image.png
このようなダイアログが表示されるかもしれないので、Grant Permission を
クリックします。
image.png
Authorize gitpod-ioをクリック、Gitアカウントのパスワードを入力します。
image.png
この画面が別ウインド(タブ)で表示されればOKです。元のブラウザのタブに戻ります。
image.png

もう一度、Pushのボタンを押します。完了すると、Pushのボタンは表示されなくなります。
この時点で、GitHubのリポジトリは更新されました。

ここまでの設定で、GitHubのリポジトリに作成したnode.jsのサーバーをGitpod上で編集し、かつ実行できることが確認できました。

開発を実務で行うとすると、この手順6,7を繰り返すことになります。

長くなりましたので、続きは別の記事にしたいと思います。
その3

Online完結!Web開発環境クッキングレシピ[ver 2019.11]-その3

$
0
0

Online完結!Web開発環境クッキングレシピ[ver 2019.11]-その2、の続きです

手順.8 Heroku用ファイルを追加して、リポジトリを更新

Web開発環境クッキングレシピ[ver 2019.11]-その2、の継続で、gitpodへログインし、.heroku.dockerfileとheroku.ymlファイルを追加します

heroku.dockerfile
FROM node:12.13WORKDIR /appCOPY . /appRUN npm i
CMD npm start
heroku.yml
build:docker:web:.heroku.dockerfile

手順6と同じように、リポジトリを更新する作業をしましょう。

手順.9 Herokuアカウントを作成する

Herokuのサインアップページを開き、アカウントを作成します。Primary development languageはNode.jsとし、必要項目を入力して(Companyは任意)Create Free Accountをクリックします。
image.png

Herokuより、メールが飛んで来るので、メール内のリンクをクリックして、パスワード設定画面を開きます。
image.png
下記画面になるので、進みます。
image.png

手順.10 Herokuアプリケーションを作成する

下記画面で Create new appのボタンをクリックします。
image.png
App nameのところに、名前を入力します。この名前はHerokuのサービスで一意の名前でなくてはいけないので、ほかのユーザーと重複しないものを考えて命名します。
image.png
次の画面で、Deployment methodを GitHub に選択しなおします。
image.png
選択すると、下に Connect to GitHub のボタンが表示されるので、クリックします。
image.png
以下のようなポップアップが表示されるので、Authorize heroku をクリックし、次のポップアップでGitHubアカウントのパスワードを入力します。
image.png
Connect to GitHubの場所にリポジトリ名を選択する場所が表示されますので、herokudevとしてSearchボタンを押し、Connectのボタンをクリックして、HerokuとGitHubリポジトリを接続します。
image.png
接続が完了するとページ下部にAutomoatic DeployとManual deployが表示されるので、Manual deploy の場所にあるDeployBranchを押してデプロイを実行してみます。
image.png
デプロイが成功すると、Your app was successfully deployedと表示され、下にViewの
ボタンが表示されるので、クリックします。
image.png
Hello Worldページが表示されるかと思います
image.png

手順.11 Herokuの実行スタックをContainerへ変更

手順10でのHeroku のサーバー環境はHeroku-18 Stackというものになっているので、これをContainerへ変更します
Gitpodへログイン、ワークスペースを開き、ページ下部のTerminalのところに移動してコマンドを入力していきます

heroku login --interactive

Emailとパスワードを促されますので、Heroku へのログイン情報を入力します
image.png

heroku list と入力するとあなたの作成したアプリケーション名が表示されるので、記憶し、heroku stack:set container -a あなたのアプリケーション名と入力します

heroku list
heroku stack:set container -a *****

念のため、最後にheroku logout でログアウトしておきましょう。

手順.12 Herokuの再デプロイ

手順10のManual deploy、DeployBranchを押してデプロイを再実行してみます。

Dockerコンテナを構築しているログが表示されている様子がわかります。
デプロイが成功したら再度Viewをクリックして、アプリケーションが動作していることを確認します。
image.png

Herokuの設定にはAutomatic deploysもありますので、こちらを設定すれば、Gitpodでプログラムソースコード編集をし、コミットをすれば自動でHerokuがDeployを実行するかと思いますが、こちらの設定は省略します。

終わりに(お味はいかが?)

いくつかのサービスの無料アカウントを駆使して、Webブラウザのみで開発から実行環境を整える方法の1つとして、手順化することができました。環境への依存度が低いこの方法でプログラミング学習や実験などに活用いただけたらと思います。

#docker alpine + headless Chrome + #node pm2 + html-pdf-chrome で HTML PDF 変換する。一時ファイル必要なし。

$
0
0

html-pdf-chrome

https://github.com/westy92/html-pdf-chrome

  • puppeteer ではない
  • HTMLファイルではなくソースを渡した時にPDF変換したい

docker

docker run -it alpine ash

chromium フォント nodejs をインストール

apk add --update udev ttf-freefont chromium nodejs npm

必要があれば Google 日本語フォントのインストール

mkdir /noto

cd /noto

wget https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip

unzip NotoSansCJKjp-hinted.zip && mkdir -p /usr/share/fonts/noto && cp *.otf /usr/share/fonts/noto && chmod 644 -R /usr/share/fonts/noto/ && fc-cache -fv

cd /

Dockerを使ってHeadless Chromeを動かしてみる - Qiita

node module をインストール

npm install html-pdf-chrome
npm install -g pm2

pm2の起動

--headless --no-sandbox --disable-gpu を指定する

pm2 start chromium-browser --interpreter none -- --headless --no-sandbox  --disable-gpu --disable-translate --disable-extensions --disable-background-networking --safebrowsing-disable-auto-update --disable-sync --metrics-recording-only --disable-default-apps --no-first-run --mute-audio --hide-scrollbars --remote-debugging-port=9222

...

┌────┬─────────────────────────┬─────────┬─────────┬──────────┬────────┬──────┬──────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name                    │ version │ mode    │ pid      │ uptime │ ↺    │ status   │ cpu      │ mem      │ user     │ watching │
├────┼─────────────────────────┼─────────┼─────────┼──────────┼────────┼──────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ 0  │ chromium-browser        │ N/A     │ fork    │ 99       │ 0s     │ 0    │ online   │ 0%       │ 2.0mb    │ root     │ disabled │
└────┴─────────────────────────┴─────────┴─────────┴──────────┴────────┴──────┴──────────┴──────────┴──────────┴──────────┴──────────┘

変換スクリプト

CSSもすべて詰め込んだHTML

consthtmlPdf=require('html-pdf-chrome');consthtml=`
<html>
<head>
  <style>
  @page {
    margin: 0;
    padding: 0;
    size: 15in 11in;
  }
</style>
</head>
<body>
<h1>HELLO!</h1>
</body>
</html>
`;constoptions={port:9222,// port Chrome is listening on};htmlPdf.create(html,options).then((pdf)=>pdf.toFile('./example.pdf'));htmlPdf.create(html,options).then((pdf)=>pdf.toBase64());htmlPdf.create(html,options).then((pdf)=>pdf.toBuffer());

変換

node convert.js

local で確認

docker cp <DOCKER_CONTAINER_ID>:/example.pdf ./
open ./example.pdf

結果

image

CSS JS 対応状況は?

headless chrome を利用してるので、なんでもできるでしょ。

HTML から CSS JS ファイルを参照するには?

docker で http サーバーを立てて 外部参照可能な場所にファイルを置ければよいのかもしれないが、未調査。

pm2 が使える?使えない? 使い方調査が必要だ。

AWS - Amazon Linux 環境の場合は

chrome binary をインストールするための universal な shell script がある

Installing Google Chrome On CentOS, Amazon Linux, or RHEL

Original by Github issue

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

Node(express)でサーバーを立てた時、 CORSエラー出てしまったらヘッダー情報を追加しよう

$
0
0

状況・経緯

Node(express)を使用してAPIを作成。そのAPIを別で立てたローカルサーバーでアクセスしたら以下のようなエラーが出た。

Access to fetch at 'http://localhost:3000/' from origin 'http://127.0.0.1:8080'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

http://127.0.0.1:8080からlocalhost:3000へのアクセスは CORSポリシーによってブロックされていますといわれてしまった・・・

CORSとは

オリジン間リソース共有(Cross-Origin Resource Sharing)のこと。セキュリティ上の理由からブラウザからオリジン間HTTPリクエストを制限している。

オリジン間リソース共有Cross-Origin Resource Sharing (CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。ウェブアプリケーションは、自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) にあるリソースをリクエストするとき、オリジン間 HTTP リクエストを実行します。

オリジン間リソース共有 (CORS)

No 'Access-Control-Allow-Origin' header is present on the requested resource. とは

CORS リクエストへのレスポンスが、リソースが現在のオリジン内で操作しているコンテンツによってアクセスできるかどうかを判断するために使われる、必須の Access-Control-Allow-Origin ヘッダーを欠いています。

ヘッダー情報にAccess-Control-Allow-Originがないからダメと怒られているらしい。

解決策

解決するには、
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
CORSを無効にして no-corsモードをセットしろとのこと。

なので、

ヘッダーに

Access-Control-Allow-Origin: *

を追加した。

何をしたのか

自分で用意したサーバーへのアクセスを許可した。

今回の場合、http://127.0.0.1:8080でアクセスしようとしたらエラーが出たのでこのように書くとアクセスが許可される。

Access-Control-Allow-Origin: http://127.0.0.1:8080

また、ワイルドカードである*を使用することであらゆるアクセスを許可することができる。

Access-Control-Allow-Origin: *を使う際の注意点

公開するAPIには使用しても問題ないが、非公開APIには具体的なドメインやドメイン一覧を設定すること。

詳しくは↓
Reason: CORS header 'Access-Control-Allow-Origin' missing

expressでサーバーを立てた場合

server.js
constexpress=require('express');constapp=express();constport=process.env.PORT||3000;app.set('port',port);// サーバースタートapp.listen(port,()=>console.log(`App started on port ${port}.`));// ドメイン直下(localhost:3000)にアクセスした時の処理app.get('/',(req,res,next)=>{res.set({'Access-Control-Allow-Origin':'*'});// ここでヘッダーにアクセス許可の情報を追加// 何らかの処理});

このような感じになる。


参考

オリジン間リソース共有 (CORS)
CORS のエラー
逆引きメモ:expressの使い方

Viewing all 8818 articles
Browse latest View live