20201104のNode.jsに関する記事は5件です。

WSL、Zsh、VSCode、Docker、NodeJS セットアップまとめ in 2020

はじめに

新しいSurfaceをもらったので、せっかくだからWSLを試したいと思います。
まとめだけなので、調べる手間を省きたい方向けです。

WSL、WSL2のインストール

Docker Desktop WSL 2 backendを使うためにWSL2が必要なので、最初からWSL2にアップグレードした方がいいと思います。

公式マニュアル(日本語)

すでにWSL1のディストリビューションを持っている方は同じドキュメントでアップグレード方法も記載されています

Zsh

Linux上の手順と同じ。
WSLを開き、ZSHをインストールします。
(PowerShellなどでwslを入力すれば開きます)

sudo apt update
sudo apt install zsh

oh-my-zsh & autosuggestion(自動補完)

Oh-my-zsh

sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

zsh-autosuggestion

git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

Vimなどのテキストエディターで~/.zshrcを開き、ファイル内で以下を追加:

source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh

Zshをリロード:

source ~/.zshrc

VSCode

大体VSCodeをインストールするだけで動きます。
公式マニュアル(日本語)
WSLためのExtension

自分は以下の方法でDefault ShellをZSHにしたのですが、必要かどうかはわかりません:
VSCodeで Ctrl+ Shift + P → "Select Default Shell" を入力 → WSL(ZSH)を選択

NodeJS

LinuxでNodeJSをインストールのと同じ手順です。
NVMを使ってインストールします。

nvm

インストール

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash

以下を~/.zshrcに追加:

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

Zshをリロード:

source ~/.zshrc

NodeJS

WSLを開きます。
特定バージョンをインストール

nvm install x.x.x

or 最新版

nvm install node

Docker (Docker Desktop WSL 2 backend)

要件は前述のWSL、WSL2のマニュアルに従えば満たしてるはずなので、
最新版のインストーラーをダウンロード、インストール途中でWSL2のチェックボックスを入れるだけで完成。

公式マニュアル (英語)(見なくてもおk)

もしWSLでdockerを入力すると以下のエラーが出てくると:

The command 'docker' could not be found in this WSL 2 distro.
We recommend to activate the WSL integration in Docker Desktop settings.

See https://docs.docker.com/docker-for-windows/wsl/ for details.

WindowsでDocker Desktopを起動していないか、もしくは自分のLinux DistributionのWSLバージョンをチェックしてください、WSL2じゃないと動きません。

確認とアップグレード方法

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

npm 最新版 インストール 方法

最新のnpmを簡単にインストールする方法伝授してゆく!!!

n packageとかいうのを使う!

sudo apt-get update
sudo apt-get install nodejs
sudo apt-get install npm

次にキャッシュをクリアしてから、n packageを導入する

sudo npm cache clean
sudo npm install n -g

最新版(安定してるverとるよー)

sudo n stable
パス通す
sudo ln -sf /usr/local/bin/node /usr/bin/node

これからはn packageで管理するための最初に入れたnodeは使わないから消しておく!

sudo apt-get purge -y nodejs npm

バージョン確認

npm-v
node-v

このサイトにあるNode.jsのversionとnpmのバージョンが"Fermium"のやつになってれば成功!
https://nodejs.org/ja/download/releases/

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

JavaScript 特定桁の0と1で表すことができる全ての組み合わせを求める関数

やりたいこと

例: 引数1に3を渡すと3ビットで表せれるすべての組み合わせを出力する。
たまに使用するので、個人的なメモ(誰かの役に立つと嬉しい)

出力例

[
  [ '0', '0', '0' ],
  [ '0', '0', '1' ],
  [ '0', '1', '0' ],
  [ '0', '1', '1' ],
  [ '1', '0', '0' ],
  [ '1', '0', '1' ],
  [ '1', '1', '0' ],
  [ '1', '1', '1' ]
]

コード

const getAllBit = (len) => {
  //すべての組み合わせの個数
  const end = Math.pow(2, len) - 1

  let result = []
  for (let i = 0; i <= end; i++) {
    //toStringの引数に2を渡すことで2進数表記にする
    //len分だけ0うめ
    const bit = i.toString(2).padStart(len, '0')
    result.push(bit.split(''))
  }

  return result
}

console.log(getAllBit(5))

追記: コメント欄でご指摘があった、再利用しない関数をなくし一つの関数でまとめました。

実行例

引数に5を渡した場合(上記のコードと同じ)

[
  [ '0', '0', '0', '0', '0' ],
  [ '0', '0', '0', '0', '1' ],
  [ '0', '0', '0', '1', '0' ],
  [ '0', '0', '0', '1', '1' ],
  [ '0', '0', '1', '0', '0' ],
  [ '0', '0', '1', '0', '1' ],
  [ '0', '0', '1', '1', '0' ],
  [ '0', '0', '1', '1', '1' ],
  [ '0', '1', '0', '0', '0' ],
  [ '0', '1', '0', '0', '1' ],
  [ '0', '1', '0', '1', '0' ],
  [ '0', '1', '0', '1', '1' ],
  [ '0', '1', '1', '0', '0' ],
  [ '0', '1', '1', '0', '1' ],
  [ '0', '1', '1', '1', '0' ],
  [ '0', '1', '1', '1', '1' ],
  [ '1', '0', '0', '0', '0' ],
  [ '1', '0', '0', '0', '1' ],
  [ '1', '0', '0', '1', '0' ],
  [ '1', '0', '0', '1', '1' ],
  [ '1', '0', '1', '0', '0' ],
  [ '1', '0', '1', '0', '1' ],
  [ '1', '0', '1', '1', '0' ],
  [ '1', '0', '1', '1', '1' ],
  [ '1', '1', '0', '0', '0' ],
  [ '1', '1', '0', '0', '1' ],
  [ '1', '1', '0', '1', '0' ],
  [ '1', '1', '0', '1', '1' ],
  [ '1', '1', '1', '0', '0' ],
  [ '1', '1', '1', '0', '1' ],
  [ '1', '1', '1', '1', '0' ],
  [ '1', '1', '1', '1', '1' ]
]

5ビットで表すことができるすべての組み合わせが出力できてます。

参考にした記事

js 与えられた整数を二進数で返す

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

MarkdownをGitHubに上げるだけでブログを公開できる仕組みをサクッと作ってみた

世の中には便利なCMSプロダクトがたくさんありますが、ぶっちゃけエンジニアだったらWeb上のフォームでコンテンツを入力するより、ローカルでMarkdownを作ってサクッとGitHubにPushするだけでブログ公開できたほうが楽だなーと思ったので作ってみました。

できるようになること

下記のようなインデックスページとブログページをMarkdownを作るだけで生成できるようになります。

画面収録 2020-10-17 12.48.55.mov.gif

ブログ公開の手順は下記の通りでとても簡単です。

  1. Markdownでブログを書く
  2. インデックスページを自動生成する
  3. GitHubにPushして自動デプロイ

実装

それでは実装していきます。

主要パッケージのバージョン

この記事を書いている時点の主要パッケージのバージョンは下記の通り。
以降は下記のパッケージが入っている前提で説明します。

package.json
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-markdown": "^4.3.1",
    "react-router-dom": "^5.1.2",
    "react-scripts": "3.4.3",
    "styled-components": "^5.2.0",
    "typescript": "^4.0.3",
    "@material-ui/core": "^4.9.11",
    "@material-ui/icons": "^4.9.1",

今回の肝となっているMarkdownからwebページを生成する処理はreact-markdownを使っています。
https://github.com/rexxars/react-markdown

Webサイトの準備

今回はReactを使ってWebサイトを作成します。
サイトの公開にはVercelを使っています。

Vercelを使ってReactで作ったアプリケーションを公開する方法は公式ドキュメントに載っているのでそちらを参照してください。
Githubと連携してしまえばPushするだけでデプロイされるのでものすごく簡単ですよ。
https://vercel.com/guides/deploying-react-with-vercel-cra

create-react-appで作ったwebサイトからサンプルコードを漏れなく消す』という記事でWebサイトをReactで作って最低限の状態まで作る手順を書いているのでそちらも見ていただけると嬉しいです。

ブログページの構成

/blogsでブログページへのインデックスを表示するページを作ります。
ブログページのURLは/blogs/:titleとします。:titleのところがブログごとに変動します。

これに合わせてrouterを作ります。

src/pages/index.tsx
// ※routerの箇所のみ抜粋しています
const Blogs = lazy(() => import('./Blogs'));

<Switch>
  <Route path="/blogs" component={Blogs} />
</Switch>
src/pages/Blogs/index.tsx
import React from 'react';
import { Route, Switch, Link } from 'react-router-dom';
import { List, ListItem, ListItemText } from '@material-ui/core';
import Blog from './Blog';
// data.jsonは後ほど紹介するバッチで自動生成しているjsonファイル
// ブログのインデックス情報を定義しています
import mds from './data.json';

export default () => {
  // react-markdownの機能を使ってmarkdownからページを生成
  const blogs = mds.map((md) => (
    <Route key={md} path={`/blogs/${md}`}>
      <Blog mdPath={`/mds/${md}.md`} />
    </Route>
  ));
  // mdsを基にブログページへのリンクを生成
  const index = mds.map((md) => (
    <ListItem button component={Link} to={`/blogs/${md}`}>
      <ListItemText primary={md} />
    </ListItem>
  ));
  return (
    <Switch>
      {blogs}
      <Route>
        <List component="nav" aria-label="secondary mailbox folders">
          {index}
        </List>
      </Route>
    </Switch>
  );
};

ブログページを作成

Markdownはpublic/mds/配下に格納することにしました。
とりあえずサンプルとしてfirst.mdとsecond.mdをMarkdown形式で作りました。

public/mds/first.md
# first blog

初めてのブログ
public/mds/second.md
# second blog

2 つめのブログ

json自動更新

public/mds/配下のファイルを読み込み、インデックスページの情報源data.jsonを自動生成するバッチを作りました。

updateBlogIndex.js
const fs = require('fs');

fs.readdir('./public/mds/', (err, files) => {
  if (err) throw err;
  const convertedFiles = files.map((file) => (
    file.replace(/\.md$/, '')
  ));
  console.log(convertedFiles);

  const j = JSON.stringify(convertedFiles.reverse());
  console.log(j);
  fs.writeFileSync('./src/pages/Blogs/data.json', j);
});

上記を実行すると下記のようなjsonファイルがブログタイトル(ファイル名)の配列が書かれたjsonが生成されます。

src/pages/Blogs/data.json
["second","first"]

本番環境へデプロイ

これで実装は完了です。
かなり簡単ですよね。むしろ下手にCMS導入するより簡単です!!(もちろんCMSはもっと多機能ですがw

ブログ公開

最初に書いた通り下記の3つの手順でできます。

Markdownでブログを書く

public/mds/にmarkdown形式でブログを書きます。
現在の仕様だとファイル名がタイトルになります。

インデックスページを自動生成する

updateBlogIndex.jsを実行してインデックスページを生成します。

GitHubにPushして自動デプロイ

Vercelを使っているのでGithubの特定のブランチにPushすると自動デプロイされます。

今後やりたいこと

とりあえずMarkdownを作るだけでブログを公開するという最低限の仕組みは作れましたが、まだCMSとしては弱すぎるので下記は実装したいと思っています。

インデックス生成バッチを手動実行するのが面倒

手動実行とはえてして忘れるものです。
CIなどで自動実行させるようにして忘れないようにするべきです。

インデックスのページネーション

今は1つのページにすべてのインデックスが表示されてしまうので、ブログ数が大量に増えたら破綻します。
ページネーションさせるなどを考える必要があります。

ブログの管理方法を考える

今は名前の降順にインデックスが作成されます。
ファイルの命名規則を決めて日付をいれるなどをすれば今の仕様でも管理できるかも知れませんが、別途投稿日などを持つようにして管理しやすいようにしたい。
また、public/mds/直下に格納しているが投稿日などでディレクトリ階層を作ったほうが管理しやすくなりそう。

ブログページに投稿日を入れたい

ブログはいつ投稿されたかという情報が大事なので、ブログページに投稿日を入れるようにしたい。
ブログのファイル名などに投稿日を持たせるようにして、jsonを生成するときに日付情報を持たせるようにするなど方法を検討したい。

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

Azure FunctionsのNodeでSQL Serverから値を取得したメモ

概要

AzureのFunctionsでNodeを利用したSQL Serverへの接続をしたメモ。
async awaitを使ってConnectionをとれるようにした。
ORMapperを自前で作ってみた。
自動でやってくれるライブラリも探せばありそうだなー。

この時点のソース

ソース

models/db.ts
import {Connection,Request, TYPES } from 'tedious'

let connectionInstance = null;
export const getConnection = () => new Promise<Connection>(async (resolve, reject)=>{
  if(connectionInstance) {
    resolve(connectionInstance)
  }
  try {
    connectionInstance = await createConnection()
    resolve(connectionInstance)  
  } catch (err) {
    reject(err)
  }
})

const createConnection = ()=> new Promise<Connection>((resolve, reject)=>{
  const config = {
    server: process.env["SQLConnectionServer"],
    authentication: {
        type: 'default',
        options: {
            userName: process.env["SQLConnectionUserName"],
            password: process.env["SQLConnectionUserPassword"],
        }
    },
    options: {
        database: process.env["SQLConnectionDatabase"],
        rowCollectionOnDone: true, // Requestの第二引数のrowsに値を入れるために必要
        rowCollectionOnRequestCompletion: true,  // Requestの第二引数のrowsに値を入れるために必要
    }
  }
  const connection = new Connection(config);
  connection.on('connect', function(err) {  
    if (err) {
      reject(err)
      return
    }  
    resolve(connection)
  });
})

/**
 * レコードをオブジェクトにして返す
 * @param columns レコード1行
 */
const formatORMapping = <T>(columns: any[]) => {
  const ret = {} as T
  columns.forEach(col=>{
    console.log(col)
    ret[col.metadata.colName] = col.value
  })
  return ret
}
export const read = <T>(connection: Connection, query: string) => new Promise<T[]>((resolve, reject) =>{
  const request = new Request(query, (err, rowCount, rows) => {
    if (err) {
        reject(err);
        return;
    }
    console.log(rowCount + ' row(s) returned');
    resolve(rows.map<T>(formatORMapping))
  });

  connection.execSql(request);
})
models/users.ts
import * as db from './db';
interface User {
  UserID: number
  Name: string
}
export const select = async ()=>{
  const connection = await db.getConnection();
  const query = "select * from Users";
  return await db.read<User[]>(connection, query)
}
index.ts
import { AzureFunction, Context, HttpRequest } from "@azure/functions"
import * as users from './models/users';

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    const responseMessage = await users.select();
    context.res = {
        body: responseMessage
    };
};
export default httpTrigger;

参考

Azure Functions から SQLServerに接続する(node.js編)
クイック スタート:Node.js を使用して Azure SQL Database または Azure SQL Managed Instance 内のデータベースに対してクエリを実行する
Get started with SQL Server
Tedious API
Win10 + node.js から SQL Server 2019 Express に CSVファイルを書き込んでみる 修正版(tedious-connection-pool)

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