2021.09.14リリースのDeno v1.14で、deno.json(Denoの設定ファイル)が導入されした。
元々、DenoにはCargo.tomlやpackage.jsonのような設定ファイルが存在しませんでしたが、import-mapやtsconfig.jsonの一括管理や、lintやfmtの設定を行う目的で設定ファイルが導入されました。
この記事では、設定ファイルの書き方について解説します。
2023.04.27のv1.33以降、設定ファイルの書き方が変更されています (詳しくは後述)。
deno.jsonの特徴
Node.jsにおけるpackage.jsonやtsconfig.jsonの反省を踏まえた設計になっています。
- ブラウザと同様、deno.jsonが無くても動作する(あくまでオプションという扱い)
- ファイル中にコメントを書く場合は、拡張子をjsoncにする必要がある
- 未知のプロパティを許可しない(他のプログラムの設定ファイルとして使うことはできない)
- 外部モジュールの読み込みには関与しない
- ブラウザと挙動を合わせる
- package.jsonの「パスのルートまで遡って設定ファイルを発見する」という動作は、URLからのimport時にサーバーに無駄な負荷をかける
- 実行時のエントリポイントでのみ使用される
- 指定できるのは1ファイルのみ
外部モジュールのトップにdeno.jsonが置いてあったとしても、そのモジュールをimportするプログラムからは単に無視されます。ここがpackage.jsonとの大きな違いです。
deno.jsonの構文
deno.jsonには主に以下の内容を指定できます。
- tsconfig.jsonの設定
- import-mapの設定
- Denoサブコマンドに関する設定(
deno lint
/deno fmt
/deno test
/deno bench
) - ロックファイルの設定
通常はプロジェクトフォルダの1番上にdeno.jsonを設置します。
ファイル中にコメントを書く場合は拡張子をjsonc
にします。
また、Deno v1.34以降、ファイル名はglob展開されるようになりました。(例: **/*.ts
)
なお基本的にデフォルト値のままでも動作するため、task
とimport-mapの設定以外は記述しないことが多いです。
// 注:全てoptionalなプロパティ(指定してもしなくてもよい)
// 基本的にはデフォルト設定で動作するので記述不要。
{
// tsconfig.jsonのcompilerOptionsに相当
"compilerOptions": {
"allowJs": true,
"lib": ["deno.window"],
"strict": true
// ...etc
},
// import-mapのimportsプロパティに相当
"imports": {
// (例)
"lodash": "https://esm.sh/lodash@4.17.21"
},
// import-mapのscopesプロパティに相当
"scopes": {
"https://deno.land/x/example/": {
"https://deno.land/std@0.177.0/": "./patched/"
}
},
// 外部ファイルのimport-mapを使用したい場合に指定する
// コマンドラインフラグに`--import-map=<FILE>`が渡された場合は、その値で上書きされる
"importMap": "./import-map.json",
// deno taskコマンド設定
"tasks": {
// (例) `deno task task_name`を実行すると`echo 1`が走る
"task_name": "echo 1"
},
// deno lintコマンド設定
"lint": {
// lint対象に含めるファイル
"include": ["./include/"],
// lint対象から除外するファイル
"exclude": ["./exclude/"],
// lint対象のルールを指定する
"rules": {
"tags": ["recommended"], // ベースのルールセット (デフォルトは"recommended")
"include": ["ban-untagged-todo"], // tagsで指定したルールに対して追加したいルール
"exclude": ["no-unused-vars"] // tagsで指定したルールに対して除外したいルール
// ルール名は https://lint.deno.land/ を参照
},
// 結果の表示形式
"report": "pretty" // デフォルト
// "report": "compact" // 省略形
// "report": "json" // JSON形式
},
// deno fmtコマンド設定
"fmt": {
// フォーマット対象に含めるファイル
"include": ["./include/"],
// フォーマット対象から除外するファイル
"exclude": ["./exclude/"],
// インデント幅
"indentWidth": 2,
// 1行当たりの文字数
"lineWidth": 80,
// 行末にセミコロンを付加するかどうか
"semiColons": true,
// 引用符にシングルクォーテーションとダブルクォーテーションのどちらを使用するか
"singleQuote": false,
// インデントにスペースとタブのどちらを使用するか
"useTabs": false,
// Markdownファイル内での文章の改行方法
"proseWrap": "always" // 文章をlineWidth幅で改行する (デフォルト)
// "proseWrap": "preserve" // 改行位置を変更しない
// "proseWrap": "never" // 全ての改行を削除する
},
// deno benchコマンド設定
"bench": {
// ベンチマーク対象に含めるファイル
"include": ["./include/"],
// ベンチマーク対象から除外するファイル
"exclude": ["./exclude/"]
},
// deno testコマンド設定
"test": {
// テスト対象に含めるファイル
"include": ["./include/"],
// テスト対象から除外するファイル
"exclude": ["./exclude/"]
},
// フォーマッター、リンター、テスト、ベンチマーク等全てにおいて無視されるファイル
"exclude": ["./node_modules/"],
// npmライブラリの保存場所をnode_modulesディレクトリにするかどうか
// trueにすると、実行時に--node-modules-dirフラグを渡したときと同様の挙動になる
"nodeModulesDir": false,
// ロックファイル(deno.lock)を生成するかどうか
"lock": true
}
上記以外のプロパティがあった場合、エラーが発生します。
glob展開
Deno v1.34以降、ファイル名はglob展開されます。
この機能はrustのglobライブラリを使用して実装されているようです。そのドキュメントによると、使用できる構文は以下のものです。
文法 | 意味 |
---|---|
? |
任意の1文字に一致 |
* |
任意の文字列に一致 (空文字列にも一致) |
** |
カレントディレクトリと任意のサブディレクトリに一致 ただし、 **a やb** , *** のような構文はエラー |
[...] |
括弧内の任意の文字と一致 (例: [0-9] /[a-b] /[abc] )Unicode順に従って文字の範囲を指定することができる |
[!...] |
括弧内にない任意の文字と一致 (例: [!0-9] /[!a-b] /[!abc] ) |
メタ文字(?
, *
, [
, ]
)自体にマッチさせたい時は、各括弧[]
構文を使用してマッチできます。(例: [?]
)
-
[[]
と[]]
はそれぞれ[
と]
という文字に対してマッチする。 -
[![]
と[!]]
も同様に、それぞれ[
と]
という文字以外に対してマッチする。 -
[...]
内で-
という文字にマッチさせたい時は、先頭か末尾に配置する
(例:❌[a-b]
、⭕[-ab]
)
これらのglob展開は、include
/exclude
のファイル名指定のほか、deno task
コマンドでも使用することができます。
構文の変更について
2023.04.27のv1.33以降、設定ファイルの書き方が変更されています (flat config)。
"files": {
"include": ["src/"],
"exclude": ["src/testdata/"]
},
"options": {
"useTabs": true,
"lineWidth": 80,
"indentWidth": 4,
"singleQuote": true,
"proseWrap": "preserve"
}
が
"include": ["src/"],
"exclude": ["src/testdata/"],
"useTabs": true,
"lineWidth": 80,
"indentWidth": 4,
"singleQuote": true,
"proseWrap": "preserve"
に変更されています。
従来形式の設定ファイルを使用すると、以下のようなwarningが表示されます。
従来形式は今夏リリースのDeno v2で使用できなくなる予定ですので、早めに更新しましょう。
Warning: "options" configuration is deprecated. Please use "flat" options instead.
Warning: "files" configuration is deprecated. Please use "include" and "exclude" instead.
deno.jsonの使い方
Deno1.18以降、deno.jsonは自動で読み込みされます。
コマンドライン実行時の設定
コマンドラインから実行する際は、ルートに向かって自動でdeno.json(c)
を探します。最初に見つかったdeno.json(c)
が使用されます。
- ファイル名を指定して実行した場合(例:
deno fmt ./src/serve.ts
)
→ファイルが存在するディレクトリからルートに向かってdeno.json(c)
を探索 - ファイル名を指定せずに実行した場合
→カレントディレクトリからルートに向かってdeno.json(c)
を探索
> deno run ./src/serve.ts # ./srcからルートに向かってdeno.json(c)を探索
> deno fmt ./src/serve.ts # ./srcからルートに向かってdeno.json(c)を探索
> deno fmt # カレントディレクトリからルートに向かってdeno.json(c)を探索
> deno lint # カレントディレクトリからルートに向かってdeno.json(c)を探索
> deno task serve # カレントディレクトリからルートに向かってdeno.json(c)を探索
設定ファイルを強制的に指定して実行したい場合は、コマンドラインフラグの--config
で指定します。
> deno run --config ./deno.json ./mod.ts
設定ファイルを無視したい場合は、コマンドラインフラグで--no-config
を指定します。
> deno run --no-config ./mod.ts
エディタの設定
vscode等の拡張機能からも、自動読み込みが行われます。
強制的に指定する場合は./vscode/settings.json
等のエディタ設定ファイルを開き、deno.config
プロパティにdeno.jsonへのパスを指定します。
{
"deno.enable": true,
"deno.lint": true,
"deno.config": "./deno.jsonc"
}
まとめ
- Deno設定ファイル(deno.json)を使うと、
deno fmt
やdeno lint
の設定やimport-mapの指定を行うことができる - コマンド実行の際には自動で読み込まれる
- 2023年4月のv1.33から書き方が変わったので注意
フォーマッターやリンターの設定については、デフォルト値がスタイルガイドに沿うような形で設定されているため、通常は設定を上書きする必要はありません。
deno.jsonの機能は順次追加されています。
それぞれの機能が導入されたバージョンは、
- v1.14:リンター・フォーマッター・tsconfigの設定をサポート
- v1.18:設定ファイルの自動検出をサポート
- v1.20:import-mapとタスクランナーをサポート
- v1.24:
deno test
サブコマンドの設定をサポート - v1.27:リンターの
report
設定を追加 - v1.29:ロックファイルと
deno bench
コマンドの設定をサポート - v1.30:ファイル中に直接import-mapを記述可能になる / フォーマッタのセミコロン有無設定を追加
- v1.33:flat configの導入で階層構造が変更(#17799)
- v1.34:全コマンドまとめて
exclude
するための設定と、npmライブラリの保存にnode_modules
ディレクトリを使用するかどうかの設定、ファイル名のglob展開に対応
という時系列でした。