Express web framework (Node.js/JavaScript)の勉強 part1
webアプリの知識がないことに対しての危機感と興味からExpress web framework (Node.js/JavaScript) - Learn web development | MDN を読んでみることにした。
個人的に気になったところや手順を残す。
私の開発環境は以下の通り
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.1 LTS Release: 20.04 Codename: focal
Nodeのインストール
はじめに node をインストールする
私の場合は nodenv を使ってインストールした
Hello World
まずは導入のための章であるHelloworld Express の内容を理解する
const express = require('express'); const app = express(); const port = 3000; app.get('/', (req, res) => { res.send('Hello World!') }); app.listen(port, () => { console.log(`Example app listening on port ${port}!`) });
1行目 const express = require('express');
一行目の const express = require('express');
はモジュールをインポートするためのものである。
自作のファイルや、 node_modules
ディレクトリ以下に存在するモジュールをインポートできる。
自作ファイルをインポートする場合には、require(./path/to/myLocalModule);
のように、現在のファイルが存在するディレクトリからの相対パスで表現する。
この表記方法はUnixだけでなくWindowsでも可能と記載されている(手元にWindows環境がないため未確認)
参考
2行目 const app = express();
Expressアプリケーションを作成する。
関数express()
はモジュールexpress
が提供するトップレベルの関数とのことである。
app
オブジェクトは下記の目的のためのメソッドを持つ
この章では"httpリクエストのルーティング"機能を使用する
ちなみに変数名がappという名前は慣習らしい
参考
5〜7行目 app.get('/', (req, res) => { ...以下略
特定のパスへのHTTPのGETリクエストを、特定のコールバック関数へと誘導する。
今回の例ではhttp://localhost:3000/
に対してGETメソッドが呼ばれた場合に、無名関数(req, res) => { res.send('Hello World!')}
が呼ばれる
req
はHTTP Requestを、res
はHTTP Responseを表す。
res.send([body])
によってResponseのボディ部を作成(内容を登録)するようだ
参考
9〜11行目 app.listen(port, () => { ...以下略
3行目で指定されたport=3000を使ってbindし外部からの接続を待つ
第二引数はおそらくサーバが構築したばあいに実行されるコンソールへの出力と予想する
参考
補足:文字列中に変数の値を埋め込む方法
バッククォートをつかうとできるようだ
bashなどになれているため最初はダブルクォートで囲んでしまい、意図通り動かなくて悩んだ
参考
まとめ
- expressではappというオブジェクト作成し、そこに対して例えばgetメソッドを使うことで、特定のメソッドへのルーティングを実現する
device treeにおけるアンパサンド(&)の意味
はじめに
device treeを触っているときの疑問を解消する内容が下記リンクにかかれていた。
linux kernel - Meaning of an ampersand prefix in a device tree - Unix & Linux Stack Exchange
本記事は上記ページを備忘録を兼ねて翻訳しようと思う。
※英語が得意なわけではないので意訳を含みます。誤りがあれば指摘ください。
翻訳
質問
異なるノードを指定しようとするDTSファイルを眺めていたときに、興味深い、いくつかのノードの命名規則を見つけた。
/ { model = "TI AM335x BeagleBone Black"; compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; }; &ldo3_reg { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-always-on; }; &mmc1 { vmmc-supply = <&vmmcsd_fixed>; }; &mmc2 { vmmc-supply = <&vmmcsd_fixed>; pinctrl-names = "default"; pinctrl-0 = <&emmc_pins>; bus-width = <8>; status = "okay"; }; / { hdmi { compatible = "ti,tilcdc,slave"; i2c = <&i2c0>; pinctrl-names = "default", "off"; pinctrl-0 = <&nxp_hdmi_bonelt_pins>; pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; status = "okay"; }; };
ノードの先頭に&
がついている場合どのような影響があるのでしょうか?
- 上の例における
&ldo3_reg
、&mmc1
、&mmc2
のケースです
ノードはルートノードの中に存在できる一方で、ルートノードから分離されている必要性は何でしょうか?
- device treeでは
/
の中がルートノードとして表現されます - 上の例ではルートノードの中に、ノード
hdmi
が存在している一方で、&
から始まるノードは/{ };
の外側に記述されていることを述べていると予想します
興味深いことに、上の例では2つのルートノードが存在します。これは問題ないのでしょうか?
- 先頭と末尾の方に存在する2つの
/
を示していると予想します
回答
https://developer.toradex.com/device-tree-customization より
ノードはampersand(&)とラベルを用いて参照可能です
プロパティの上書き
プロパティを上書きする場合、ノードはampersandとラベルを使って参照される必要があります
後に記述されたdevice treeのエントリーは、それより以前に記述されたエントリーを上書きします(エントリの順番は重要であり、したがってインクルードの順番も重要です)
一般的に高いレイヤ(キャリアが作成するボードのためのdevice tree)は、低いレイヤ(例えばSoCのdevice tree)を上書きします。
- 高いレイヤ = dtsファイル、 低いレイヤ = dtsiファイル と考えれば良いかもしれません。
これを実現するために高いレイヤ(のdevice tree)は低いレイヤ(のdevice tree)を最初に取り込みます(includeします)
例えば、デバイスもしくはホストになれる(デュアルロールな)USBコントローラは、dr_modeをプロパティを使い明示的にデフォルトモードを上書きします
&usbdev0 { dr_mode = "host"; };
まとめ
プロパティの上書きのためには&label
の形式が必要ということを知った
ただ、上記がdevice treeの公式のページか不明なので、公式なページで明言されているならば知りたい