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

Google Colab上で Node.js でサーバーを動して外部からアクセス(モジュール:ngrok・express)

はじめに 内容は表題のとおりです。 なお、Google Colab でやるメリットは、今回の内容を試し始める前から特にないと思っていたりしましたが(他に Node.js をホスティングしてくれるサービスもあったりするので、それらを使うほうがオススメ)、「やってみたら動くか気になったので試した」というものです。 今回の内容をやろうと思った流れ 最近、Google Colab をちょこちょこ触るようになりました。 その中で、以下の記事を見つけて、簡単に動作確認をしてみてうまくいきました。  ●Google ColabでJavaScriptしよう - Qiita   https://qiita.com/moomooya/items/0d565df082bf4b7019d7 Google Colab で無事に JavaScript が実行できたw https://t.co/aKdT5CASRB pic.twitter.com/f7VmmBwBlD— you (@youtoy) April 4, 2021 上記の事例では、以下のコードを動かしてみるところで終わりでしたが、「さらに他の機能も動作させられたりするかな?」と思って、追加でやったのが今回の内容です。 var moment = require('/content/node_modules/moment') moment.locale('ja') console.log(moment().format('M月D日(dd)')) Google Colab上でサーバーを動かして外部からアクセス 表題のとおり、今回やる内容は以下になります。 Google Colab上で Node.js を動かせるようにする express のモジュールでサーバーを動かす ngrok のモジュールで外部から Google Colab にアクセスできるようにする 上記のそれぞれを進めていきます。 Google Colab上で Node.js を動かせるようにする下準備 実行する内容は、基本的には冒頭で紹介していた記事のとおりです。  ●Google ColabでJavaScriptしよう - Qiita   https://qiita.com/moomooya/items/0d565df082bf4b7019d7 しかし、実行する手順については入れ替えてやっていきます。具体的には以下のとおりです。 1)ノートブックを新規作成 2)ipynbをダウンロードのダウンロードとテキストエディタでの書きかえ ※ 参照元の記事の「一度 [ファイル] > [.ipynbをダウンロード] でファイルをダウンロードし、ダウンロードしたファイルをテキストエディタで開いて・・・」という部分 3)ipynbをアップロード 4)「npmの初期化とIJavaScriptのインストール ※ 参照元の記事の「npmの初期化とIJavaScriptのインストールを行います。npm installではrootでの実行を通すために--unsafe-permオプションをつけてください。・・・」という部分 5)登録済みのカーネルにjavascriptが含まれていることを確認・npm_modulesの場所を確認 ※ 参照元の記事の「登録済みのカーネルにjavascriptが含まれていることを確認します。・・・」という部分 npm install と JavaScript の処理の動作確認 ここまで進めたら、npm install を使ったインストールを行いますが、この記事では ngrok・express をインストールします。以下のコマンドを実行します。 !npm install ngrok express インストールができたら、いったんここで JavaScript の処理の動作確認を行います。 試しに、以下を実行してみます。 console.log(`test`) 自分の場合は、ここで必ずシンタックスエラーがでていました。 このエラーの対処に関しては、参照元の記事の最後のほうに書かれていた「再読込後のエラー?」という部分の内容が活用できました(自分の手順では、再読込はしていないのですが)。 具体的には、以下の画像で示した部分で行う操作です。 再度、先ほどのコードを実行すると、今度はうまく処理結果が得られました。 ngrok・express のモジュールを組み合わせて動かす それでは、最後に ngrok と express を使った処理を書いていきます。 今回動かすプログラムの元になるものは、以下の記事に書かれた内容です(この記事の下準備として、自分の PC内で試して書いた内容です)。  ●ngrok と express を組み合わせて Hello World!(ngrok のモジュールを利用) - Qiita   https://qiita.com/youtoy/items/f44041689390deb81350 この記事の中のプログラムにちょっとだけ変更を加えて利用します。 変更箇所は最初の 3行です。 const ngrok = require("/content/node_modules/ngrok"), express = require("/content/node_modules/express"); const port = 6000; const app = express(); app.get("/", (req, res) => { res.send("Hello World!"); }); ngrok.connect(port).then((url) => { app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`); console.log(`Example app listening at ${url}`); }); }); require で指定するモジュールは、フルパスで記載する必要があるようです(上でも参照していた記事の内容より)。 また、ポート番号も適当に変えました。 これを実行した結果が以下です。 ngrok で生成された URL にブラウザからアクセスすることで、ブラウザ上で「Hello World!」と表示できるのが確認できました。 あと、上記のプログラム実行を終了させる方法に関して、適したものが何かは分かっていないのですが、「ランタイムの再起動やリセット」を行うことで、外部からのブラウザアクセスができなくなる(ngrok が止まる)のは確認できました。 おわりに 無事、やろうと思ったことは実現できました。 冒頭に書いたとおり、Google Colab でやるメリットは試し始める前から特にないと思っていたのですが、やってみた後も同様です。本当は、Python と共存させられて機械学習周りの機能と連携させられるとか、Node.js で GPU が使えてそれを活用できる用途がある、とかあれば良いのですが・・・。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Express: ファイルアップロード

ライブラリーのインストール sudo npm install -g multer app.js //------------------------------------------------------------------------- // app.js // // Apr/11/2021 //------------------------------------------------------------------------- const express = require('express') const fs = require('fs') var cfenv = require('cfenv') const multer = require('multer') const app = express() const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, './data_work') }, filename: function (req, file, cb) { cb(null, file.originalname) } }) const upload = multer({ storage: storage }) app.post('/upload', upload.single('file'), (req, res) => { const filename = req.file.originalname const file = req.file console.log(file) const content = fs.readFileSync(req.file.path, 'utf-8') res.send(filename + ': uploaded ***\n') }) var appEnv = cfenv.getAppEnv() app.listen(appEnv.port, '0.0.0.0', function() { console.log("server starting on " + appEnv.url) }) //------------------------------------------------------------------------- サーバーの起動 $ export NODE_PATH=/usr/lib/node_modules $ node app.js server starting on http://localhost:3000 テストスクリプト p01.jpg が data_work にアップロードされます。 curl http://localhost:3000/upload -F 'file=@p01.jpg' HTTPie を使ったテストスクリプト http -f POST http://localhost:3000/upload file@p01.jpg 参考情報 Express で簡単な WebAPI を作成
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ngrok と express を組み合わせて Hello World!(ngrok のモジュールを利用)

表題の内容の通りです。 ngrok と express のモジュールを読み込んで、シンプルに Hello World! を返す、という内容を試した際の個人用メモです。 事前準備から実行まで 事前準備 事前に npm install ngrok express を実行してください。 コードの内容 以下の内容を、例えば app.js など適当な名前で作成します。 以下でポート番号は 8080 としましたが、適当に変えてしまって問題ありません。 const ngrok = require("ngrok"), express = require("express"); const port = 8080; const app = express(); app.get("/", (req, res) => { res.send("Hello World!"); }); ngrok.connect(port).then((url) => { app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`); console.log(`Example app listening at ${url}`); }); }); そして、 node app.js を実行してください。 そうすると、ローカル・グローバル側からのそれぞれのアクセス先の情報が、以下のように出力されます。 どちらにアクセスしても、ブラウザ上で以下が表示されます。 参照した記事 ●Raspberry Piをngrokで公開する - Part1: Expressをpm2から起動する - Qiita  https://qiita.com/masato/items/9fd096a544fc462a7b11 【追記】 その後にやったこと ●Google Colab上で Node.js でサーバーを動して外部からアクセス(モジュール:ngrok・express) - Qiita  https://qiita.com/youtoy/items/2f75ad138861191e5019
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【2021年4月版】Node.js v15 の npm 7 で TypeScript の MonoRepo に入門

NPM にもやってきましたワークスペース YarnやLernaでお馴染みのワークスペース管理ですが、Node v15 の nvm 7 からこれに対応した模様です! Medium: Migrating to a Monorepo Using NPM 7 Workspaces 上記の記事では exprimental とありますが、現在では GA の模様です。 自分も最近では Serverless と SPA での開発がメインでどちらも TypeScript を使うので、Typescript でも宜しく Mono Repository できないものかと考えておりましたら・・・ いい感じの Typescript での Monorepo サンプルを発見いたしましたので、これに沿って Typescript での Monorepo に入門してみたいと思います。 1. まず JS から TypeScript を導入する前に、JS で Workspace の破壊力を試してみましょう。 1-1. プロジェクトの階層構造を構築 以下のようなコマンドでプロジェクトのフォルダを作成します。 $ mkdir project1 && cd $_ $ npm init -y $ mkdir app $ mkdir -p lib/component-a $ mkdir -p lib/component-b $ cd app && npm init -y $ cd ../lib/component-a && npm init -y $ cd ../component-b && npm init -y $ cd ../.. 結果、以下のようなフォルダ構成のプロジェクトが出来上がります。 project1 ├── app │  └── package.json ├── lib │  ├── component-a │  │ └── package.json │  └── component-b │  └── package.json └── package.json 1-2. ワークスペースの宣言 トップの package.json に workspaces を追加します。 project1/package.json { ... "workspaces": [ "libs/*", "app" ], ... } 上記のような指定で、app と libs 以下のpackage.jsonを含むサブフォルダ全てを"個別のモジュール"として認識してくれます。 これで、npm i をして、結果を表示してみましょう。 $ pwd /xxx/xxx/project1 $ npm i ... $ npm ls project1@1.0.0 /xxx/xxx/project1 ├── app@1.0.0 -> /xxx/xxx/project1/app ├── component-a@1.0.0 -> /xxx/xxx/project1/libs/component-a └── component-b@1.0.0 -> /xxx/xxx/project1/libs/component-b のような感じで app と component-a、component-bが認識されていることがわかります。 ついでに node_modules 内はどうなっているか見てみましょう。 $ tree . ├── app │ └── package.json ├── libs │ ├── component-a │ │ └── package.json │ └── component-b │ └── package.json ├── node_modules │ ├── app -> ../app │ ├── component-a -> ../libs/component-a │ └── component-b -> ../libs/component-b ├── package.json └── package-lock.json このような感じで、app と libs 以下の component-a、component-b が個別のモジュールとして依存関係に追加されているのが確認できました。 1-3. 動作確認用プログラムの追加 プログラム上、ちゃんと認識されているのか、確認してみたいと思います。 シンプルなスクリプトを以下のように作成します。 component-a には以下の index.jsを作成してみます。 libs/component-a/index.js module.exports = 'A だよ!'; 続いて component-b には以下の index.jsを作成してみます。 libs/component-b/index.js module.exports = 'B どす〜'; そしてこれらをappから呼び出してみましょう。 app/index.js console.log("start app"); const moduleA = require('component-a'); console.log(moduleA); const moduleB = require('component-b'); console.log(moduleB); 1-4. 動作確認 では、app/index.js を起動してみます。 $ pwd /xxx/xxx/project1 $ node app/index.js start app A だよ! B どす〜 $ cd app && node index.js start app A だよ! B どす〜 トップレベルのディレクトリからも app ディレクトリからでも相対パスなどなしでちゃんと component-aとcomponent-bが読み込めています。 app/package.json の Dependencies には component-aやcomponent-bは追加してませんよ!? さらにlibs以下の js を書き換えても即座に反映されます。(シンボリックリンクだから当たり前だけど・・・) これまでのバラバラのリポジトリでのモジュール開発ではあっちこっちpullしてビルドして、エラー出たら依存してるバージョン上げてまたビルドして・・・大変でした。 いや、素晴らしいですね! 2. いよいよ TypeScript それではいよいよ Typescript で Workspace に挑戦してみます。 上記のサンプルリポジトリで紹介されている手順 を参考にやってまいりましょう。 2-1. プロジェクトの階層構造を構築 まずは以下の手順でプロジェクトのディレクトリ構成を js の時と同じ手順で構築します。 $ mkdir sample_ts_ws && cd $_ $ npm init -y $ mkdir app $ mkdir -p lib/component-a $ mkdir -p lib/component-b $ cd app && npm init -y $ cd ../lib/component-a && npm init -y $ cd ../component-b && npm init -y $ cd ../.. はい、以下のようになりますね。 結果、以下のようなフォルダ構成のプロジェクトが出来上がります。 sample_ts_ws ├── app │  └── package.json ├── lib │  ├── component-a │  │ └── package.json │  └── component-b │  └── package.json └── package.json 2-2. ワークスペースの宣言 トップの package.json に workspaces を追加します。 sample_ts_ws/package.json { ... "workspaces": [ "libs/*", "app" ] } 続いてnpm iを叩きます。ここまでの結果は同じです。 sample_ts_ws $ npm ls sample_ts_ws@1.0.0 /xxxx/xxxxx/sample_ts_ws ├── app@1.0.0 extraneous -> /xxxx/xxxxx/sample_ts_ws/app ├── component-a@1.0.0 extraneous -> /xxxx/xxxxx/sample_ts_ws/lib/component-a └── component-b@1.0.0 extraneous -> /xxxx/xxxxx/sample_ts_ws/lib/component-b npm ERR! code ELSPROBLEMS npm ERR! extraneous: app@1.0.0 /xxxx/xxxxx/sample_ts_ws/node_modules/app npm ERR! extraneous: component-a@1.0.0 /xxxx/xxxxx/sample_ts_ws/node_modules/component-a npm ERR! extraneous: component-b@1.0.0 /xxxx/xxxxx/sample_ts_ws/node_modules/component-b ... あの。。。なんかエラー出てるんすけど(NPM problem: npm ERR! extraneous)。。。 依存関係がうまく認識されていないっぽいので明示的に依存を追加しました。さっきは大丈夫だったんだけどなぁ。。。なんかあるのでしょう。。。 sample_ts_ws/package.json { .... , "dependencies": { "app": "^1.0.0", "component-a": "^1.0.0", "component-b": "^1.0.0" } } まぁ、これもOKですね。 2-3. TypeScript環境の構築 で、TypeScriptの環境を突っ込んでいきます。 TypeScriptパッケージのインストールとtsconfig.jsonの作成をします。 sample_ts_ws $ npm i -D typescript ... sample_ts_ws $ npx tsc --init message TS6071: Successfully created a tsconfig.json file. 2-3-1. トップのプロジェクトの設定調整 トップのプロジェクトの設定変更です。 以下のように、"compilerOptions"の"composite": true をコメントアウトを解除して有効にします。 sample_ts_ws/tsconfig.json { "compilerOptions" : { .... "composite": true, /* Enable project compilation */ .... } } これがTypescript設定の起点となります。 また"tsconfig.json"とは別にビルド用の設定 "tsconfig.build.json"を作成します。こちらには全ての子コンポーネントを参照に追加しておきます。 sample_ts_ws/tsconfig.build.json { "files": [], "references": [{ "path": "app" }, { "path": "lib/component-a" }, { "path": "lib/component-b" }] } そしてこのファイルを参照するビルドスクリプトを package.json に追加しましょう。 json { ... "scripts": { "compile": "tsc -b tsconfig.build.json", }, ... } トップのプロジェクトはこれでOKです。 2-3-2. ワークスペース側のプロジェクトの設定調整 続いてコンポーネント側に tsconfig.json を追加していきます。 まず、lib/component-a と component-b は依存関係がないので、以下のようなシンプルな tsconfig.json でOKです。 lib/component-a/tsconfig.jsonとlib/component-b/tsconfig.json { "extends": "../../tsconfig.json", "compilerOptions": { "rootDir": "src", "outDir": "dist" } } extendsでトップのtsconfig.jsonを継承しています。 続いて app には上記のコンポーネントを参照したtsconfig.jsonを追加します。 app/tsconfig.json { "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "src", "outDir": "dist" }, "references": [{ "path": "../lib/component-a" }, { "path": "../lib/component-b" }] } で、今回は outDir に dist を指定しました。このパスと package.json の main 属性は合わせておかないとビルドが通らないので以下のように合わせておきましょう。 lib/component-a/package.jsonとlib/component-b/package.json { ... "main": "dist/index.js", ... } 2-4. 動作確認用プログラムの追加 続いてtsのプログラムを作成します。 まずはコンポーネント側から lib/component-a/src/index.ts export const ComponentA = { A : 'A だよ!' }; lib/component-b/src/index.ts export const ComponentB = { B : 'B どす〜' }; もはやscrフォルダを作る方がめんどくさい位ですが。。。 で、このコンポーネントを参照する app 側のコードを作成します。 app/src/index.ts import { ComponentA } from "component-a"; import { ComponentB } from "component-b"; console.log("start app"); console.log(ComponentA.A); console.log(ComponentB.B); VS Code 上ではimport のところで"component-a"と"component-b"ともにコード補完は効くのですが、型が見つからないエラーが出てしまいます。 2-5. 動作確認 これは現時点では放置でコンパイルと動作確認をしましょう。 まずは現時点でのファイル構成をおさらいしておきます。 sample_ts_ws $ tree -I node_modules . ├── app │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── lib │ ├── component-a │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ └── component-b │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── package.json ├── package-lock.json ├── tsconfig.build.json └── tsconfig.json 7 directories, 13 files node_modulesを除外すると上記のような構成になっているかと思います。 それでは以下のコマンドでコンパイルします。 sample_ts_ws $ npm run compile > sample_ts_ws@1.0.0 compile > tsc -b tsconfig.build.json 続いて、生成された index.js を叩いてみます。 sample_ts_ws $ node app/dist/index.js start app A だよ! B どす〜 sample_ts_ws $ cd app && node dist/index.js start app A だよ! B どす〜 ということで無事に module の export がちゃんと効いていることが確認できました! 番外. VS Code でのエラー解消・・・? コマンドラインではちゃんと動いていますが、手元の環境の VS Code では相変わらず"型が見つからないエラー"が出ています。 自分の場合は app/tsconfig.json の設定を適当にいじってエラーを起こし元に戻す で index.ts 側のエラーの表示が消えました。何かしらキャッシュ的な問題があるのでしょう。node v15から対応したばかりだし、ということで大目に見ておきましょうか。。。 それでは、今回は以上といたします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

mocha + chai + SeleniumによるE2Eテスト メモ

mocha + chai + SeleniumによるE2Eテスト方法についてメモする。 e2eテストとは End to Endテストの略称。 システム全体が正しく動作することを確認するテスト。 Webサービスの場合:ユーザと同様にブラウザ操作を行い、サービスが期待通りの挙動をしているか確認する。 mocha テスティングフレームワーク テストを記述する関数群を提供し、それらの関数を使って書かれたテストの結果を判定、集計した上で結果を表示する機能を持つフレームワーク。 以下の記述方法に対応している。 TDD(テスト駆動開発): メソッド動作をテストで表現しながら設計していく考え方 BDD(振る舞い駆動開発): 振る舞い(要求仕様)をテストで表現しながら設計していく考え方 アサーションツールはバンドルされていない。 chai アサーションツール テストの実行結果を判定する。 selenium Web ブラウザの操作を自動化するためのフレームワーク。 テスト以外にもタスクの自動化や Web サイトのクローリングなど様々な用途で利用される。 Selenium を使ってブラウザを自動で操作するには以下をインストールする必要がある。 Web ブラウザ Google Chrome, Firefox, など WebDriver ブラウザを操作するための API を公開するモジュール Selenium WebDriver と通信しプログラムからブラウザを操作するライブラリ 事前準備 node.jsインストール ライブラリインストール npm install -D selenium-webdriver mocha chai chromedriver@89.0.0 ※chromedriverバージョンは使用中のGoogle Chromeバージョンに合わせる。 テストコード test/test.js 表示ページのtitle要素検証 検索ボックス入力によるページ遷移検証。 const { Builder, By, Key } = require("selenium-webdriver"); var chai = require('chai'); var assert = chai.assert; let driver; // テスト対象の宣言 describe("BDD Test", () => { // describeの前に実行される前提条件を記述。 // Google Chrome起動 before(() => { driver = new Builder().forBrowser("chrome").build(); }); // describeの後に実行される後処理を記述。 // Google Chrome終了 after(() => { return driver.quit(); }); // 検証内容を記述。 // 1. 表示ページの`title`要素検証 it("正常系 Qiitaページタイトル検証", async () => { // 指定したURLへ遷移 await driver.get("https://qiita.com"); // title要素を取得する。 const title = await driver.getTitle(); // 検証 assert.strictEqual(title, "Qiita"); }); // 2. 検索ボックス入力によるページ遷移検証。 it("正常系_Qiita検索ページ遷移検証", async () => { // 指定したURLへ遷移 await driver.get("https://qiita.com"); // 検索ボックスに「selenium」を入力し、検索。 await driver.findElement(By.xpath('/html/body/div[1]/div[1]/div/div/div/div[1]/form[1]/input')).sendKeys("selenium", Key.RETURN); // URLを取得 const currentUrl = await driver.getCurrentUrl(); // 検証 assert.strictEqual(currentUrl, "https://qiita.com/search?q=selenium"); }); }); テスト実行 package.jsonにmochaでテスト実行をするnpm scriptを追加する。 "scripts": { "test": "mocha test/test.js --timeout 20000" } 以下のコマンドを実行する。 npm run test 参考情報 JavaScript(Node.js)でSeleniumを使って自動UIテストをする方法 Node.jsとSeleniumでWebアプリのUIテストを自動化(2018年版) mocha / chai チートシート Mochaを使ってJavaScriptのテストをブラウザで実行してみよう mochaとchaiの最も基本的な使い方
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む