- Deno と Deno Deploy ハンズオン
- 0. このセクションの目標
- 1. まず、Deno って何?
- 2. さっそく、Deno をインストールしましょう
- 3. Deno 使ってみよう
- 4. (発展) サンプルプロジェクトのコードを読んでみよう
- 5. Deno Deploy を用いてコードをデプロイしてみよう
- 5-1. 実際にデプロイしてみる
- 6. まとめ
このセクションでは以下の項目を身につけましょう!
deno runコマンドで TypeScript ファイルを実行できる 💪- Deno Deploy を用いてコードをデプロイして、他の人が見られるようにする 🚀
その他発展的内容も記載しています。
- Deno でコードをリントしてみよう
- Deno でコードをフォーマットしてみよう
- Deno でコードをテストしてみよう
- サンプルプロジェクトのコードを読んでみよう
Deno とは、JavaScript や TypeScript で書かれたコードを実行する環境です。
公式サイト >
![]()
Deno がインストールされた環境でdeno run <ファイル名>のコマンドを実行することで、JavaScript や TypeScript で書かれたファイルを実行できます。
Deno はコードを実行する機能以外にも、コードをリントしたり、コードをフォーマットしたり、コードをテストしたりできる機能が初めから備わっていて大変便利です。
このセクションではサンプルプロジェクトを用意しています。これから Deno をインストールして、書いたコードを実行してみましょう!
早速、Deno を以下のリンク先からインストールしてみましょう。
基本的には公式サイトの手順を参考にします。
ターミナルを準備してから、公式サイトのコマンドをコピーしてターミナルに貼り付けてインストールしてみましょう。
ターミナルはWindowsならpowershell、Mac OSならターミナルなどがありますが、なんでも大丈夫です。
Mac OS の人はhomebrewというパッケージ管理ツールをインストールして、そのhomebrewを使用してDenoをインストールすると今後も便利そうです。
サンプルプロジェクトのコードを Deno で実行してみよう。
-
VSCode で、
intern-dev-tutorial/denoを開きましょう。 -
VSCode の拡張機能のタブから「Deno」を検索してインストールしよう。
- VSCode の上のヘッダーの「表示」から「コマンドパレット(Command Palette)」を押す。
- 「Deno: Initialize Workspace Configuration」を選択する。
- VSCode の上のヘッダーの「ターミナル」から「新しいターミナル」を押して、ターミナルを表示しておこう
Deno を有効化すると、現在のフォルダに.vscodeというフォルダが作成されて、中にsettings.jsonというファイルが作成されます。
今回は VSCode で Deno を快適に使用できるようにするためこのような設定をします。
settings.jsonは、 Deno を使用する上での設定を登録できるファイルです。
準備に沿って設定すると、以下のような内容になっています。
{
"deno.enable": true
}このセクションでは、Deno で JavaScript ファイルを実行する方法を学びます。
Deno では JavaScript ファイルをrunコマンドを用いて以下のようにして実行できます。
deno run <ファイル名>では、早速 Deno でこのプロジェクトの直下にあるserver.jsを実行してみましょう。
ターミナルで以下のテキストを入力して Enter を押してみましょう。
deno run server.js実行すると以下のような文言がターミナルに表示されます。
┌ ⚠️ Deno requests net access to "0.0.0.0:8000".
├ Requested by `Deno.listen()` API.
├ Run again with --allow-net to bypass this prompt.
└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) >一旦は深く考えずにyを入力していきましょう。
そうすると以下のような文言がターミナルに表示されます。
Listening on http://localhost:8000/では、ブラウザのアドレスバーに http://localhost:8000 のアドレスを入力して検索してみましょう。
検索してみても画面が切り替わらないですね。 ここでターミナルの方を見てみましょう。
┌ ⚠️ Deno requests read access to "public".
├ Requested by `Deno.stat()` API.
├ Run again with --allow-read to bypass this prompt.
└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) >このような文言が表示されているので、先ほど同様にyを押してみましょう。
ブラウザに戻ってみて、以下のような画面が表示されれば成功です!
インターンへようこそ!
Deno で JavaScript ファイルのserver.jsを無事実行できました! 簡単ですね!
実行されたコード内で「ファイルの読み込み/書き込み」や「ネットワーク通信」の処理が走るとその時点でコンソールに確認の文言が表示され、そのまま実行するか拒否するかの選択を促します。
改めて先ほど表示された文言を確認してみましょう。
┌ ⚠️ Deno requests net access to "0.0.0.0:8000".
├ Requested by `Deno.listen()` API.
├ Run again with --allow-net to bypass this prompt.
└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) >
Deno が`0.0.0.0:8000`にアクセスしようとしています。許可するには`y`、拒否するには`n`、以降全てのネットワーク権限を許可するには`A`を入力してください先ほど表示された文言は上記のようになっており、ネットワークへのアクセスを許可するためにyを押したということになります。
一方で、ブラウザでhttp://localhost:8000へアクセスした時に表示された以下の文言は以下のような内容でした。
┌ ⚠️ Deno requests read access to "public".
├ Requested by `Deno.stat()` API.
├ Run again with --allow-read to bypass this prompt.
└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) >
public フォルダ内のファイルの読み込みを行おうとしています。許可するには`y`、拒否するには`n`、以降全ての読み込み権限を許可するには`A`を入力してくださいこのように Deno はデフォルトでは「ファイルの読み込み/書き込み」、 「ネットワーク通信」を許可しない限りは一切実行できません。
この仕組みにより、Deno では高いセキュリティが期待できます。
しかし、毎回実行するたびにyを入力するのは面倒ですよね。
runコマンドにオプション指定をして毎回yを入力しないようにしてみましょう。
deno runをするときに、それぞれ以下のような対応のオプション指定をしてあげると、権限を許可できます。
-
ファイルの読み込み ->
--allow-read -
ファイルの書き込み ->
--allow-write -
ネットワーク通信 ->
--allow-net
今回の場合「ファイルの読み込み」と「ネットワーク通信」の権限を与える必要があったので、以下のように実行してあげるとターミナルに警告文が表示されずに実行できます!
deno run --allow-read --allow-net server.jsオプションを指定したコマンドを実行して、警告文がでないことを確認してみましょう。
また、--watchオプションについても知っておくと良さそうです。
--watchオプション指定をしておくことで、
server.jsを編集した時に再度コマンドを打って実行しなおさなくても Deno が勝手に再実行してくれるので便利です。
--watchオプション指定を加えたコマンドでserver.jsを実行してみましょう。
最終的なコマンドは以下のようになります。
deno run --watch --allow-read --allow-net server.js前のセクションでは以下のコマンドでserver.jsが実行できることを学びました。
deno run --watch --allow-read --allow-net server.jsしかし、このコマンドで毎回実行しようとすると以下のようなデメリットが考えられます。
- 毎回これを打つのは長い
- どの権限を許可していたか忘れたら、一度実行しないといけない
- 結局このコマンドをどこかにメモなどに保存する流れになりそう
このようなデメリットを解決する方法として、taskコマンドがあります!
このセクションではtaskコマンドについて学んでいきますが、
チーム開発では無理に使う必要はなく、runコマンドで毎回実行しても問題ないです。
taskコマンドは以下のようにして実行します。
deno task <タスク名>では、このタスク名はdeno.jsonファイルで設定しています。
deno.jsonファイルの以下の部分をみてみましょう。
"tasks": {
"start": "deno run --watch --allow-net --allow-read server.js"
},ここには、実行したいコマンドに別名(タスク名)を与えることができます。
deno run --watch --allow-net --allow-read server.jsにstartと言う別名を与えるように設定しています。
よってdeno task startに実行するとdeno run --watch --allow-net --allow-read server.jsを実行していることと同じになります。
deno task startとてもスッキリして良さそうです!
もし追加でファイルの書き込み権限を与えるために--allow-writeオプションを追加したいとなっても、deno.jsonのstart部分のコードを修正するだけで良いです。
このセクションではtaskコマンドについて学びました。 便利コマンドなのでぜひ使ってみてください!
このセクションでは、Deno で JavaScript ファイルをリントする方法を学びます。
Denoには JavaScript ファイルをリントする機能が標準で備わっています。
リントとは、「与えられたルールに基づいて、潜在的にバグとなりうるソースコードを チェック すること」です。
例えば以下のようなものが挙げられます。
- ソースコード内に未使用の変数が存在する
- ソースコード内に初期化されていない変数が存在する
この機能を使うことで意図してないミスを未然に警告してくれて大変に役立ちます。
JavaScript ファイルをリントするには以下のようなコマンドでできます。
deno lintとても簡単にできます。
このリントで参照するルールはdeno.jsonのlint部分で設定されています。
"lint": {
"include": ["./**/*.js"],
"rules": {
"tags": ["recommended"],
"include": ["ban-untagged-todo"],
"exclude": ["no-unused-vars"]
}
}今回のこの設定はDeno 公式サイトの設定をコピーしたものです。
Deno でリント時に参照されるルールの一覧はDeno のリントルールで確認できます。
今回の設定ではtagsにrecommendedが指定されているので、上記のサイトのルール一覧の中からrecommendedタグがついているもの全て適用しています。
また、includeによって追加でban-untagged-todoルールを適用し、excludeによってno-unused-varsルールを除外しています。
recommendedルールでは、他の有名なリンターの
ESLint や typescript-eslint で recommended として扱われているルールの多くをサポートしています。
では、一度リントエラーを起こしてみましょう。
server.jsを開いて一番下の行に以下の行を追加して、Ctrl + Sで保存してみましょう。
var message = "Jig.jpインターンへようこそ!";保存ができたらターミナルで以下のコマンドを実行してみましょう。
deno lintそうすると以下のような結果が表示されます。
(no-var) `var` keyword is not allowed.
var message = 'Jig.jpインターンへようこそ!';
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
at /Users/fujii/dev/deno-sample-project/server.js:27:1
help: for further information visit https://lint.deno.land/#no-var
Found 1 problem
Checked 3 filesこれは「var は使わないでください」といった警告文です。(詳細なルール: no-var)
どのファイルの何行目まで表示してくれて便利です。
このように、lintコマンドを実行すると、あらかじめ決めておいた「ルール」を元に、それにそぐわないコードがないか チェック します。
チーム開発でもリントを使って、潜在的にバグとなりうるコードがないかチェックしてみましょう!
このセクションでは、Deno で JavaScript ファイルをフォーマットする方法を学びます。
Denoにはファイルをフォーマットする機能も標準で備わっています。
フォーマットするとは「コードの形を整える」ことです。
このフォーマットを使用することでどの人がコードを書いても同じようにコードを整えられるので、
人によってコードの形がバラバラになるといったことが起こらず便利です。
自分 1 人で開発している時であっても、適当に書いたコードをきれいに整えてくれるのでありがたいです。
JavaScript ファイルをフォーマットするには以下のようなコマンドでできます。
deno fmtこれも簡単ですね。
このコマンドを実行するとカレントディレクトリ以下の JavaScript ファイル全てに対してフォーマットします。
フォーマットの設定は、deno.jsonのfmt部分で設定されています。
こちらもリントと同様に、公式サイトの設定をコピーしたものです。
"fmt": {
"useTabs": true, // タブを使用するか
"lineWidth": 80, // 一行の文字数
"indentWidth": 4, // インデントの文字数
"semiColons": true, // セミコロンをつけるかどうか
"singleQuote": true, // シングルクォートを使用するかどうか
"proseWrap": "preserve",
"include": ["./**/*.js"],
}基本的にはこの設定で十分ですが、ルールを変更したい時にはこちらの設定をいじりましょう。
設定できるフォーマッタの種類については公式サイトから確認できます。
では、実際にフォーマットしてみましょう!
deno fmtをターミナルに打ち込んで Enter をしてみましょう。
Checked 3 files
のような文言が表示されました。
では、server.jsの中身を見て何か変化はありましたでしょうか?
おそらくないはずです。
すでに指定されたルールに則って、フォーマット(整形)してあったからです。
では試しに、フォーマットのルールを変えてみましょう。
deno.jsonのfmt部分の
semiColonsの部分をfalse, singleQuoteの部分をtrueに書き換えてみましょう。
以下のようになります。
"fmt": {
"useTabs": false,
"lineWidth": 80,
"indentWidth": 2,
"semiColons": false, // trueからfalseに変更した
"singleQuote": true, // falseからtrueに変更した
"proseWrap": "preserve",
"include": ["./**/*.js"]
},そして再度、deno fmtを実行し, server.jsの中身を見てみましょう。
-
行末にセミコロン(;)がない
-
文字列はすべて('')で囲まれている
のように修正されていますね。
このようにdeno fmtを使用することでコードを整えてくれます。
チーム開発でもこのフォーマット機能を利用してきれいなコードにしていきましょう!
このセクションでは、Deno で JavaScript ファイルをテストする方法を学びます。
Deno には JavaScript ファイルをテストを実行する環境も標準で備わっています。
テストには手動テストと自動テストがあります。
-
手動テストは、実際に手を動かして動作確認するもの
-
自動テストは、コードが正しく動作されるかテストする、テスト専用のコードが書かれたファイルを実行すること
で、Deno に備わっているのは「自動テスト」が行える環境です。
自動テストが行える環境を構築するのはやや大変ですが、Deno では標準で備わっているためとても便利です。
自動テストコードを書いてテストを実行することで、以下のようなメリットがあります。
- コードが適切に動作することに安心できる
- 1 回の実行で全てのテストファイルを実行できるので手動でテストするよりも効率がいい
- 自分が修正した範囲以外で悪影響がないことを安心できる
JavaScript ファイルをテストするには以下のようなコマンドでできます。
deno testこれも簡単ですね!
テストの設定に関しても以下のように、deno.jsonのtest部分で設定しています。
この設定では、末尾に.test.jsがついているファイルを実行するように指定しています。
"test": {
"include": [
"./**/*.test.js"
]
}では早速テストコードを実行してみましょう。
ターミナルに以下のコマンドを入力して Enter を押してみましょう。
deno testすると、以下のような文言が表示されます。
running 1 test from ./sample.test.js
1 + 1 は 2 である ... ok (9ms)
ok | 1 passed | 0 failed (89ms)./sample.test.jsの「1+1 は 2 である」というテストが 1 つ実行され、OK でしたと表示されています。
ではsample.test.tsの中身を以下のように修正し保存して、deno testを実行してみましょう。
assertEquals(1 + 1, 2);
↓
assertEquals(1 + 1, 3); // 3に修正すると今度は以下のような文言が表示されます。
1 + 1 は 2 である ... FAILED (10ms)
ERRORS
1 + 1 は 2 である => ./sample.test.js:3:6
error: AssertionError: Values are not equal.
[Diff] Actual / Expected
- 2
+ 3
throw new AssertionError(message);
^
at assertEquals (https://deno.land/std@0.193.0/testing/asserts.ts:188:9)
at file:///Users/fujii/dev/deno-sample-project/server.test.js:5:3
FAILURES
1 + 1 は 2 である => ./sample.test.js:3:6
FAILED | 0 passed | 1 failed (24ms)
error: Test failedこのようにもし自動テストで失敗したテストがあれば、以下の情報が表示されます。
-
自動テストが失敗したこと
-
どのテストが失敗したか
-
失敗した箇所
-
期待された値とテスト時に渡された値
このようにDenoでは、テストを行える環境が標準で備わっています。
より詳しい Deno での自動テストに関する記事は公式サイトをみて見てください。
ここからはいままで実行してきたserver.jsやこのディレクトリのファイル構造についてみていきましょう。
それぞれのファイルの役割を説明していきます。
deno.jsonDenoであれこれ実行させるときに必要な設定ファイルtask,lint,fmt,testなどの様々な設定ができる。importsに関しては後ほど説明
server.js- このサンプルプロジェクトのサーバー部分。
- ブラウザからのアクセスに対して、表示させたいファイルや文言を返す処理が書かれている。
- 先ほど
deno task startで実行させていたファイル
sample.test.js- テストコードが書かれたファイル
deno testで実行させていたファイル
public/- ブラウザからリクエストが来た時に、
server.js内の処理によってブラウザに返されるファイル類 index.html- ブラウザに表示するファイル
styles.css- スタイリングを指定するファイル
index.js- ブラウザからサーバーにアクセスする処理が書かれたファイル
- ブラウザからリクエストが来た時に、
このセクションではserver.jsを読みながら以下のことを学んでいきましょう!
-
ESModule の形でファイルを読み込む方法
-
import map を使う方法
-
クライアント側からの API リクエストに対して、ファイルや文字列を返す方法
まずは「ESModule の形でファイルを読み込む方法」について学んでいきます。
Deno で「外部からファイルを取り込む」時はESModuleというファイルの読み込みの仕組みを採用しています。
ESModuleの特徴は以下のようなものが挙げられます。
import,exportを用いて取り入れ/公開を制御できる- ファイルを実行するときに、勝手に
import先からコードを参照するため、複数のファイルを読み込む必要がなくなる
以下のようにしてその JavaScript ファイルに必要な外部の変数やメソッドを取り込むことができます。
import { <変数>, <メソッド> } from "JavaScriptファイルのPathやUrl"また、htmlファイルから JavScript ファイルを読み込みたい時がありますが、
その場合はtype="module"を付与して以下のようにします。
<script type="module" src="JavaScriptファイルのPathやUrl"></script>server.jsの最初の行で行っているように外部のserveDirメソッドを取り込むことは以下のようにしてできます。
import { serveDir } from "jsr:@std/http/file-server@1.0.17";しかし、実際のserver.jsで書かれているコードは少し違っていますね。
そのことに関しては次のセクションで学びましょう。
上記のコードで書いても問題なく動くため安心してください。
このセクションではESModuleと言う形で外部のファイルを取り込む方法を学びました!
前のセクションで以下のように外部の変数やメソッドを取り込む方法を学びました。
import { serveDir } from "jsr:@std/http/file-server@1.0.17";ここで、Deno のimport mapと言う機能を使ってみましょう。
まずdeno.jsonのimport部分をみてみると以下のようになっています。
"imports": {
"@std/http": "jsr:@std/http@^1.0.17"
},この設定によって JavaScript ファイルで外部のファイルにアクセスするとき、
jsr:@std/http/file-server@1.0.17は@std/httpでアクセスできるようになりました。
よって以下のように書き換えることができます!
import { serveDir } from "@std/http";スッキリして良さそうですね。
import mapと言う機能を使用することで以下のようなメリットがあります。
-
毎回 URL を直書きする必要がなくなる
-
可読性が上がる
-
使用する外部のファイルのバージョンを固定できる
-
バージョンの変更は
deno.jsonのimport部分の URL の数字を変えるだけで全てのファイルに適用される -
deno.jsonのimport部分を見るだけで、このプロジェクトで使用されているライブラリの一覧を確認できる
ぜひ使ってみましょう!
このセクションではimport mapと言う機能の使い方や使用するメリットを学びました。
クライアント側からの API リクエストに関する処理を学びましょう!
-
API リクエストの種類を判別する処理
-
ファイルを返す処理
-
文字列を返す処理
まずクライアント側からの API リクエストを受け付ける処理は以下のようにserve関数で行います。
/**
* APIリクエストを処理する
*/
Deno.serve((req) => {
// リクエストに対する処理の中身
});このreq変数を用いて API リクエストのmethod部分とpath部分を見ていきます。
API リクエストにはmethodというものがあり、以下のようなものがあります。
-
GET (取得)
-
POST (送る)
-
PUT (更新)
-
DELETE (削除)
また API リクエストのpathというものはGET http://localhost:8000/welcome-messageの/welcome-message部分を指します。
server.jsでは、API リクエストのmethodがGETで、pathが/welcome-messageの時にreturn new Response(<文言>)で文言を返しています。
以下の箇所で行っています。
// URLのパスを取得
const pathname = new URL(req.url).pathname;
// パスが"/welcome-message"だったら「"jigインターンへようこそ!"」の文字を返す
if (req.method === "GET" && pathname === "/welcome-message") {
// 文言を返す
return new Response("jig.jpインターンへようこそ!👍");
}それ以外の時、例えばhttp://localhost:8000/にアクセスした時は、
path が/なので以下のように public フォルダをクライアントに返しています。
// publicフォルダ内にあるファイルを返す
return serveDir(req, {
fsRoot: "public",
urlRoot: "",
showDirListing: true,
enableCors: true,
});よって、deno runを実行してから、http://localhost:8000/にアクセスするとpublic内のindex.htmlのページが表示されるんですね。
クライアント側で表示されるindex.htmlから読み込まれるindex.jsを読んでいきましょう。
index.jsの読み込み方法は以下のように、「3-7-2. (発展) ESModule の形でファイルを読み込む」でも説明しましたように ESModule の形で読み込んでいます。
<script type="module" src="./index.js"></script>index.jsをみてみましょう。
addEventListener('load', async () => {
...
});この部分は「ページ全体が、スタイルシートや画像などのすべての依存するリソースを含めて読み込まれたときに発生します」というものです。(MDN: loadイベント)
中のコードを見ていきます。
const response = await fetch("/welcome-message");ここではfetch APIを使用しています。 fetch メソッドは引数でpathを指定して、サーバーにリクエストを送ります。
この場合、引数が/welcome-messageになっているので、現在開いているアドレスのホスト名のhttp://localhost:8000に path の/welcome-messageをくっ付けてhttp://localhost:8000/welcome-messageにアクセスします。
先ほどの「4-4. (発展) クライアント側からの API リクエストを処理」でも説明しましたように、この API リクエストに対してクライアント側に"jig.jpインターンへようこそ!👍"という文字を返しています。
以下のコードでindex.html内にあるid="welcomeMessage"の要素を探して、"jig.jpインターンへようこそ!👍"の文字を入力しています。
document.querySelector("#welcomeMessage").innerText = await response.text();これでhttp://localhost:8000/へアクセスした時に、「jig.jp インターンへようこそ!」の文言が画面に表示されるサンプルプロジェクトの流れを追うことができました。
ここでは自分のコードをデプロイする方法を学びましょう。
前のセクションまでは手元のコンソールでdeno run <ファイル名>のコマンドを入力して、ブラウザから http://localhost:8000/にアクセスしてページを表示していました。
しかし、その状態のままでは他の人に自分のサイトを表示させることができないですね。
他の人にも自分のサイトをみてもらえるようにデプロイを行いましょう。
デプロイとは、開発したアプリケーションを実際に外部の環境に配置し、運用を開始する作業を指します。
このセクションでは Deno Deploy を用いて、deno run <ファイル名>を外部のサーバーで実行させることで、指定された URL から誰でもそのサイトを見ることができるようにします。
Deno を用いた開発をしているのであれば、Deno Deploy を使用することでとても簡単にコードをデプロイできます。
Deno Deploy の公式サイト を開きましょう。
まずは自分の GitHub アカウントでログインしましょう。
ログインできたら「Overview」の画面の右上にある「New Project」ボタンからプロジェクト作成画面に移動しましょう。
自分が作成したプロジェクトを選択しましょう。
もしここに作成したプロジェクトが表示されない場合は、「Modify GitHub Permission」をクリックして、GitHub の設定画面に遷移してください。
「Repository access」の項目で Deno Deploy からアクセスできるリポジトリ(プロジェクト)を選択できます。「Select Repositories」から自分が作成したプロジェクトを選択して、「Save」ボタンで保存しましょう。
保存し終えたら Deno Deploy の画面から再度自分が作成したリポジトリを選択しましょう。
選択したら、「Entrypoint」の欄からdeno runで実行したいファイルを選択します。deno run server.jsとしたい場合はserver.jsを選択します。
「Entrypoint」のファイルを選択し終えたら、「Deploy Project」ボタンからデプロイを行いましょう!
デプロイが完了したらダッシュボード画面に遷移します。
その画面の「Domains」の箇所に記載されている URL をクリックすることでサイトにアクセスできます!
コードを書かずにポチポチ選択するだけでデプロイできました! 簡単ですね!
このセクションの初めに以下の目標を立てましたが、達成できましたでしょうか?
このセクションでは以下の項目をマスターしましょう 🎉
deno runコマンドで TypeScript ファイルを実行できる 💪- Deno Deploy を用いてコードをデプロイする方法を理解する 🚀
他の発展的な内容もとても便利な機能ばかりですので、ぜひ実際に開発する時には Deno の様々な機能を活用してみてください!










