- 投稿日:2020-05-22T21:49:29+09:00
あなたのnpmパッケージ、脆弱性の塊説。急いで最新にするよ!
npm便利ですよね。
昨今フロントweb開発でNode.jsが登場しないことはないので、みなさんお使いかと思いますが、ちゃんとバージョン管理していますか?
私はしがないweb制作者ですが、npmパッケージなしでの開発はありえないです。
ただそういえばバージョン管理をしていないなと思い、現在バージョンと最新バージョンを比べてみることに。そしたら...
$ npm outdated
微妙にパッケージが古くなってた...
npm-check-updatesをインストール
まずはpackage.jsonを最新バージョンにアップグレードしてくれるnpm-check-updatesをインストールします。
npm i npm-check-updatesそしたら、
ncu -u
Run npm install to install new versions.
というメッセージが出たらOK、最後にパッケージをインストールします。
npm iすると...
660の脆弱性があるから直すためにnpm audit fixしろよな!
ということらしいです?
ヒェ...
(npmの更新サボってた人はみんな数百レベルであると思われます)とりあえずコマンドを実行します。脆弱性のある箇所を自動修正してくれるコマンドです。
npm audit fixすると
残り12個の脆弱性は手作業でオナシャス!!
ということらしい。
マジかい。
npm auditで脆弱性一覧を出してみる。
15個の脆弱性のうち、一個の危険性が
high
になっていました(脆弱性から正規表現を使ったDoS攻撃を受ける可能性があるそうです)highのものを詳しくみてみます。
───────────────┬──────────────────────────────────────────────────────────────┐ │ High │ Denial of Service │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Package │ http-proxy │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Patched in │ >=1.18.1 │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Dependency of │ browser-sync [dev] │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Path │ browser-sync > http-proxy │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ More info │ https://npmjs.com/advisories/1486 │ └───────────────┴──────────────────────────────────────────────────────────────┘
browser-syncが依存している、http-proxyに問題があるそう。なんぞこれ...?
調べてみると、執筆時点5日前にアップデートが出ており、最新版にする必要がありそうです。
https://www.npmjs.com/advisories/1486
とりあえず
$ npm install http-proxyで最新版をダウンロードし、再度脆弱性のある箇所を自動修正してくれるコマンド↓
npm audit fixすると...
fixed 9 of 13 vulnerabilities in 1275 scanned packages 4 vulnerabilities required manual review and could not be updatedhigh消えたし、4つまで減らせたよかった!!
ぬわ〜ん疲れたも〜ん!!
結論 npmは定期的にお手入れせよ
バージョンは古くなってるし、脆弱性はあるし、多分自動化できるんだろうけど弱弱エンジニアなので、これから調べてみます。
みんなもnpmパッケージのバージョン管理、やろう!!
- 投稿日:2020-05-22T19:02:31+09:00
HTMLから画像を生成するシンプルな方法(Node.js)
どうもこんにちは、@y_temp4です。
最近、趣味で個人開発している Web サービスの AnyMake にて、画像を動的に生成するプログラムを書く機会があったのでその方法についてまとめてみます。
関連記事:埋め込みコンテンツを追加しました!| AnyMake | note
node-html-to-image を使う
自分は画像生成周りは全然詳しくないのですが、普段フロントエンドのコードを書くことが多いので
「HTML から画像生成できたら便利だな〜」
と思いました。
そこで少し調べると、node-html-to-imageというライブラリが見つかり、これを使うと割と簡単にやりたいことが実現できそうでした。
使い方
以下のコードは README からの引用ですが、このように HTML を引数として渡してやると、その HTML の表示結果が画像として出力されます。
const nodeHtmlToImage = require("node-html-to-image"); nodeHtmlToImage({ output: "./image.png", html: "<html><body>Hello world!</body></html>" }).then(() => console.log("The image was created successfully!"));上記の例だと、「Hello World!」と書かれたシンプルな画像ファイルが生成されます。
今回自分は画像を返す API を作りたかったので、README にある以下のコードを参考に作成しました。
const express = require("express"); const router = express.Router(); const nodeHtmlToImage = require("node-html-to-image"); router.get(`/api/tweet/render`, async function(req, res) { const image = await nodeHtmlToImage({ html: "<html><body><div>Check out what I just did! #cool</div></body></html>" }); res.writeHead(200, { "Content-Type": "image/png" }); res.end(image, "binary"); });非常にシンプルですがこれで最低限やりたいことは実現できたので、お手軽に画像生成したい場合はこれが良さそうです。
ちなみにですが、このライブラリの内部処理としては Puppeteer で HTML を描画してスクリーンショットを撮っているだけです。
言われてみれば確かにこれでいけるな...と README や内部の処理を読んでいて思いましたが、やっている事的にあんまり軽くはなさそうなので、もしこれより良さそうな方法で簡単に HTML から画像を生成する方法をご存知の方がいらっしゃればぜひコメント欄にて教えていただけますと嬉しいです ?
- 投稿日:2020-05-22T17:21:49+09:00
【超初級】Node.jsの始め方 〜 2020.05.22ver〜
? Node.jsをインストールしてみよう♪
https://nodejs.org/ja/
こちらをクリックするとHPに行くと以下のような画面が出てくると思います。
どっちでも良いですが、推奨版をインストールするほうが安定的かもしれません。
流石に、インストールの方法は皆さんご存知かと思うので割愛します。? nodeがインストールできたか確認してみよう
実際にnodeが入っているかを確認しましょう!
ターミナルnode -vターミナルを開き上記のように入力してみてください。
v12.16.3などと出てきたらOKです!? npmについて
nodeで開発を行っていく上で、必須となってくるのがnpmと呼ばれるもので
ノード関連のパッケージマネージャーです。
Node Package Maneger の略です。Ruby on Railsでいうgemみたいな感じです。
多様なライブラリを後から追加で使うことができます。
expressなどが有名です。これは、nodeをインストールすると同時にnpmもインストールされます。
確認してみましょうターミナル% npm
このような画面が出ていればnpmもインストールされています。? ファイルを立ち上げてみよう!
今回はVSCodeを使っていきます。
それに類するものであればなんでもいいです。
早速、どこでも良いので適当なフォルダを作ります。
先程作ったフォルダの中に、ファイルを作成します。
nodeはJavaScriptなので.jsファイルを作成します。
適当にコードも書いてみましょう。では、nodeで実際にファイルを立ち上げてみましょう。
ターミナルから自身が作ったディレクトリまで行きます。
すると、先程作成した、hello.jsが存在していると思います。
ターミナル% node hello.jsこのように記入してみてください。
すると、hello.jsに書いたコードが実際にターミナルに反映されています。
書いていて気づきましたが、helloを誤字ってるのは気にしないでください(恥)このように、nodeでファイルを立ち上げるときは、 node ファイル名 という形でターミナルに記載すればOKです。
ちなみに、ターミナルに入力するときは、.jsといった拡張子は実は書く必要がないので、次回から省いていきましょう!超基礎的で退屈だったかもしれませんが、今回は以上です!
? 次回予告
今後の方針として、expressを使わずに、簡単なメモツールを作成していこうかと思います。
nodeの基本をさっくりと沿っていくような形になります。
興味のある方は是非、見ていってください!記事を見てくださりありがとうございます。
5分で理解できるを記事を目標に執筆しております!
自身も学びの途中ですので、間違い等ありましたら、ドシドシ編集リクエストまでお願いします!
- 投稿日:2020-05-22T15:01:13+09:00
ShopifyアプリをTypescriptで開発する方法
はじめに
Shopifyアプリとは、Shopifyストアに機能を追加するWebアプリケーションです。
下記URLのチュートリアルでは、Node.js、React、GraphQLを使用して埋め込みShopifyアプリを構築するプロセスについて説明されておりますが、Typescriptで開発したいと思い、実装する方法を調べて実現できたのでご紹介したいと思います。https://shopify.dev/tutorials/build-a-shopify-app-with-node-and-react
開発環境
下記環境で確認しています。
- Mac
- VSCode
- node.js
- Shopify App CLI
プロジェクト作成
Shopify App CLIでベースのnodeのプロジェクトを作成します。
- PublicかCustomを選択します。
% shopify create node --name=starter-embedded-app ? What type of app are you building? (Choose with ↑ ↓ ⏎, filter with 'f') > 1. Public: An app built for a wide merchant audience. 2. Custom: An app custom built for a single client.
- 次にどの開発ストア向けで作成するか選択します。
% shopify create node --name=starter-embedded-app ? What type of app are you building? (You chose: Public: An app built for a wide merchant audience.) Organization [Shopify Partnerアカウントのビジネス名] ? Select a Development Store (Choose with ↑ ↓ ⏎, filter with 'f') 1. xn-xxxxx1.myshopify.com > 2. xn-xxxxx2.myshopify.com
- プロジェクトが生成されます。
% shopify create node --name=starter-embedded-app ? What type of app are you building? (You chose: Public: An app built for a wide merchant audience.) Organization [Shopify Partnerアカウントのビジネス名] ? Select a Development Store (You chose: xn-xxxxx2.myshopify.com) ✓ node v14.3.0 ✓ npm 6.14.4 ┏━━ Cloning into starter-embedded-app... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┃ Cloning into 'starter-embedded-app'... ┃ remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Compressing objects: 100% (3/3), done. remote: Total 1071 (delta 0), reused 0 (delta 0), pack-reused 1068 Receiving objects: 100% (1071/1071), 1.83 MiB | 1.97 MiB/s, done. Resolving deltas: 100% (720/720), done. ┃ 100% ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ (3.11s) ━━ ✓ Cloned into starter-embedded-app ┏━━ Installing dependencies with npm... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┃ ✓ 37 npm dependencies installed ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ (53.38s) ━━ ✓ Dependencies installed ✓ .env saved to project root ✓ starter-embedded-app was created in your Partner Dashboard https://partners.shopify.com/xxxxx/apps/xxxxx ⭑ Run shopify serve to start a local server ⭑ Then, visit https://partners.shopify.com/xxxxx/apps/xxxxx/test to install starter-embedded-app on your Dev Store
- アプリを起動し、アプリをストアにインストールして動作を確認します。
Typescript開発セットアップ
Typescript開発で必要なパッケージをインストールします。
※ 先にncuで既存パッケージの最新化もします。
※ typescriptに関しては、最新の3.9.3ではエラーがでてたのでバージョンを3.8.3に指定してインストールしています。% ncu -u % npm install % npm install --save-dev typescript@3.8.3 ts-node @types/node @types/react @types/react-dom @types/koa @types/koa-session @types/koa-router @types/js-cookie
tsconfig.json, tsconfig.server.json, next-env.d.ts, nodemon.json ファイルを作成します。
tsconfig.json{ "compilerOptions": { "target": "esnext", "module": "esnext", "jsx": "preserve", "lib": ["dom", "es2017"], "baseUrl": ".", "moduleResolution": "node", "strict": true, "allowJs": true, "noEmit": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, "skipLibCheck": true, "noUnusedLocals": true, "noUnusedParameters": true, "isolatedModules": true, "removeComments": false, "preserveConstEnums": true, "sourceMap": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true }, "exclude": ["dist", ".next", "out", "next.config.js"], "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"] }tsconfig.server.json{ "extends": "./tsconfig.json", "compilerOptions": { "module": "commonjs", "outDir": "dist", "target": "es2017", "isolatedModules": false, "noEmit": false }, "include": ["server/**/*.ts"] }nodemon.json{ "watch": ["server"], "exec": "ts-node --project tsconfig.server.json server/server.ts", "ext": "js ts" }next-env.d.ts/// <reference types="next" /> /// <reference types="next/types/global" />package.jsonを下記の通り編集します。
package.json〜省略〜 "scripts": { "test": "jest", "dev": "NODE_ENV=development nodemon", "build": "next build && tsc --project tsconfig.server.json && cp server/index.js dist/", "start": "NODE_ENV=production node dist/index.js" }, 〜省略〜JSファイルをTS/TSXファイルに変更する
JSファイルをTS/TSXファイルに変更して、エラー箇所を修正していきます。
- pages/index.js は pages/index.tsx にリネームのみ
- pages/_app.js は pages/_app.tsx にリネームし、下記の通り編集します。
pages/_app.tsx〜省略〜 import translations from "@shopify/polaris/locales/en.json"; declare var API_KEY: string; // 追加 const client = new ApolloClient({ 〜省略〜 const { Component, pageProps } = this.props; const shopOrigin = Cookies.get("shopOrigin") ?? "error"; // 変更 return ( 〜省略〜
- server/server.js は server/server.ts にリネームし、下記の通り編集します。
server/server.ts〜省略〜 import session from "koa-session"; // import * as handlers from "./handlers/index"; コメントアウト dotenv.config(); const port = parseInt(process.env.PORT || '8081', 10); // 変更 const dev = process.env.NODE_ENV !== "production"; 〜省略〜 const handle = app.getRequestHandler(); const SHOPIFY_API_SECRET = process.env.SHOPIFY_API_SECRET ?? "error"; // 変更 const SHOPIFY_API_KEY = process.env.SHOPIFY_API_KEY ?? "error"; // 変更 const SCOPES = process.env.SCOPES ?? "error"; // 変更 app.prepare().then(() => { 〜省略〜 async afterAuth(ctx) { //Auth token and shop available in session //Redirect to shop upon auth const shop = ctx.session?.shop; // 変更 ctx.cookies.set("shopOrigin", shop, { httpOnly: false, secure: true, sameSite: "none" }); ctx.redirect("/"); } 〜省略〜上記の必要最低限の修正のみで初期プロジェクトは動作するようになると思います。
エラーを回避する修正しかしていないので、適宜修正してください。まとめ
ここまで変更を加えたときのフォルダ構成は下記の通りになります。
starter-embedded-app ├── .dependabot │ └── config.yml ├── .editorconfig ├── .env ├── .env.example ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmrc ├── .prettierignore ├── .shopify-cli.yml ├── .stylelintignore ├── .stylelintrc.js ├── .travis.yml ├── LICENSE.md ├── README.md ├── next-env.d.ts ├── next.config.js ├── nodemon.json ├── package-lock.json ├── package.json ├── pages │ ├── _app.tsx │ └── index.tsx ├── server │ ├── handlers │ │ ├── client.js │ │ ├── index.js │ │ ├── mutations │ │ │ ├── get-one-time-url.js │ │ │ └── get-subscription-url.js │ │ └── register-webhooks.js │ ├── index.js │ └── server.ts ├── tsconfig.json └── tsconfig.server.json
あとは、チュートリアルに沿って機能を追加していけば、Typescriptでも開発できることが確認できると思います。
本記事のリポジトリは下記においてますので何かの参考になれば幸いです。
https://github.com/winuim/starter-embedded-app参考サイト
Shopify App CLI でアプリを開発する
TypeScript Next.js example
Custom server with TypeScript + Nodemon example
- 投稿日:2020-05-22T11:48:43+09:00
VercelでLINE BOTを動かす 2020年5月版
よく使う記事(↓)のソースコードを元にVercel(旧: now.sh)にLINE BOTをデプロイします。
ちなみに、Vercelはnow時代から仕様がちょくちょく変わる印象があるのであくまでも現時点版だと思った方が良さそうです。
事前準備: LINE BOTを作成し、ngrokで動作確認
参考記事のSTEP3のngrokでトンネリングさせるところまで進めます。
1. Vercelコマンドのインストール
$ npm i -g vercel既にインストールしている人はこの手順はスキップしましょう。
2. プロジェクトのファイル微修正
Vercelにデプロイするにあたりちょっとした修正を3箇所行います
2-1. server.jsをapiフォルダへ
プロジェクトのルート(package.jsonがある階層)に
api
という名前でフォルダを作成します。
api
フォルダ内に、もともLINE BOTで作成したserver.js
を移動させます。Vercel上ではapiフォルダ内に置いたプログラム(
.js
or.ts
)をNode.jsで実行する模様です。2-2. vercel.jsonを作成
プロジェクトのルート(package.jsonがある階層)に
vercel.json
という名前でファイルを作成します。vercel.json{ "version": 2, "routes": [ { "src": "/", "dest": "api/server.js" }, { "src": "/webhook", "dest": "api/server.js" } ] }2-3. server.jsを更新
server.js
の末尾を以下に変更します。server.js・ ・ (省略) ・ ・ // app.listen(PORT); // console.log(`Server running at ${PORT}`); (process.env.NOW_REGION) ? module.exports = app : app.listen(PORT); console.log(`Server running at ${PORT}`);3. デプロイ
あとはプロジェクトのルートでvercelコマンドを実行するだけです。デプロイ時に対話式に質問が来ますが全てエンターで進めます。
Vercelの利用が初めての場合のみログイン認証があります。
$ vercelデプロイが成功すると
https://<アプリ名>.now.sh
というURLが発行されます。この時点で、このURLにブラウザでアクセスし、
Hello LINE BOT!(GET)
の文字が表示されれば問題なくデプロイできています。4. LINE Developersの管理画面でWebhook URLを更新
LINE DevelopersのWebhook設定の管理画面から
https://<アプリ名>.now.sh/webhook
というURLを設定します。これで完成となります。
更新する際
デプロイし直す場合はvercelコマンドだけでデプロイ可能です。
$ vercelローカルでngrokで試す際はapiフォルダにserver.jsを移動させてあるので
$ node api/server.jsという実行の仕方に変えましょう。
所感 now時代と違うところなど
割と軽微な変更でデプロイできました。一回感覚を掴むと問題ないですが、初見だとちょっと戸惑う人いるかもなぁという印象です。
vercel.jsonは基本的にはnow.jsonと同じような書き方でしたが、buldsが非推奨っぽくなってたり、apiフォルダに入れると認識されるなど微妙に変わってるところがありうまく行くまでなんどかやり直しが発生しました。
今回はもともとローカル起動させるnode.jsプログラムの記述をあまり変えずにVercelにデプロイするやり方ですが、Vercelのドキュメント的にはapiフォルダにhoge.jsを設置すると
/api/hoge
という形でアクセスできるようになるみたいですね。詳細はこの辺を見ると良さそうです。
- 投稿日:2020-05-22T09:32:28+09:00
systemctlってめちゃくちゃ便利なんだな...
nodeのアプリをforeverでデーモン化しようと思っていたところ、そもそもsystemctl使えば必要なかったという話です。
前提
- ts-nodeのexpressアプリをデーモン化したい
- サーバー起動時にも起動したい
- AWSのEC2
systemctlの設定を書く
systemctlは昔のserviceコマンドに替わるものですがだいぶ便利になっています。
昔はinit.dにややこしい起動スクリプトを書く必要がありましたが今では、
/usr/lib/systemd/system/foo.service[Unit] Description=foo [Service] Type=simple ExecStart="/home/ec2-user/repo/script/start.sh" [Install] WantedBy=multi-user.targetこれだけで
$ sudo systemctl enable foo $ sudo systemctl start foo $ sudo systemctl stop fooできます。
start.shには、普通にyarn startが書かれています。
もちろんパスを通したりする必要はありますが。
こんな感じで書いてます。start.sh#!/bin/bash set -e cd /home/ec2-user/repo export PATH=/home/ec2-user/.nvm/versions/node/v14.3.0/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin:$PATH export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" /home/ec2-user/.nvm/versions/node/v14.3.0/bin/yarn start便利な世の中になりましたね。
どうでもいいけどserviceコマンドと違って
$ service foo start $ systemctl start foo逆なのがなかなか慣れない...