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

## はじめに
内容は表題のとおりです。
なお、Google Colab でやるメリットは、今回の内容を試し始める前から特にないと思っていたりしましたが（他に Node.js をホスティングしてくれるサービスもあったりするので、それらを使うほうがオススメ）、「やってみたら動くか気になったので試した」というものです。

### 今回の内容をやろうと思った流れ
最近、Google Colab をちょこちょこ触るようになりました。
<script async class="speakerdeck-embed" data-id="8db17960e47d4677acb42146082a7b89" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

その中で、以下の記事を見つけて、簡単に動作確認をしてみてうまくいきました。
　●Google ColabでJavaScriptしよう - Qiita
　　https://qiita.com/moomooya/items/0d565df082bf4b7019d7

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Google Colab で無事に JavaScript が実行できたｗ <a href="https://t.co/aKdT5CASRB">https://t.co/aKdT5CASRB</a> <a href="https://t.co/f7VmmBwBlD">pic.twitter.com/f7VmmBwBlD</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1378742150842605569?ref_src=twsrc%5Etfw">April 4, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

上記の事例では、以下のコードを動かしてみるところで終わりでしたが、「さらに他の機能も動作させられたりするかな？」と思って、追加でやったのが今回の内容です。

```javascript
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 をインストールします。以下のコマンドを実行します。

```bash
!npm install ngrok express
```

インストールができたら、いったんここで  JavaScript の処理の動作確認を行います。
試しに、以下を実行してみます。

```javascript
console.log(`test`)
```

自分の場合は、ここで必ずシンタックスエラーがでていました。
![シンタックスエラー（ログ出力）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ce7d849c-5c4a-54f2-e24f-42cfc6a607ed.jpeg)

このエラーの対処に関しては、参照元の記事の最後のほうに書かれていた「再読込後のエラー？」という部分の内容が活用できました（自分の手順では、再読込はしていないのですが）。
具体的には、以下の画像で示した部分で行う操作です。
![エラーの解消のための手順.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/91923fd9-1149-7bd2-93f3-e2ffeb745e7b.jpeg)

再度、先ほどのコードを実行すると、今度はうまく処理結果が得られました。
![OK.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/c194f4ab-c617-e3c6-965e-221049b3b504.jpeg)

### ngrok・express のモジュールを組み合わせて動かす
それでは、最後に ngrok と express を使った処理を書いていきます。

今回動かすプログラムの元になるものは、以下の記事に書かれた内容です（この記事の下準備として、自分の PC内で試して書いた内容です）。
　●ngrok と express を組み合わせて Hello World!（ngrok のモジュールを利用） - Qiita
　　https://qiita.com/youtoy/items/f44041689390deb81350

この記事の中のプログラムにちょっとだけ変更を加えて利用します。
変更箇所は最初の 3行です。

```javascript
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` で指定するモジュールは、フルパスで記載する必要があるようです（[上でも参照していた記事](https://qiita.com/moomooya/items/0d565df082bf4b7019d7)の内容より）。
また、ポート番号も適当に変えました。

これを実行した結果が以下です。
![サーバーの実行.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/a1ae0c78-f839-980f-9e97-eacb66e810f0.jpeg)

ngrok で生成された URL にブラウザからアクセスすることで、ブラウザ上で「Hello World!」と表示できるのが確認できました。

あと、上記のプログラム実行を終了させる方法に関して、適したものが何かは分かっていないのですが、「ランタイムの再起動やリセット」を行うことで、外部からのブラウザアクセスができなくなる（ngrok が止まる）のは確認できました。

## おわりに
無事、やろうと思ったことは実現できました。

冒頭に書いたとおり、Google Colab でやるメリットは試し始める前から特にないと思っていたのですが、やってみた後も同様です。本当は、Python と共存させられて機械学習周りの機能と連携させられるとか、Node.js で GPU が使えてそれを活用できる用途がある、とかあれば良いのですが・・・。