8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ClojureScript内からnpmモジュールを呼び出す(npm-deps)

Last updated at Posted at 2017-12-09

tl;dr

project.clj にコンパイラ・オプション :npm-deps:install true を追加。

こんな感じ。

diff --git a/project.clj b/project.clj
index 24f0146..065a9f6 100644
--- a/project.clj
+++ b/project.clj
@@ -25,6 +25,8 @@
                 :output-to "target/js/compiled/hello_aws_cli.js"
                 :output-dir "target/js/compiled/dev"
                 :target :nodejs
+                :npm-deps {:aws-sdk "^2.167.0"}
+                :install-deps true
                 :optimizations :none
                 :source-map-timestamp true}}
              {:id "prod"

ClojureScript を書き始めた cljs newbie がハマる大きな落とし穴、
それが「ClojureScript コード内から npm なコードを呼び出す」です。1

ちょっとググってみたところ、CLJSJSを使うといいよ〜とか、そこにない場合は自力で externs を書く必要があるよとか、いろいろ見つかるのですが、どれもうまく行かなかったり設定に戸惑ったりすること1週間...2

npm-deps コンパイラ・オプションを使え!

そんな中、この記事を発見。
https://clojurescript.org/news/2017-07-12-clojurescript-is-not-an-island-integrating-node-modules

ほうほう!
早速試してみましょう。

$ lein new figwheel-node hello-aws-cli
$ cd hello-aws-cli

project.clj に :npm-deps {:aws-sdk "^2.167.0"}:install trueを追加。

diff --git a/project.clj b/project.clj
index 24f0146..065a9f6 100644
--- a/project.clj
+++ b/project.clj
@@ -25,6 +25,8 @@
                 :output-to "target/js/compiled/hello_aws_cli.js"
                 :output-dir "target/js/compiled/dev"
                 :target :nodejs
+                :npm-deps {:aws-sdk "^2.167.0"}
+                :install-deps true
                 :optimizations :none
                 :source-map-timestamp true}}
              {:id "prod"

依存関係インストール + cljs コード → JS コードへのトランスパイル + REPL を開くために lein figwheelを実行。

$ lein figwheel
Launching ClojureScript REPL for build: dev
Figwheel Controls:
          (stop-autobuild)                ;; stops Figwheel autobuilder
          (start-autobuild [id ...])      ;; starts autobuilder focused on optional ids
          (switch-to-build id ...)        ;; switches autobuilder to different build
          (reset-autobuild)               ;; stops, cleans, and starts autobuilder
          (reload-config)                 ;; reloads build config and resets autobuild
          (build-once [id ...])           ;; builds source one time
          (clean-builds [id ..])          ;; deletes compiled cljs target files
          (print-config [id ...])         ;; prints out build configurations
          (fig-status)                    ;; displays current state of system
          (figwheel.client/set-autoload false)    ;; will turn autoloading off
          (figwheel.client/set-repl-pprint false) ;; will turn pretty printing off
  Switch REPL build focus:
          :cljs/quit                      ;; allows you to switch REPL to another build
    Docs: (doc function-name-here)
    Exit: Control+C or :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
Prompt will show when Figwheel connects to your application

と出るので、別ターミナルを立ち上げて

$ node target/js/compiled/hello_aws_cli.js
Hello world!
Figwheel: Can't start Figwheel!! Please make sure ws is installed
 do -> 'npm install ws'

ん??
lein figwheel でインストールされる依存関係は project.clj に記述されているものだけ(package.json で管理されているものはインストールしてくれない)みたいですね。

そこで、言われる通り npm install を実行したのち、再度実行してみると...

$ npm install
....

$ lein figwheel
Hello world!
Figwheel: trying to open cljs reload socket
Figwheel: socket connection established

おっ、うまくいってそう。
もう片方のターミナルをみると、

...
Prompt will show when Figwheel connects to your application
To quit, type: :cljs/quit
dev:cljs.user=> (+ 1 2)
3
dev:cljs.user=>

いい感じですね!これで REPL の準備ができました。
それでは AWS SDK を読み込めるか試してみましょう!

dev:cljs.user=> (require '[cljs.nodejs :as nodejs])
nil
dev:cljs.user=> (def AWS (nodejs/require "aws-sdk"))
#'cljs.user/AWS
dev:cljs.user=> AWS
#js {:util #js {:environment "nodejs", :engine #object[engine], :userAgent #object[userAgent], :isBrowser #object[isBrowser], :isNode #object[isNode], :uriEscape #object[uriEscape], :uriEscapePath #object[uriEscapePath], :urlParse #object[urlParse], ... ; 以下略

おっ!やったね。

:npm-deps コンパイラオプションを使うと、驚くほど簡単に npm が使えていい感じですね!3

参考 URL

https://cljs.github.io/api/compiler-options/npm-deps
https://anmonteiro.com/2017/03/requiring-node-js-modules-from-clojurescript-namespaces/
https://clojurescript.org/news/2017-07-12-clojurescript-is-not-an-island-integrating-node-modules

  1. ハマったのは私だけかもしれませんが...😅

  2. 最新のAWS SDK for javascriptAlexa Skill Kitを使いたかったのです

  3. ただし、ClojureScript v1.9.518 以降 でしか使えないのでお気をつけください...

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?