NBBとExpressJSによる再ロードされたワークフロー
35242 ワード
nbb ( nが表すものは何でも😄 ) 魅力的なプロジェクトです.それは力をもたらす
このブログ記事のコードを見ることができますhere . 供給this 依存関係として
このプロジェクトのための強力な学習体験は、“ハローワールド”のWebサーバー、コマンドライン引数解析、およびデータベースをシミュレートする状態管理から成ります.
道に沿って、私は依存管理とツーリングについて何かを学ぶべきです.
ほとんど信じられないけど
NREPLサーバを起動するには
それから、スペースマックで
現在働いていないものがたくさんあります
これまでのところ
始めましたyargs , そして機能している間に Yargsはコマンド/オプションに関する議論を支持します. ユーザー引数を最初に提供することなく、コマンドとオプションを記述できない方法を次のコードに示します.
糸は処理後にプロセスを殺す この動作はREPLでテストを難しくするので理想的ではありません.私は新しいプロセスを始めることなくヘルプ命令を作ることができなければなりません.
幸運にも、パッケージされたBorkdude
アプリケーションのエントリポイントは、コマンドライン引数がvarargsとして渡される' main '関数です.
まず、作成
の定義を変えましょう
この次の課題は確かに私にいくつかのトラブルを与えたが、3つの発見は非常に助けた.3 エー スクリプトを引数として渡すべきではありません.代わりに、CLASSPATHにある あなたがすべてのスクリプトを中央のディレクトリに加えることができて、あなたのシェルinitでそのディレクトリをデフォルトで含むことができて、彼らの名前またはファイルシステム場所を指定せずにあなたのスクリプトを走らせるので、Count - 2は特に顕著です.
あなたが保存したディレクトリから実行していると仮定します
インストールプロセス
あなたがclojure生態系に慣れていないならば、「再ロードされたワークフロー」と呼ばれているスチュアートシエラによってトレンディされた考えがありますほとんどの大きなクロージャアプリケーションが使用し、そこから選択する多くのライブラリがあります.
基本的な考え方は、それがすぐに停止し、主要なプロセスを停止せずにstatutiveリソースを起動する方法を提供することです.それはキラーreplの経験の必要性です.5
オプションを見直した後にweavejester/integrant 小さいので、1つだけ依存し、2つのソースファイルを合計します.
インテグラントは
カット機能のショートリスト: ESN設定 仕様検証 それは
まず、ハンドラを定義しましょう.
Inteantで始まる最高の場所はConfigマップです.
次に、どのようにすべてを起動するには、積分を教えてください.このプロセスは、
私たちはカップルを定義します
あなたはそれに気づくかもしれない
多分、それはすでにします:私は、専門家です.しかし、あなたがそうでない異なるサーバーに変わるならば、どうですか?それは私たちのフックに良いかもしれない
このプロセスの間、私が遭遇した唯一の'バグ'は、リクエストハンドラを
好きです
私は、それが私をそれから使うのを止めると思いません.
Emacsはそれがclojure replであると思います、しかし、それはNBBサーバーに接続しています-我々は少し混乱しました.畝↩
後で新しい発見
ほとんどのExpressjs“こんにちは、世界”チュートリアルはここで停止します.畝↩
私の経験では、“clojure”が自動的に変更されたコンポーネントをeval(およびそれらの依存関係)を再起動します.私はどのツールがこの機能を提供するかわからない.そして、私はそれがこのアプローチで働くかどうか決定する運命を誘惑しませんでした.😁畝↩
SQLiteのような実際のデータベースを使用して次のように良い学習ステップになります.畝↩
babashka
to nodejs
. 私は今週、それで遊んで、私が見つけたものを共有したいです.それはかなりクールです!TLドクター
このブログ記事のコードを見ることができますhere . 供給this 依存関係として
clj -Spath
and nbb --claspath
.ハローワールド
このプロジェクトのための強力な学習体験は、“ハローワールド”のWebサーバー、コマンドライン引数解析、およびデータベースをシミュレートする状態管理から成ります.
道に沿って、私は依存管理とツーリングについて何かを学ぶべきです.
ツーリング
ほとんど信じられないけど
nbb
NREPLサーバを起動できます.Emacsでは、すべてのクロージャモードコマンドが正しく動作しないということはちょっと面倒です.NREPLサーバを起動するには
nbb nrepl-server
.それから、スペースマックで
.cljs
ファイル.Then SPC m i
( sesman-start
) とlocalhostに接続します.cider-connect-clj
. この操作は、NREPLサーバに甘い2次元バッファを接続します.現在働いていないものがたくさんあります
cider-switch-to-repl-buffer
) 1 , しかし、あなたはそれに切り替えることができますSPC b b
( list-buffers
).これまでのところ
nbb
's NREPLサーバーは、開発のこの初期段階で、ポーランドで私を吹き飛ばしました.ヤルでコマンドライン引数を解析します。
始めましたyargs , そして機能している間に
yargs
理想的ではなかった.(-> argv # argv should be unecessary
yargs
(.command ...)
(.options ...)
--help
幸運にも、パッケージされたBorkdude
tools.cli
with v0.3.0
NBBの.もちろん、サブコマンドを使う必要があるならば、Yargsはより良いオプションであるかもしれませんtools.cli
今のところ.ツールでコマンドライン引数を解析します。CLI
tools.cli
クロジュールと同じ作品.お気軽にこのセクションをスキップしてくださいtools.cli
.アプリケーションのエントリポイントは、コマンドライン引数がvarargsとして渡される' main '関数です.
nbb
また、SEQに引数を詰め込み*command-line-args*
.まず、作成
hello_world.cljs
次にファイルをペーストします.(ns hello-world
(:require [clojure.tools.cli :as cli]))
(def default-port 3000)
(def cli-options
[["-p" "--port PORT" "Port number"
:default default-port
:parse-fn js/Number
:validate [#(< 1024 % 0x10000) "Must be a number between 1024 and 65536"]]
["-h" "--help"]])
(defn handle-args [args] (println args))
(defn main
[& args]
(handle-args
(cli/parse-opts
args cli-options)))
REPLでこれを試してみてくださいtools.cli
作品hello-world> (main)
{:options {:port 3000}, :arguments [], :summary -p, --port PORT 3000 Port number
-h, --help, :errors nil}
hello-world> (main "--port" "9093")
{:options {:port 9093}, :arguments [], :summary -p, --port PORT 3000 Port number
-h, --help, :errors nil}
hello-world> (main "--help")
{:options {:port 3000, :help true}, :arguments [], :summary -p, --port PORT 3000 Port number
-h, --help, :errors nil}
hello-world> (main "--port" "foobar")
{:options {:port 3000}, :arguments [], :summary -p, --port PORT 3000 Port number
-h, --help, :errors [Failed to validate "--port foobar": Must be a number between 1024 and 65536]}
cli/parse-opts
コマンドライン引数を処理するために必要なすべてのコンポーネントを含むマップを生成します.2 :options
: アプリケーションが使用するパラメータ:summary
: ヘルプドキュメント用にフォーマットできる文字列:errors
: 妥当性検査エラー.ここでカスタムエラーメッセージを見ることができます.handle-args
何か役に立つことをする.(defn start-app [{:keys [port]}]
(println "starting server on port" port))
(defn print-help [summary]
(println "hello world server")
(println summary))
(defn print-errors
[{:keys [errors summary]}]
(doseq [e errors]
(println e))
(print-help summary))
(defn handle-args
[{:keys [options summary errors] :as args}]
(cond
(seq errors) (print-errors args)
(:help options) (print-help summary)
:else (start-app options)))
再びRPLから同じことを実行すること自由に感じなさい.あなたが何を渡すかに関係なく、フォーマットされたテキストを見るべきです.端末からの走行
この次の課題は確かに私にいくつかのトラブルを与えたが、3つの発見は非常に助けた.3
--main <ns>/<fn>
パラメータをnbb
コマンドライン.--classpath <dir1:dir2:...>
. nbb
自動的にクラスパスにカレントディレクトリが含まれます.あなたが保存したディレクトリから実行していると仮定します
hello_world.cljs
.$ nbb --main hello-world/main --help
hello world server
-p, --port PORT 3000 Port number
-h, --help
$ nbb --main hello-world/main
starting server on port 3000
$ nbb --main hello-world/main --port 9093
starting server on port 9093
$ nbb --main hello-world/main --port foobar
Failed to validate "--port foobar": Must be a number between 1024 and 65536
エクスプレスズ
インストールプロセス
expressjs
あなたがnodejsに精通しているならば、mundaneです.ファーストランnpm install express
式を取得するには次に、名前空間のフォームを変更してプロジェクトに利用可能にします.(ns hello-world
(:require [clojure.tools.cli :as cli]
["express$default" :as express]))
次のコードでサーバーを起動することができますが、まだそれをしないでください.簡単に迂回する必要がある.4 (.listen
(doto (express)
(.get "/" (fn [_ res]
(.send "hello, world"))))
default-port)
再ロードされたワークフロー
あなたがclojure生態系に慣れていないならば、「再ロードされたワークフロー」と呼ばれているスチュアートシエラによってトレンディされた考えがありますほとんどの大きなクロージャアプリケーションが使用し、そこから選択する多くのライブラリがあります.
基本的な考え方は、それがすぐに停止し、主要なプロセスを停止せずにstatutiveリソースを起動する方法を提供することです.それはキラーreplの経験の必要性です.5
オプションを見直した後にweavejester/integrant 小さいので、1つだけ依存し、2つのソースファイルを合計します.
インテグラントは
nbb
現在の状態では、私はいくつかの機能を削除し、今はうまく動作します.Githubプロジェクトを見るcrinklywrappr/integrant .カット機能のショートリスト:
npm
ノード依存性とclj
clojure依存性のために.$ classpath="$(clj -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.crinklywrappr/integrant {:git/tag "v1.0.3" :git/sha "8462388"}}}}}')"
$ nbb --classpath $classpath nrepl-server
ExpressJSによるIntegrantの使用
まず、ハンドラを定義しましょう.
(defn hello-world [count]
(fn [_ res]
(swap! count inc)
(.send res (str "Hello, World! (count: " @count ")"))))
私たちはcount
データベースをシミュレートする.サーバーを起動するたびに、サーバーに何人のリクエストをしたかをカウントし、0でカウントを再起動します.6 Inteantで始まる最高の場所はConfigマップです.
(ns hello-world
(:require [integrant.core :as ig]
["express$default" :as express]
[clojure.tools.cli :as cli]))
(def config
{:express/server {:port default-port :app (ig/ref :express/app)}
:express/app {:handler hello-world :count (ig/ref ::count)}
::count {:start 0}})
この設定マップは簡単です.各キー値ペアは将来のステートフルコンポーネントの構成を参照します.あなたは、(ig/ref <qualified-key>)
関数.次に、どのようにすべてを起動するには、積分を教えてください.このプロセスは、
ig/init-key
マルチメソッド最初のパラメータはコンポーネントに対応するキーです、そして、2番目のパラメータはそのコンポーネントのconfigのマップです.(defmethod ig/init-key :express/app [_ {:keys [handler count]}]
(doto (express)
(.get "/" (handler count))))
(defmethod ig/init-key :express/server [_ {:keys [port app]}]
(.listen app port))
(defmethod ig/init-key ::count [_ {:keys [start]}]
(atom start))
サーバーだけが閉じられる必要があります.この方法はig/halt-key!
マルチメソッドまた、サーバーオブジェクトである2番目のパラメータにのみ興味があります.この関数は有効です.(defmethod ig/halt-key! :express/server [_ server]
(when (and (some? server) (.-listening server))
(.close server)))
REPLでこれをテストすること自由に感じなさい.hello-world> (def system (ig/init config))
; now visit localhost:3000/ and refresh a few times
hello-world> (ig/halt! system)
あなたがこのセクションを混乱させるとわかるならば、あなたに点検するよう奨励しましょうsystem
または' canonical '積分を読み込む.あなたが私がいくつかの詳細について光沢があると感じるならば、そうすることは非常に啓発されます.すべてをまとめる
私たちはカップルを定義します
start
/stop
システムを上下に動かすプロセスを簡素化する機能.(def system (atom nil))
(defn start
"system is an atom"
([] (start config))
([config] (start config system))
([config system] (reset! system (ig/init config))))
(defn stop
"system is an atom"
([] (stop system))
([system]
(when (map? @system)
(swap! system ig/halt!))))
最後に、再定義start-app
呼ぶstart
を使っている.(defn start-app [{:keys [port]}]
(-> config
(assoc-in [:express/server :port] port)
start))
おめでとう!現在、コマンドライン消費とREPL開発に適したスクリプトがあります.hello-world> (start) ; or eg (start-app {:port 9093})
hello-world> (stop)
$ nbb --classpath $classpath --main hello-world/main --port 9093
一歩一歩
あなたはそれに気づくかもしれない
ctrl+c
コマンドラインからサーバを停止する必要があります.それは良いですが、もしExpressJSが正しく自分の後にクリーンアップしない場合はどうですか?多分、それはすでにします:私は、専門家です.しかし、あなたがそうでない異なるサーバーに変わるならば、どうですか?それは私たちのフックに良いかもしれない
stop
関数をsigintに設定する.(defn exit
[& _]
(stop)
(.exit js/process 0))
(.on js/process "SIGINT" exit)
ハッピーハッキング!閉鎖的思考
このプロセスの間、私が遭遇した唯一の'バグ'は、リクエストハンドラを
partial
, 例えば(partial hello-world count)
. それを働かせるために、私は2009年から閉鎖を返しましたhello-world
. これが確かかどうか分かりませんnbb
問題またはexpressjs
問題好きです
nbb
. もしかしたらbb
😉. 最大の問題は、clojure依存性を特定して、それが現在JARRを読むことができない人間工学です.しかし、私はそれらの面の両方が改善することを望みます.私は、それが私をそれから使うのを止めると思いません.
Emacsはそれがclojure replであると思います、しかし、それはNBBサーバーに接続しています-我々は少し混乱しました.畝↩
arguments
今私たちにとって不可欠ではありません(main "foobar")
, あなたは行動でそれを見ることができます.畝↩ 後で新しい発見
clj
ビルドツールもこれを行います.畝↩ ほとんどのExpressjs“こんにちは、世界”チュートリアルはここで停止します.畝↩
私の経験では、“clojure”が自動的に変更されたコンポーネントをeval(およびそれらの依存関係)を再起動します.私はどのツールがこの機能を提供するかわからない.そして、私はそれがこのアプローチで働くかどうか決定する運命を誘惑しませんでした.😁畝↩
SQLiteのような実際のデータベースを使用して次のように良い学習ステップになります.畝↩
Reference
この問題について(NBBとExpressJSによる再ロードされたワークフロー), 我々は、より多くの情報をここで見つけました https://dev.to/crinklywrappr/reloaded-workflow-with-nbb-expressjs-31f3テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol