20200222のNode.jsに関する記事は8件です。

nodebrewでnodeをインストール

homebrewを使ってnodeをインストールする

brew install nodebrew

ちゃんと入ったか確認
nodebrew -v
セットアップ
nodebrew setup
pathを設定しろと言われるのでbash_profileに追加
export PATH=$HOME/.nodebrew/current/bin:$PATH

再読み込み
. ~/.bash_profile

nodeをインストール

利用可能な一覧
ls-remote
使用可能なバージョンがリストされるので好きなものをインストール(記載時点の最新)
nodebrew install-binary v13.9.0
ちゃんとあるか確認
nodebrew ls
v13.9.0が表示されればOK

nodebrew use v13.9.0
use v13.9.0 が表示される

node --version
v13.9.0が表示されればOK

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

5分で作れるWebAPIテストサーバー(自動デプロイも)

はじめに

5分で作れるかは分からない(笑)
WebAPIのテスト用のサーバーがほしいので作ってみた。
「node.js + Express + App Service(Azure)」 の構成で作ります。
レスポンス値を変更したときにデプロイするのは面倒くさいので、gitへのpushをキーにデプロイするようにします。

作ろうと思った経緯

ローカルテスト環境がなく、お客さんに許可を取らないと(他の会社さんが作っている)WebAPIを含む機能のテストができない。
許可申請から承認が下りるまでに1週間かかり、その間は待機しているらしい。
テスト用のダミーサーバーを作って試験を進められるようにしたい。

前提条件

  • nodeのインストール済(検証環境はnodistインストール済だった)
  • Azureのサブスクリプション、リソースグループは作成済

検証環境

  • Windows10
  • VSCode 1.42.1
  • nodist: 0.9.1
  • node: 10.15.3
  • npm: 6.9.0

とりあえずローカルで作ってみる

Azureのチュートリアルに沿って作成すればOK。
* クイック スタート: Node.js Web アプリを作成する | Microsoft Docs
以下からのコマンドは、VSCodeのターミナル(bash)で実施している。

てきとうなディレクトリを作成し、移動する

cd azure-app-service

expressプロジェクトの作成

コマンド

npx express-generator myExpressApp --view pug --git

実行結果

$ npx express-generator myExpressApp --view pug --git
npx: 10個のパッケージを20.703秒でインストールしました。

   create : myExpressApp\
   create : myExpressApp\public\
   create : myExpressApp\public\javascripts\
   create : myExpressApp\public\images\
   create : myExpressApp\public\stylesheets\
   create : myExpressApp\public\stylesheets\style.css
   create : myExpressApp\routes\
   create : myExpressApp\routes\index.js
   create : myExpressApp\routes\users.js
   create : myExpressApp\views\
   create : myExpressApp\views\error.pug
   create : myExpressApp\views\index.pug
   create : myExpressApp\views\layout.pug
   create : myExpressApp\.gitignore
   create : myExpressApp\app.js
   create : myExpressApp\package.json
   create : myExpressApp\bin\
   create : myExpressApp\bin\www

   change directory:
     $ cd myExpressApp

   install dependencies:
     $ npm install

   run the app:
     $ DEBUG=myexpressapp:* npm start

npmインストール

コマンド

cd myExpressApp
npm install

実行結果

$ npm install
npm WARN deprecated core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
npm WARN lifecycle The node binary used for scripts is C:\Program Files (x86)\Nodist\bin\node.exe but npm is using C:\Program Files (x86)\Nodist\v-x64\10.15.3\node.exe itself. Use the `--scripts-prepend-node-path` option to include the path for the node binary npm was executed 
with.

> core-js@2.6.11 postinstall C:\workspace\azure-app-service\myExpressApp\node_modules\core-js
> node -e "try{require('./postinstall')}catch(e){}"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: 
> https://opencollective.com/core-js 
> https://www.patreon.com/zloirock 

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)

npm notice created a lockfile as package-lock.json. You should commit this file.
added 118 packages from 174 contributors and audited 247 packages in 18.009s
found 1 low severity vulnerability
  run `npm audit fix` to fix them, or `npm audit` for details

サーバー起動

ここまでexpressプロジェクトができているので、サーバーが起動できる。

コマンド

npm start

実行結果

$ npm start
npm WARN lifecycle The node binary used for scripts is C:\Program Files (x86)\Nodist\bin\node.exe but npm is using C:\Program Files (x86)\Nodist\v-x64\10.15.3\node.exe itself. Use the `--scripts-prepend-node-path` option to include the path for the node binary npm was executed 
with.

> myexpressapp@0.0.0 start C:\workspace\azure-app-service\myExpressApp
> node ./bin/www


ブラウザで確認

ブラウザで localhost:3000 にアクセス。

001.png

動いているのが確認できた。

AzureでAppServiceを作成する

AppServiceを作成する

AzurePortalを開く。

追加をクリック。

002.png

サービスの設定

各項目を入力する。

003.png

  • サブスクリプション:事前に用意したもの
  • リソースグループ:事前に用意したもの
  • 名前:任意。ここの入力名がURLの1部になる
  • ランタイムスタック:今回はnodeを使うので、最新の「Node 12 LTS」にした
  • 地域:とりあえず東日本
  • SKUとサイズ:初期値はいい感じのスペックのものにされているので、1番安価な「F1」に変更

入力したら「確認および作成」を押下 → 確認画面に遷移するのでそのまま「作成」

問題なければ、デプロイが開始される。

1分くらいでデプロイが完了する。
004.png

自動デプロイの準備

githubでデプロイ用のリポジトリを作成する

自分は、「azure-app-service」を作成した。

ローカルにクローンする

任意の場所に先ほど作成したリポジトリをクローンする。

資材の移動

ローカルでの検証時に作成した「myExpressApp」の中身をリポジトリの直下にコピーする。

移動後のディレクトリ構成イメージ

006.png

動作確認

この状態で動くか確認する

npm start

して

localhost:3000

に接続してExpressの画面が出ればOK

コミット

動作が確認できたので、念のためこの状態でコミット→プッシュしておく。

Azureにデプロイする

「自動デプロイの準備」で作成したプロジェクトをVSCodeを開く。

拡張機能をインストール

Azure App Serviceを操作するための、拡張機能「Azure App Service」をインストールする。

インストールが完了すると左部のメニューに追加されるので選択する。
005.png

上部の「↑」を選択

上部の「↑」(Deplay To Web App...)を選択する。

  • Select the folder to zip and deploy: Expressプロジェクトのルートディレクトリを選択(azure-app-service)
  • Select subscription: AppServiceを作成したサブスクリプション
  • Select Web App: 作成したAppServiceを選択
    • 上書きしてよいか確認ダイアログが出るので、「OK」→「Deploy」

デプロイが始まるので、完了するまで待つ(10秒くらい)。

デプロイが完了したら実際に接続してみる

「https://<作成したAppService名>.azurewebsites.net/」にブラウザで接続

デプロイができていれば下記のようにローカルと同じ画面が出る。
007.png

これでデプロイはOK。

Azureに自動デプロイする

デプロイ設定を行う

AzurePortalで作成したAppServiceを開き、画面左部メニューから「デプロイセンター」を選択する。

008.png

デプロイ設定

  1. ソース管理:Githubを選択(初回は認証がかかるかも)
  2. ビルドプロバイダー:App Serviceのビルドサービス
  3. 構成:
    • 組織:自分のgithubアカウント
    • リポジトリ:作成したリポジトリ
    • ブランチ:master
  4. 概要:内容を確認して、完了を押下

デプロイ設定もこれで完了。

今後はmasterブランチにプッシュされたタイミングでビルドが走るようになる。

(参考)作業を行ったgithubリポジトリ

おわりに

今回はじめてwebサーバを作成したが、こんなにも簡単にできるんだという感想。
自分は今までプログラミングがメインでAzureを使ったり、サーバを構築したりという作業をしたことがなかった。
作ったものが自分のPC内だけで動いているのと、全世界からつながっているのはやっぱり感動が違う。
今回はテスト用のレスポンスサーバーが目的だったが、Webサービスも簡単に作れるようになっているのはすごいと思った。
Webサービスを公開する予定はないが、このように簡単に構築できることを知れて良かった。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

COTOHA アクセストークンの取得 (Node.js)

COTOHA API Portal の使用例です。

次と同じことを Node.js で行いました。

COTOHA アクセストークンの取得

access_token.js
#! /usr/bin/node
// ---------------------------------------------------------------
//
//  access_token.js
//
//                  Feb/22/2020
//
// ---------------------------------------------------------------
console.error ("*** 開始 ***")
const dotenv = require('dotenv')
var Client = require('node-rest-client').Client

dotenv.config()

var config = {
    client_id: `${process.env.CLIENT_ID}`,
    client_secret: `${process.env.CLIENT_SECRET}`,
    developer_api_base: `${process.env.DEVELOPER_API_BASE_URL}`,
    access_token_publish_url: `${process.env.ACCESS_TOKEN_PUBLISH_URL}`,
}

const data = {
    "grantType": "client_credentials",
    "clientId": config.client_id,
    "clientSecret": config.client_secret
    }

const url = config.access_token_publish_url

const headers={
    "Content-Type": "application/json"
    }

const args = {
    data: data,
    headers: headers
}

var client = new Client()

client.post(url, args, function (data, response) {
    console.log(data)
    console.error ("*** 終了 ***")
})

// ---------------------------------------------------------------

実行コマンド

export NODE_PATH=/usr/lib/node_modules
./access_token.js

使ったバージョン

$ node --version
v13.9.0
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【NestJS】@nestjs/configを使って環境変数を読み込む

やりたいこと

環境変数で設定した値をNestJSアプリ内で使う。

環境

@nestjs/configは、内部的にdotenvを使っています。
両方を使ってみて、環境変数の読み込みを一箇所で管理する場合は、dotenvそのものを使うほうが簡便だと感じました。ここでは、備忘録のため設定手順を残しておきます。

dotenvを使う場合の手順はこちら

インストール

yarn add @nestjs/config

// or

npm install @nestjs/config

使い方

まずsrc/app.module.tsで読みこみます。

src/app.module.ts
import { ConfigModule } from '@nestjs/config' // この行と
:
@Module({
  imports: [ConfigModule.forRoot()],          // この行を追加
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

global moduleとして読み込む場合は、{ isGlobal: true }を渡します。

src/app.module.ts
  imports: [ConfigModule.forRoot({ isGlobal: true })],

実際に環境変数を使いたい場所でconfig.getを使って読み込みます

src/foo/foo.service.ts
import { ConfigService } from '@nestjs/config'

@Injectable()
export class Foo {
  constructor(
    private readonly config: ConfigService,
  ) {
    const val = this.config.get('SOME_VALUE')

isGlobal: true を設定している場合は以上ですが、設定していない場合は対応するmoduleでinjectします。

src/foo/foo.module.ts
import { ConfigModule, ConfigService } from '@nestjs/config' // ここと

@Module({
  imports: [FooModule, ConfigModule],                        // ここと
  controllers: [FooController],
  providers: [FooService, FooInvoker, ConfigService],        // ここ

ドキュメント

https://docs.nestjs.com/techniques/configuration

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【NestJS】dotenvを使って環境変数を読み込む

やりたいこと

環境変数で設定した値をNestJSアプリ内で使う。

環境

NestJS用に、内部的にdotenvを使っている@nestjs/configもありますが、dotenvそのものを使うほうが簡便だと思っています。

@nestjs/configを使う場合の手順はこちら。

インストール

yarn add dotenv

// or

npm install dotenv

設定

ここでは、アプリ内で統一して環境変数を読み込む場所として、src/config/app.config.tsを想定しています。

src/config/app.config.ts
require('dotenv').config()

if (!process.env.DB_PASSWORD) {
  throw new Error('DB_PASSWORD must be set.')
}

export const DB_PASSWORD = process.env.DB_PASSWORD
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CLIP STUDIO PAINTのファイルからNode.jsでサムネイル画像を出力する

CLIP STUDIO PAINTファイル(.clip)のサムネイル画像をNode.js上で出力してみました。

CLIPSTUDIO PAINTのファイルからサムネイル画像を取得

CLIP STUDIO PAINTで作成した漫画データのサムネール出力の為の調査

こちらの記事のように、Pythonやシェル、Goで実装されたライブラリ等はあったものの、JavaScript(TypeScript)で実装されたものが無かったので調べてみました。

概要

  • clipファイルからSQLite部分のデータを切り出し
  • 切り出したSQLiteファイルからサムネイル画像のデータを抽出

次節から実装になりますが、ファイルの読み書きにfs.readFileSync/writeFileSyncを使用しています。
また、単なる出力テストなので、実装する場合はfs.readFile/writeFileの使用及び適宜例外処理をお願いします。

コード

とりあえず全体像。TypeScriptで記述しています。
外部モジュールとしてsqlite3をインストールしてください。

$ npm i sqlite3
import * as fs from "fs"
import * as sqlite3 from "sqlite3"

// .clipファイルパス
const path = "../sample_asset/illust1"
const clipPath = path + ".clip"
// Bufferの読み込み
const clipBuffer = fs.readFileSync(clipPath)

// SQLiteのデータは「SQLite format 3」から始まるらしい
const searchText = "SQLite format 3"
// Uint8Arrayに変換
const uint8Array = new Uint8Array(Buffer.from(searchText))

// clipからSQLiteのデータのスタート位置を取得
const findIndex = clipBuffer.indexOf(uint8Array)

// SQLite部分のみ切り出し
const dbBuf = clipBuffer.slice(findIndex, clipBuffer.length)

// 一時書き出し用のSQLiteファイルパス
const dbPath = path + ".sqlite"
// いったんsqliteファイルに書き出し
fs.writeFileSync(dbPath, dbBuf)

// sqlite3モジュールでSQLiteファイルを展開
const db = new sqlite3.Database(dbPath)
db.serialize(() => {
  // CanvasPreviewテーブルからImageData(png)を抽出
  db.all("SELECT ImageData FROM CanvasPreview", (err, row) => {
    if (err) {
      console.log(err)
      return
    }

    if (row[0].length > 0) {
      // png出力パス
      const binaryPath = path + ".png"
      // rowのImageDataプロパティからpngを生成
      fs.writeFileSync(binaryPath, row[0].ImageData)
    }
  })
})

解説

clipファイルの読み込み

// .clipファイルパス
const path = "..\\sample_asset\\illust1"
const clipPath = path + ".clip"
// Bufferの読み込み
const clipBuffer = fs.readFileSync(clipPath)

fs.readFileSyncでclipファイルの読み込みを行う。
fs.readFileSyncBufferを返す。

SQLiteのデータの位置を探索

clipファイルは何らかのメタデータ+SQLiteで構成されているらしく、
そのままでは下記のとおりSQLiteとして展開できない。

// PowerShellで確認
$ C:\...> sqlite3 illust1.clip
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.

// テーブルリストを出力
$ sqlite> .table
Error: file is not a database

そこで、SQLiteのデータだけ切り出してやる必要がある。
噂によるとSQLiteのデータは「SQLite format 3」から始まるらしい。

// SQLiteのデータは「SQLite format 3」から始まるらしい
const searchText = "SQLite format 3"
// Uint8Arrayに変換
const unit8Array = new Uint8Array(Buffer.from(searchText))

// clipからSQLiteのデータのスタート位置を取得
const findIndex = clipBuffer.indexOf(uint8Array)

// SQLite部分のみ切り出し
const dbBuf = clipBuffer.slice(findIndex, clipBuffer.length)

// 一時書き出し用のSQLiteファイルパス
const dbPath = path + ".sqlite"
// いったんsqliteファイルに書き出し
fs.writeFileSync(dbPath, dbBuf)

Buffer#indexOfにて、SQLiteのインデックスを取得する。
インデックスが分かったら、そこから終点までsliceしてやる。

取得したバッファをfs.writeFileSyncでSQLiteファイルとして書き出し。

SQLiteの展開とpngの書き出し

SQLiteファイルのテーブルは次のようになっており、
CanvasPreviewテーブルにプレビュー画像のデータが保持されている。

// PowerShellで確認
$ C\...> sqlite3 illust1.sqlite //←上で生成したやつ
$ sqlite3> .table
AnimationCutBank            Layer
Canvas                      LayerThumbnail
CanvasItem                  Mipmap
CanvasItemBank              MipmapInfo
CanvasPreview               Offscreen
ElemScheme                  ParamScheme
ExternalChunk               Project
ExternalTableAndColumnName  RemovedExternal

sqlite3モジュールにより、先ほど生成したSQLiteファイルを展開する。

// sqlite3モジュールでSQLiteファイルを展開
const db = new sqlite3.Database(dbPath)
db.serialize(() => {
  // CanvasPreviewテーブルからImageData(png)を抽出
  db.all("select ImageData from CanvasPreview", (err, row) => {
    if (err) {
      console.log(err)
      return
    }

    if (row.length > 0) {
      // png出力パス
      const binaryPath = path + ".png"
      // row[0].ImageDataプロパティからpngを生成
      fs.writeFileSync(binaryPath, row[0].ImageData)
    }
  })
})

クエリにてCanvasPreviewからImageDataを取得する。
このとき出力結果のrowには、次の形でデータが格納されている。

{ ImageData:
   <Buffer 89 50 4e 47 0d 0a ... >}

つまり、row[0].ImageDataで目的のサムネイル画像のデータを取得することが可能。
最後に、fs.writeFileSyncによりillust1.pngrow.ImageDataを書き出してやれば終了である。

参考

CLIP STUDIO PAINTで作成した漫画データのサムネール出力の為の調査

CLIPSTUDIO PAINTのファイルからサムネイル画像を取得

CLIP STUDIO PAINTの.lipファイルをハックして作業動画を書き出すWindowsアプリを作った

Node.js で TextEncoder や SHA512 を作る

MDN - オブジェクトでの作業

Node.js で SQLite を扱う

Writing to Files in Node.js

Get list of tables from SQLite in Node.js

主にPowerShell関係

MS - certutil

Windows10でバイナリ<->HEXテキスト変換

PowerShellからデータを出力するパターンまとめ

cutコマンドについてまとめました 【Linuxコマンド集】

Windows PowerShell : UNIXの cut コマンド相当の作業をする。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

puppeteerでThis relative module was not found: ~ ws ~ WebSocketTransport.js

環境

・windows10
・vue-cli3
・electron-builder

現象

electronでpuppeteerを使おうとした。
npm run electron:serveしたら、

This dependency was not found:

* ws in ./node_modules/puppeteer/lib/WebSocketTransport.js

To install it, you can run: npm install --save ws

対応

To install it, you can run: npm install --save ws

とあるので言われたとおりにコマンドを打つ。
で、再度build。
しかし、同じエラーが…。

解決策

node_modules/puppeteer/lib/WebSocketTransport.jsをいじる。

const WebSocket = require('ws');

const WebSocket = require('../node_modules/ws');

に修正する。(wsをnpm installした後に)

備考

issueはこちら
https://github.com/puppeteer/puppeteer/issues/3487

自分の環境ではこの方法で助かったが、リンク先は割と紛糾しているみたい?
この分野(electron+αの開発)は日本語の参考記事も少ないので、じぶんみたいなぺーぺーだとわりと簡単なところで結構つまづく。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

npmコマンドで順番を無視した引数を使う方法

npmコマンドを書いている中で、オプションをprocess.argv[2]と取りますが、
これの順番を決め打ちで取りに行かない方法を探した結果、argvを使うことにしました。

前提条件

  • npmがインストールされていること
  • package.jsonがあること

インストール

$ npm install -D argv

使い方

ファイル作成

touchコマンドでファイルを作成します。

$ touch test.js option.json

test.js

argvモジュールの読み込みと、option.jsonの読み込み、
argvのメソッドで引数のデータを取り込みます。

const argv = require('argv')
const option = require('./option')
const args = argv.option(option).run()

console.log(args)

option.json

引数で使うための名前と型、を設定するオブジェクトを設定します。
配列になっているため、必要な数だけオプションを増やすことが可能です。

[
  {
    "name": "option",
    "short": "o",
    "type": "string",
    "description": "あなたのスクリプトのオプションを定義します",
    "example": "'script --option=value' or 'script -o value'"
  }
]

package.json

npm run testコマンドでtest.jsを動かすように定義します。
オプションの設定をされていない引数は配列でtargetsとして記録されます。

{
  "scripts": {
    "test": "node test sample -o aaa"
  }
}

実行

npmコマンドを実行します。

$ npm run test

出力結果

{ targets: [ ‘sample’ ], options: { option: 'aaa' } }

オブジェクト形式でデータが取れているので、特定の値を取るときは、
args.options.optionという形式でaaaと取ることができます。

参考文献

この記事は以下の情報を参考にして執筆しました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む