20200712のNode.jsに関する記事は6件です。

Node.jsまとめ

1. はじめに

Node.jsと、それを取り巻く環境。リリースから今日に至るまでの歴史や、現場での使われ方など――調べられるだけ調べましたので、ここに備忘録として残します。

※ 2020/07/13
誤字・脱字を修正。

2. Node.jsとは?

Node.jsはC++で書かれた JavaScriptの実行環境 です。 ECMAScriptCommonJS のような規格・仕様の名称ではなく、 jQueryReact.jsVue.jsAngularJS といったライブラリやフレームワークの名前でもなく、JavaScriptのソースファイルを受け取って、書いてあるコードの通りに処理を行ってくれるアプリです。

具体的には、以下のように動作します。

test.js
console.log(1);
console.log("2");
console.log("3 knock out!");
コンソール
C:\Users\AGadget> node .\test.js
1
2
3 knock out!

C:\Users\AGadget>

2-1. 誕生秘話

最初のバージョンである v0.0.1 がリリースされたのは2009年5月27日のことです。Node.jsの生みの親 Ryan Dahl 氏は、当時最も人気があったWebサーバーアプリ Apache HTTP Server が抱える C10K問題 に対する批判とともに当アプリを開発・発表しました。

C10K問題とは、サーバーへの 同時接続数 が1万台を超えるほどになると、ハードウェアのスペックに余裕があっても、サーバーがパンクしやすくなるという現象のことです。重ねて触れておきますが、同時接続数が1万台を超えたら必ず発生するというわけではなく、ここでいう1万台というのはあくまで目安であり、大量接続数を表す比喩表現です。

具体的には、CPUの性能には概ね余裕があるものの、メモリが不足したり、プロセスIDが不足したり、ファイルディスクリプタが不足したりするためにサーバーとして機能しなくなるそうです。これは先のApache HTTP Serverで採用されているリクエストの処理方法が、大量の同時接続を捌くのに不向きであるために生じるものでした(向き不向きの話であり、Apache HTTP Serverは優秀なWebサーバーアプリです)。

この厄介なC10K問題に対応できるWebサーバーを構築する プラットフォーム として、Node.jsは誕生しました(Node.js自体はWebサーバーではない)。もちろん、実際に使ったことがある人なら分かるように、Node.jsを使ってWebサーバーを立てることは容易です。ただ、それはJavaScriptで書かれたWebサーバーを立てるためのライブラリをNode.js側から呼び出しているのであって、やはりNode.jsはWebサーバーではありません。

2-2. 需要

Node.jsの需要――現場での使われ方ですが、後述する npm (Node Package Manager) を利用して、Web開発に役立つライブラリやフレームワークの導入・管理に用いられるのが、まずあるかと思います。実際私もお世話になっています。

次に、Webサーバーアプリ(Apache HTTP Serverや Nginx など)から呼び出されるAPIサーバーのポジションにNode.jsが採用されることがあるようです。また、そこから Go などで書かれたプログラムに処理を振り分けたりするのに使われるとか(Webサーバー ⇔ Node.js ⇔ Goみたいな)。

その反面、WebサーバーをNode.jsで立てるというのは一般的ではないようです。現実問題として、Webサーバーに要求される性能・機能等に対して、Node.jsでは色々と不足しているため、そこはちゃんとしたWebサーバーアプリのほうが使われるそうです。

3. npmとは?

npm (Node Package Manager) はJavaScriptで書かれた、Node.js標準の パッケージマネージャー です。 純利益率の略称ではありません。 開発者は Isaac Z. Schlueter 氏。リリースされたのは2010年1月12日。Node.jsがリリースされてから、およそ8ヶ月後のことでした。

パッケージマネージャーとは呼んで字の如く、 パッケージ を管理するためのアプリのことです。ざっくりと表現するならば パッケージと呼称されるプログラム群を超簡単にインストールしたりするためのアプリ ということになろうかと思います。

3-1. パッケージとは?

パッケージ( モジュールプロジェクト などと呼ばれることも)は、ツール・ライブラリ・フレームワークなどの 再利用可能なコード をNode.jsが制定した規格に準じるかたちでまとめたファイル群およびディレクトリのことです。

こう書くと何やら難解な代物に思えてきますが、Node.jsが定めたルールに基づいて、ディレクトリにソースコードを突っ込めば、それだけでモジュールになります。ルールというのは、例えば、パッケージのメタ情報をまとめた package.json というファイルを、パッケージとなるディレクトリのなかに配置する必要がある、といったものです。

3-2. package.json

package.jsonはnpmに対応したパッケージを構築するのに必要となる設定ファイルの名前です。

npmはこのファイルが配置されているディレクトリをパッケージとして認識します。

ところで、このpackage.jsonというファイル名ですが、これを別の名前に変えることはできません。例えば manifest.json とか settings.json といったようにです。また package.inipackage.csv など、ファイル形式を変更してもいけませんので注意してください。

4. Node.jsの操作

Windows 10 64bit版でのNode.jsの操作方法を説明します。

Node.jsを使用するには node.exe を呼び出します。Node.jsのインストール時に、インストールパスを初期設定から変更していないならば C:\Program Files\nodejs\node.exe にあるはずです。

コマンドの文法は以下の通りです。

C:\Users\AGadget> node [オプション] [スクリプトパス] [スクリプトに渡す引数]

具体的には、このような感じで使います。以下例ではgift-kibidango.jsというスクリプトに、3つの文字列を引数として渡して実行させています。

C:\Users\AGadget> node .\gift-kibidango.js "Falcon" "Tiger" "Locust"

4-1. ヘルプを表示する

node.exeのコマンドの一覧や、その使い方を確認するには -hオプション--helpオプション を指定します。

C:\Users\AGadget> node -h

C:\Users\AGadget> node --help

4-2. Node.jsのバージョンを確認する

インストールされているNode.jsのバージョンを確認するには -vオプション--versionオプション を指定します。

C:\Users\AGadget> node -v

C:\Users\AGadget> node --version

5. npmの操作

Windows 10 64bit版でのnpmの操作方法を説明します。npmの文法は概ね以下の通りです。

C:\Users\AGadget> npm [コマンド] [コマンドを制御する引数]

ところで、npmのコマンドには フリーダム過ぎる きらいがあることを、頭の片隅にでも置いておいてください。例えば、以下コマンドは全て同じ結果を表してしまいます。

C:\Users\AGadget> npm version -v

C:\Users\AGadget> npm version --v

C:\Users\AGadget> npm version -version

C:\Users\AGadget> npm version --version

C:\Users\AGadget> npm -v

C:\Users\AGadget> npm --v

C:\Users\AGadget> npm -version

C:\Users\AGadget> npm --version

C:\Users\AGadget> npm -v version --version

このようにフリーダムすぎると、どういった書き方が正しいのか分からなくなってきます。そのため当記事では以下ページに掲載されている書き方を参考に、ある程度統一感を持たせた書き方を掲載します。

CLI documentation | npm Documentation

5-1. npmのバージョンを確認する

インストールされているnpmのバージョンを知りたいときは versionコマンド を使用してください。

C:\Users\AGadget> npm version

versionコマンド単体で実行すると、npmのバージョンに加え、その他よくわからない要素のバージョンをまとめて取得することができます。

npmのバージョンだけ知りたい場合は -vオプション--versionオプション を付けてください。

C:\Users\AGadget> npm version -v

C:\Users\AGadget> npm version --version

5-2. パッケージを初期化する

パッケージを初期化する場合は initコマンド を使用します。当コマンドを実行すると、対話的に package.json の設定を行うことができます。

C:\Users\AGadget> npm init

初期設定が面倒な場合は -yオプション--yesオプション を付けることで標準設定のpackage.jsonが生成されます。

C:\Users\AGadget> npm init -y

C:\Users\AGadget> npm init --yes

5-3. インストールされているパッケージを確認

インストールされているパッケージを確認したいときは lsコマンド を使用してください。

C:\Users\AGadget> npm ls

インストールされたパッケージ階層のうち、特定の階層だけ見たい場合は --depthオプション を使用します。階層は最も浅い階層――トップレベルのパッケージを0としてカウントしていきます。

C:\Users\AGadget> npm ls --depth=0

また、グローバルインストールされたパッケージを見たいときは -gオプション--globalオプション を付けてください。

C:\Users\AGadget> npm ls -g

C:\Users\AGadget> npm ls --global

C:\Users\AGadget> npm ls --depth=0 -g

C:\Users\AGadget> npm ls --depth=0 --global

5-4. パッケージをインストール

パッケージをインストールする場合は installコマンド を使用してください。installコマンドに続いて、インストールしたいパッケージ名を記述してください。

C:\Users\AGadget> npm install [インストールしたいパッケージ名]

具体例として、TypeScriptを導入する場合の書き方を掲載します。

C:\Users\AGadget> npm install typescript

また、インストール時にはインストールするパッケージのバージョンを指定することができます。バージョンを指定しなかった場合は最新バージョンがインストールされます。

C:\Users\AGadget> npm install typescript@1.2.3

グローバルインストールしたい場合は -gオプション--globalオプション を付けてください。

C:\Users\AGadget> npm install typescript -g

C:\Users\AGadget> npm install typescript --global

C:\Users\AGadget> npm install typescript@1.2.3 -g

C:\Users\AGadget> npm install typescript@1.2.3 --global

5-5. 開発環境を再現する

パッケージを初期化する initコマンド を実行することで生成される package.json と、パッケージをインストールする installコマンド を組み合わせることで、他者の開発環境を簡単に再現することができます。具体例とともに説明していきます。

まず、既存のパッケージに含まれるpackage.jsonをコピーして、適当なディレクトリに配置します。

C:\Users\AGadget> COPY C:\Users\AGadget\old-pack\package.json C:\Users\AGadget\new-pack\package.json

コピー先となるディレクトリに移動し、installコマンドを実行します。

C:\Users\AGadget> CD .\new-pack

C:\Users\AGadget\new-pack> npm install

npmはカレントディレクトリにpackage.jsonが存在するか確認します。package.jsonが存在するならば、ファイル内を参照し、どのようなパッケージが導入されているかを確認します。そして最後に、記載されていたパッケージをインストールしてくれます。

5-5a. ちょっと注意

ところで、上記の方法だとコピー元と全く同じ開発環境を再現できない可能性があります。

以下.jsonファイルは、ある時点での自作パッケージの情報をまとめたpackage.jsonの内容です。TypeScriptだけが導入された状態になっています。

package-json
{
  "name": "tes-tes-testoooooo",
  "version": "1.0.0",
  "lockfileVersion": 1,
  "requires": true,
  "dependencies": {
    "typescript": {
      "version": "^3.9.5",
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.6.tgz",
      "integrity": "sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw=="
    }
  }
}

ファイル中央より、やや下方にTypeScriptが導入されている旨と、そのバージョンが ^3.9.5 であると記されています。「What' the hat!?」という感じですが、このハット記号(キャレット記号とも)がバージョン情報の先頭に付いているかどうかでnpmの挙動が変わってきます。

例えば 3.9.5 であるならばnpmは「TypeScriptのv3.9.5を導入すれば良いのか」と判断します。しかし ^3.9.5 の場合は「TypeScriptの3.x系の最新バージョンを導入すれば良いのか」と解釈してしまいます。そのため実際にインストールされるのは3.9.5ではなく、バグフィックスが行われた 3.9.6 かもしれませんし、マイナーチェンジ版の 3.10.0 かもしれないのです。

まぁ、メジャーバージョンの変更ではないので たぶん 致命的な問題にはならないとは思いますが、チームで開発する場合などはバージョンを揃えておいたほうが安心できますね。

この問題への対応方法としては2つ考えられます。1つは、受け取ったpackage.jsonのバージョン情報にあるハット記号を削除してからinstallコマンドを実行すること。もう1つは、明示的に特定のバージョンをインストールすることです。

C:\Users\AGadget> REM この方法だとTypeScriptの最新バージョンがインストールされる

C:\Users\AGadget> npm install typescript

C:\Users\AGadget> REM 特定のバージョン――例えば3.9.5をインストールしたいならば以下のように指定すること

C:\Users\AGadget> npm install typescript@3.9.5

5-5b. 救世主(?)package-lock.json登場!

2015年10月29日にリリースされた npm v5.0.0 からは package-lock.json という仕組みが新たに追加されました。

package-lock.jsonはpackage.jsonを 補完する ファイルです。npm v5.0.0以降では、installコマンドを実行するとpackage.jsonとpackage-lock.jsonの2つのファイルが生成されるようになります。

package-lock.jsonの役割は package.jsonで指定されたパッケージのうち、実際にインストールされたパッケージ(と、そのバージョン)は何か ということを明確にすることです。実際の挙動を見てみましょう。

適当なパッケージを用意し、そこにTypeScriptを導入します。バージョンは指定せず、現時点での最新バージョンを取ってくるように指示します。ここでは仮に 3.9.5 が最新バージョンであったとします。

C:\Users\AGadget> CD .\test-pack

C:\Users\AGadget\test-pack> npm init --yes
Wrote to C:\Users\AGadget\test-pack\package.json:

{
  "name": "test-pack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

C:\Users\AGadget\test-pack> npm init typescript
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN test-pack@1.0.0 No description
npm WARN test-pack@1.0.0 No repository field.

+ typescript@3.9.5
added 1 package from 1 contributor and audited 1 package in 1.185s
found 0 vulnerabilities

C:\Users\AGadget\test-pack>

上記コマンドを実行すると以下のように.jsonファイルが生成されます。

package.json
{
  "name": "test-pack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "typescript": "^3.9.5"
  }
}
package-lock.json
{
  "name": "test-pack",
  "version": "1.0.0",
  "lockfileVersion": 1,
  "requires": true,
  "dependencies": {
    "typescript": {
      "version": "3.9.5",
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz",
      "integrity": "sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw=="
    }
  }
}

package.jsonに記載されたTypeScriptのバージョンは ^3.9.5 となっていますが、package-lock.jsonでは 3.9.5 となっていることが分かります。これは「当パッケージではTypeScript v3.9以上のバージョンを使用するが、現在導入されているバージョンはv3.9.5である」ということを意味しています。

さて、この状況の裏でTypeScriptのバージョンが 3.9.6 に上がっているとします。このとき両ファイルをもとに環境を再現するとどのようなことになるでしょうか。

C:\Users\AGadget\test-pack> COPY .\package.json ..\test-pack-new\package.json

C:\Users\AGadget\test-pack> COPY .\package-lock.json ..\test-pack-new\package-lock.json

C:\Users\AGadget\test-pack> CD ..\test-pack-new

C:\Users\AGadget\test-pack-new> npm install

正解は TypeScript v3.9.5が導入される です。

npmはinstallコマンドが実行されると、カレントディレクトリ内にpackage.jsonがあるか確認します。package.jsonが存在する場合、どのようなパッケージが導入されているかを見て回ります。このとき導入されているパッケージのバージョンが固定されている場合は、そのバージョンを導入します。それに対して、ハット記号が付くなどの条件が付けられている場合は、条件を満たすバージョンのなかでの最新バージョンをインストールしようとします。

……が、このときpackage-lock.jsonがあり、かつ、package-lock.json内に当該パッケージのバージョン情報が記載されていた場合は、そのバージョンをインストールするように働くのです。これにより安全に環境を再現することができるようになりました。

全体的に挙動がややこしいため実際に使ってみて覚えてください。

5-6. パッケージをアンインストール

既にインストール済みのパッケージをアンインストールする場合は uninstallコマンド を使用してください。uninstallコマンドに続いて、アンインストールするパッケージ名を指定してください。

C:\Users\AGadget> npm uninstall [インストールしたいパッケージ名]

C:\Users\AGadget> npm uninstall package-name

グローバルインストールされたパッケージをアンインストールするときは -gオプション--globalオプション を付けてください。

C:\Users\AGadget> npm uninstall -g package-name

C:\Users\AGadget> npm uninstall --global package-name

5-7. パッケージをアップデート

導入済みのパッケージをアップデートするには updateコマンド を使用します。

C:\Users\AGadget> npm update [アップデートしたいパッケージ名]

C:\Users\AGadget> npm update package-name

グローバルインストールされたパッケージをアップデートするときは -gオプション--globalオプション を付けてください。

C:\Users\AGadget> npm update -g package-name

C:\Users\AGadget> npm update --global package-name

5-8. 最新ではないパッケージを一覧表示

導入済みのパッケージのなかから、最新バージョンにアップデートされていないパッケージを一覧表示します。

C:\Users\AGadget> npm outdated

表示対象をグローバルインストールされたパッケージとする場合は -gオプション--globalオプション を付けてください。

C:\Users\AGadget> npm outdated -g

C:\Users\AGadget> npm outdated --global
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Qiitaの記事のタグ情報を活用したアイデア創出方法

環境

node v14.5.0

作ったもの

特定の語句が使用されているQiitaの記事のタグのトップ10を抽出します。
この記事の後半で、このプログラムから抽出した言葉でマインドマップを作り、アイデアを考えます。(マインドマップ作成は手作業ですw)
※マインドマップとは、頭の中で考えていることを脳内に近い形に描き出すことで、記憶の整理や発想をしやすくするもので、主に意識高い人たちが思考の整理やアイデア創出に活用します。
たとえば、「Qiita」と入力すると、

$ node app.js
✔ 調べたい言葉を入力してください … Qiita
Python 15
JavaScript 11
初心者 9
PHP 6
Rails 6
AWS 6
Docker 6
docker-compose 5
Mac 5
Ruby 5

Qiitaという言葉を使っている記事のタグは、pythonが一番多いことが分かります。

これは、QiitaのAPIの中のitemsを使いました。
記事の一覧を新しいものから返してくれます。

https://qiita.com/api/v2/items?query="検索語句"

詳細はこちらを御覧ください。
https://qiita.com/api/v2/docs#投稿

コード

app.js
const axios = require("axios"); //HTTP通信ライブラリ
const prompts = require("prompts"); //コマンドプロンプト入力のライブラリ

async function main() {

  // 入力  (参考記事:https://co.bsnws.net/article/288)
  let questions = {
    type: "text", // インプットタイプ
    name: "word", // 変数名
    message: "調べたい言葉を入力してください"
  };
  let search =  await prompts(questions);

  let loop_number;  //ループ回数
  let tag_name = [""]; //取得するタグ名の配列
  let tag_number =[0]; //取得するタグの数の配列
  let tag_add_flag = 0; //タグを追加するか判定フラグ

  //調べたい言葉が含まれるQiitaの投稿をQittaのAPIで取得(直近100記事)
  let response = await axios.get("https://qiita.com/api/v2/items?per_page=100&query="+ encodeURIComponent(search.word));

  //データの数が100なければループ回数はデータの数、それ以外は100
  if (response.data.length < 100){
      loop_number = response.data.length;
      }
      else{
        loop_number = 100;
      }

  //検索ワードにヒットした投稿からタグを抽出する
  if (response.data.length > 0){
      for (let i = 0; i < loop_number; i++ ) {

        for (let j = 0; j < response.data[i].tags.length; j++) {
          tag_add_flag = 1;
          //tagは配列なのでループ
          for (let k = 0; k < tag_name.length; k++){  
            //既に抽出したタグなら数をカウントする
            if (response.data[i].tags[j].name == tag_name[k]){
                tag_number[k]=tag_number[k]+1;
                tag_add_flag = 0;
              }
          }
          //はじめて見るタグなら追加する
          if (tag_add_flag ==1 ){
              tag_name.push(response.data[i].tags[j].name) ;
              tag_number.push(1);
          }      
        }
      }
      //タグを降順に並べ替え
      sort(tag_name,tag_number);

      //トップ10を表示
      for (let i = 0; i < 10 ; i++ ) {
        console.log(tag_name[i], tag_number[i]);
      }

    }else{
      console.log("該当の投稿はありません");
  }

}


// 降順に並び替え (この記事参照 https://qiita.com/may88seiji/items/a6047fd0fba9d598f103)
function sort(index,data) {
  for(var i = 0; i < data.length+1; i++){
    for(var j = data.length; j>i ; j-- ){
      //隣りあう2つの値を比べて、後ろが多きければ交換する
      if(data[j]>data[j-1]){
        //数値の交換
        let tmp1 = data[j];
        data[j] = data[j-1];
        data[j-1] =tmp1;
        //インデックスの交換
        let tmp2 =index[j];
        index[j] = index[j-1];
        index[j-1] =tmp2;        
      }
    }
  }
}

main();

参考サイト

promptsライブラリー
prompts : node.js用のコマンドラインからの値を受け取る時に便利なライブラリ

並べ替え
JavaScript バブルソート

ありがとうございました。

マインドマップ

これで終わりではなくて、ここからが始まりです。
タグをマインドマップでつなげてみると、おぼろげながら進むべき道が見えるような気がしてみました。

例えば、起業に興味があるとします。

$ node app.js
✔ 調べたい言葉を入力してください … 起業
Python 10
初心者 8
ポエム 8
起業 7
リーンスタートアップ 6
Qiita 6
個人開発 5
今読んでおくべき記事100選 5
PHP 5
スタートアップ 4

同様に、これらの語句の記事で使われてるタグを調べます。
pythonという言葉が使われている記事のタグは、 Python、機械学習、AtCoder、AWS、AIなど
初心者は、 CSS、PHP、HTML、Rails、Rubyなど
ポエムは、JavaScript、Python、初心者、機械学習、新人プログラマ応援など
リーンスタートアップは、アジャイル、リーン、スクラム、スタートアップ、Qiitaなど
Qiitaは、Python、JavaScript、初心者、PHP、Railsなど

同様のことを繰り返します。

これを意識高くマインドマップにしてみました。
(汚い手書きですいません)
IMG_6802.jpg

なんとなく、おぼろげながら、Qiita民が起業に進むべき道が見えてきませんか?
まずは、HTML、CSS、Rubyなどで基礎をかためて、アジャイルってところですかね。(無理矢理感)

あと、私は地方創生に関する仕事をしています。せっかくなので何かヒントはないか、Qiitaのタグからマインドマップを作ってみました。

IMG_6801.jpg

やっぱり、Qiita民が地方創生するには、ハッカソンが良さそうですね。
ProtoOutStudioやMAというタグも出てきました。
他にも開発合宿の誘致など、良いかもしれません。

今回の投稿は、めちゃくちゃ無理矢理感高いですが、タグ情報の繋がりから、今まで気づかなかった何か見えてくるかもしれませんので、お試しください。

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

Qiitaの記事のタグ情報を活用した意識高いアイデア創出方法

環境

node v14.5.0

作ったもの

特定の語句が使用されているQiitaの記事のタグのトップ10を抽出します。
この記事の後半で、このプログラムから抽出した言葉でマインドマップを作り、アイデアを考えます。(マインドマップ作成は手作業ですw)

たとえば、「Qiita」と入力すると、

$ node app.js
✔ 調べたい言葉を入力してください … Qiita
Python 15
JavaScript 11
初心者 9
PHP 6
Rails 6
AWS 6
Docker 6
docker-compose 5
Mac 5
Ruby 5

Qiitaという言葉を使っている記事のタグは、pythonが一番多いことが分かります。

これは、QiitaのAPIの中のitemsを使いました。
記事の一覧を新しいものから返してくれます。

https://qiita.com/api/v2/items?query="検索語句"

詳細はこちらを御覧ください。
https://qiita.com/api/v2/docs#投稿

コード

app.js
const axios = require("axios"); //HTTP通信ライブラリ
const prompts = require("prompts"); //コマンドプロンプト入力のライブラリ

async function main() {

  // 入力  (参考記事:https://co.bsnws.net/article/288)
  let questions = {
    type: "text", // インプットタイプ
    name: "word", // 変数名
    message: "調べたい言葉を入力してください"
  };
  let search =  await prompts(questions);

  let loop_number;  //ループ回数
  let tag_name = [""]; //取得するタグ名の配列
  let tag_number =[0]; //取得するタグの数の配列
  let tag_add_flag = 0; //タグを追加するか判定フラグ

  //調べたい言葉が含まれるQiitaの投稿をQittaのAPIで取得(直近100記事)
  let response = await axios.get("https://qiita.com/api/v2/items?per_page=100&query="+ encodeURIComponent(search.word));

  //データの数が100なければループ回数はデータの数、それ以外は100
  if (response.data.length < 100){
      loop_number = response.data.length;
      }
      else{
        loop_number = 100;
      }

  //検索ワードにヒットした投稿からタグを抽出する
  if (response.data.length > 0){
      for (let i = 0; i < loop_number; i++ ) {

        for (let j = 0; j < response.data[i].tags.length; j++) {
          tag_add_flag = 1;
          //tagは配列なのでループ
          for (let k = 0; k < tag_name.length; k++){  
            //既に抽出したタグなら数をカウントする
            if (response.data[i].tags[j].name == tag_name[k]){
                tag_number[k]=tag_number[k]+1;
                tag_add_flag = 0;
              }
          }
          //はじめて見るタグなら追加する
          if (tag_add_flag ==1 ){
              tag_name.push(response.data[i].tags[j].name) ;
              tag_number.push(1);
          }      
        }
      }
      //タグを降順に並べ替え
      sort(tag_name,tag_number);

      //トップ10を表示
      for (let i = 0; i < 10 ; i++ ) {
        console.log(tag_name[i], tag_number[i]);
      }

    }else{
      console.log("該当の投稿はありません");
  }

}


// 降順に並び替え (この記事参照 https://qiita.com/may88seiji/items/a6047fd0fba9d598f103)
function sort(index,data) {
  for(var i = 0; i < data.length+1; i++){
    for(var j = data.length; j>i ; j-- ){
      //隣りあう2つの値を比べて、後ろが多きければ交換する
      if(data[j]>data[j-1]){
        //数値の交換
        let tmp1 = data[j];
        data[j] = data[j-1];
        data[j-1] =tmp1;
        //インデックスの交換
        let tmp2 =index[j];
        index[j] = index[j-1];
        index[j-1] =tmp2;        
      }
    }
  }
}

main();

参考サイト

promptsライブラリー
prompts : node.js用のコマンドラインからの値を受け取る時に便利なライブラリ

並べ替え
JavaScript バブルソート

ありがとうございました。

マインドマップ

これで終わりではなくて、ここからが始まりです。
タグをマインドマップでつなげてみると、おぼろげながら進むべき道が見えるような気がしてみました。

例えば、起業に興味があるとします。

$ node app.js
✔ 調べたい言葉を入力してください … 起業
Python 10
初心者 8
ポエム 8
起業 7
リーンスタートアップ 6
Qiita 6
個人開発 5
今読んでおくべき記事100選 5
PHP 5
スタートアップ 4

同様に、これらの語句の記事で使われてるタグを調べます。
pythonという言葉が使われている記事のタグは、 Python、機械学習、AtCoder、AWS、AIなど
初心者は、 CSS、PHP、HTML、Rails、Rubyなど
ポエムは、JavaScript、Python、初心者、機械学習、新人プログラマ応援など
リーンスタートアップは、アジャイル、リーン、スクラム、スタートアップ、Qiitaなど
Qiitaは、Python、JavaScript、初心者、PHP、Railsなど

同様のことを繰り返します。

これを意識高くマインドマップにしてみました。
(汚い手書きですいません)
IMG_6802.jpg

なんとなく、おぼろげながら、Qiita民が起業に進むべき道が見えてきませんか?
まずは、HTML、CSS、Rubyなどで基礎をかためて、アジャイルってところですかね。(無理矢理感)

あと、私は地方創生に関する仕事をしています。せっかくなので何かヒントはないか、Qiitaのタグからマインドマップを作ってみました。

IMG_6801.jpg

やっぱり、Qiita民が地方創生するには、ハッカソンが良さそうですね。
ProtoOutStudioやMAというタグも出てきました。
他にも開発合宿の誘致など、良いかもしれません。

今回の投稿は、めちゃくちゃ無理矢理感高いですが、タグ情報の繋がりから、今まで気づかなかった何かが見えてくるかもしれませんので、お試しください。

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

[Node.js]VSCodeエクステンション作りをしたメモ

はじめに

VSCodeのエクステンション作りにチャレンジしたメモです。

:warning: 注意 :warning:

  • メモ書きなのでかなりザックリです、、
  • オレオレエクステンション作りなので、マーケットプレイスへのデプロイは行っていません

VSCodeエクステンション手順

エクステンション作りの手順はこちらに沿います。

  • Node.js 環境作成
    • yo
    • generator-code
    • vsce
  • エクステンション作成
    • yo で雛形作成
    • 実装
    • デバッグ
  • ローカルデプロイ
    • Azure DevOps アカウント取得
    • パブリッシャー作成
    • vsixファイル作成

手順詳細

Node.js 環境作成

Node.js 本体はインストール済とします。

$ node --version
# v14.2.0
$ npm --version
# v6.14.6

yo

実装テンプレートの雛形ジェネレーター yo をインストールします。

$ npm install -g yo

generator-code

yo でジェネレートするVSCodeエクステンションの雛形です。

$ npm install -g generator-code

vsce

Node.js アプリケーションをビルドし、エクステンションファイル vsix を生成するビルドツールです。

$ npm install -g vsce

エクステンション作成

yo で雛形作成

yo でVSCodeエクステンションの雛形を作ります。

$ yo code

インタラクティブにプロジェクト名等のメタ情報を入力しながら、雛形を作ることが出来ます。
今回は sample と言うエクステンションを作ったとして、以降も書き進めます。

実装

生成されたソースのうち、エクステンションの処理本体が実装される extension.js をメンテナンスします。yo code で生成した場合、下記のコードが生成されています。

extension.js
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const vscode = require('vscode');

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed

/**
 * @param {vscode.ExtensionContext} context
 */
function activate(context) {

    // Use the console to output diagnostic information (console.log) and errors (console.error)
    // This line of code will only be executed once when your extension is activated
    console.log('Congratulations, your extension "sample" is now active!');

    // The command has been defined in the package.json file
    // Now provide the implementation of the command with  registerCommand
    // The commandId parameter must match the command field in package.json
    let disposable = vscode.commands.registerCommand('sample.helloWorld', function () {
        // The code you place here will be executed every time your command is executed

        // Display a message box to the user
        vscode.window.showInformationMessage('Hello World from sample!');
    });

    context.subscriptions.push(disposable);
}
exports.activate = activate;

// this method is called when your extension is deactivated
function deactivate() {}

module.exports = {
    activate,
    deactivate
}

エクステンションが有効化された時にコールされる activate と 無効化時コールの deactive を作り上げていくことになります。
また、言ってしまえばシンプルな Node.js 製のアプリケーションなので、パブリックな npm モジュールも npm install ${ライブラリ名} --save ですんなりと利用出来ます。

デバッグ

extension.js はデバッグ実行が出来ます。
サイドメニューのデバッグアイコンを押下し、キャプチャ矢印の「▶︎」ボタンを押すと

image.png

デバッグ実行用にエクステンションがロードされた別ウィンドウが開くので、コマンドパレットでエクステンションを指定(雛形では Hello World)して実行出来ます。

ローカルデプロイ

エクステンションをローカルデプロイする場合、エクステンションファイル(.vsix ファイル)をローカルでビルドした上で、VSCode本体にロードする形になります。

Azure DevOps アカウント取得

Azure DevOps をアカウントを取得し、エクステンションのパブリッシャーとAPIキーを取得します。
APIキー取得はこちらを参照下さい。APIキーのスコープ設定をこちらのドキュメントに沿わずに行うと、次手順で認証・権限系のエラーに見舞われます、、

パブリッシャー作成

$ vsce create-publisher ${ユーザ名}

インタラクティブ形式でユーザ名やAPIキーを問われるため、入力して下さい。

vsixファイル作成

package.jsonpublisher の項目を書き足した上、アプリケーションのディレクトリ直下で

$ vsce package

を実行すると、sample-${package.jsonに記載のバージョン}.vsix が生成されます。
VSCodeのエクステンションタブから「…」を押下して Install from VSIX から、生成されたファイルをロードすれば、ローカルインストールが完了します。

まとめ

雛形からシンプルで、JavaScriptNode.js アプリケーションの入門としても割と良いネタになるかもなーとのイメージです。
会社でもプライベートでもあんまりフロントエンドとはたわむれていないので、私もVSCodeのカスタマイズと共にちょっと遊んでみようと思います。

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

[Windows][Docker] nodeコンテナでnpm installがハングアップする件の対策

nodeにgulpやらbabelやらonsen-uiやら大量にインポートしたサーバーアプリケーション。
いままでVagrantで動いていたこの環境を、Dockerコンテナ化するタスクを受けました。
加えてマルチOS(Windows, Mac, Linux)で動作する必要があります。

現状

  • ルートディレクトリに package.json は残っていました。
  • /node_modules はありませんでした。
    (そもそも、違う環境の /node_modules は(環境依存モジュールが有る可能性があるので)流用する気はないですけれども)

package.json をたよりに npm install を実行してみた

  • Mac ... 動いた。
  • Linux ... 動いた。
  • Windows ... 全然動かない。
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /xxxxxxxxxxx/xxxxxxxxxxx/xxxxxxxxxxx
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/xxxxxxxxxxx/xxxxxxxxxxx/xxxxxxxxxxx'
... 
npm ERR! Maximum call stack size exceeded
"Failed to load external module @babel/register"

これらのエラーが途中で無秩序に発生します。
上記3種のエラーが出て止まればまだマシな方で、最悪、Docker Desktopがハングアップします。

なおコマンドインターフェース上のプログレス表示の傾向としては、

  • 最初は快速にnpm installが進行していきますが、
  • だんだん遅くなり、
  • やがてハングアップします。

現象の傾向から、メモリリークを大リファクタリングした昔の仕事をなんとなく思い出しました。

トライアンドエラー

ネット上には一見似たような事例が散見されるのですが、

  • npm install --no-bin-links
  • rm -f package-lock.json
  • docker desktopの性能設定を上げる
  • npm cache clean --force
  • .npmignore を作る
  • npm rebuild
  • npm config set registry http://registry.npmjs.org/
  • package.jsonをすべて手書きのnpm installにする

これらを全部やってみましたが、ダメでした。

結果的対処方法

割と泥臭い対応で対応しました。

  1. docker-nodeコンテナのワークディレクトリをdocker-compose.ymlなどでvolumeマウントしておく。
  2. コンテナの中のシェルにログオンする。
  3. /node_modules は絶対削除せずに、何度もnpm installする。(コンテナの外から直接docker-compose execnpm installを実行しない)
  4. インストール済のモジュールは飛ばされるので、徐々に/node_modulesの中身が充足していきます。
  5. 完成した /node_modules を(volumeマウント経由でdockerコンテナから確保し、)/windows_node_modules などとして確保しておく。
  6. ビルドスクリプトを修正し、次回からは npm install を実行させるのではなく、/windows_node_modules を mv windows_node_modules node_modules で済ませるようにする。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MacにNodeJSをリーインストールする

Install NodeJS

brew uninstall babel
brew uninstall yarn
sudo rm -rf ~/.npm ~/.nvm ~/node_modules ~/.node-gyp ~/.npmrc ~/.node_repl_history
sudo rm -rf /usr/local/bin/npm /usr/local/bin/node-debug /usr/local/bin/node /usr/local/bin/node-gyp
sudo rm -rf /usr/local/share/man/man1/node* /usr/local/share/man/man1/npm*
sudo rm -rf /usr/local/include/node /usr/local/include/node_modules
sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /usr/local/lib/dtrace/node.d
sudo rm -rf /opt/local/include/node /opt/local/bin/node /opt/local/lib/node
sudo rm -rf /usr/local/share/doc/node
sudo rm -rf /usr/local/share/systemtap/tapset/node.stp

brew uninstall node
brew doctor
brew cleanup --prune-prefix
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.0/install.sh | bash
source ~/.nvm/nvm.sh
nvm install stable

Add command

vim ~/.zshrc
source ~/.nvm/nvm.sh
source ~/.zshrc

react

npm uninstall -g create-react-app
rm -rf /usr/local/bin/create-react-app
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む