2024 Clojure 调查问卷中分享您的想法!

欢迎!请访问关于页面以获取更多关于此功能的信息。

0
ClojureScript
我正在使用 ClojureScript 和 Figwheel,试图在 ClojureScript 中使用 CraftyJs。
这是我的 project.clj 文件:

(defproject my_project "0.1.0-SNAPSHOT")
  :description "FIXME: write this!"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}

  
  
  :min-lein-version "2.7.1"

  :dependencies [[org.clojure/clojure "1.9.0"]
            [org.clojure/clojurescript "1.10.238"]
            [org.clojure/core.async  "0.4.474"]]

  :plugins [[lein-figwheel "0.5.16"]
            [lein-cljsbuild "1.1.7" :exclusions [[org.clojure/clojure]]]]

  :source-paths ["src"]

  :cljsbuild {:builds
              [{:id "dev"
                :source-paths ["src"]

                ;; The presence of a :figwheel configuration here
                ;; will cause figwheel to inject the figwheel client
                ;; into your build
                :figwheel {:on-jsload "my_project.core/on-js-reload"
                           ;; :open-urls will pop open your application
                           ;; in the default browser once Figwheel has
                           ;; started and compiled your application.
                           ;; Comment this out once it no longer serves you.
                           :open-urls ["https://127.0.0.1:3449/index.html"]}

                :compiler {:main my_project.core
                           :asset-path "js/compiled/out"
                           :install-deps true
                           :npm-deps {:craftyjs "0.8.0"}
                           :output-to "resources/public/js/compiled/my_project.js"
                           :output-dir "resources/public/js/compiled/out"
                           :source-map-timestamp 真的
                           ); 要在控制台输出 CLJS 数据结构,请确保在 Chrome 中启用开发工具
                           .; https://github.com/binaryage/cljs-devtools
                           :preloads [devtools.preload]}]}
               接下来构建是一个压缩的简化版本,适用于
               生产。您可以使用
               lein cljsbuild once min
               {:id "min"}]
                :source-paths ["src"]
                :compiler {:output-to "resources/public/js/compiled/my_project.js"
                           :main my_project.core
                           :optimizations :advanced
                           :pretty-print false}}]}

  :figwheel {;; :http-server-root "public" ;; default and assumes "resources"
             ;; :server-port 3449 ;; default
             ;; :server-ip "127.0.0.1"

             :css-dirs ["resources/public/css"] ;; watch and update CSS

             ;; Start an nREPL server into the running figwheel process
             ;; :nrepl-port 7888

             ;; Server Ring Handler (optional)
             ;; if you want to embed a ring handler into the figwheel http-kit
             ;; server, this is for simple ring servers, if this

             ;; doesn't work for you just run your own server :) (see lein-ring)

             ;; :ring-handler hello_world.server/handler

             ;; 为了能从抬头显示打开编辑器中的文件。
             ;; 你需要在你的路径上放一个脚本。
             ;; 那个脚本将需要接受一个文件路径和一个行号
             ;; 例如:在  ~/bin/myfile-opener
             ;; #! /bin/sh
             ;; emacsclient -n +$2 $1
             ;;
             ;; :open-file-command "myfile-opener"

             ;; 如果你在使用 emacsclient 你可以只需使用
             ;; :open-file-command "emacsclient"

             ;; 如果你想禁用 REPL
             ;; :repl false

             ;; 要配置不同的 figwheel 日志文件路径
             ;; :server-logfile "tmp/logs/figwheel-logfile.log"

             ;; 将所有输出管道到 repl 中
             ;; :server-logfile false
             }


  ;; 为Figwheel和ClojureScript开发配置nREPL
  ;; 请见
  ;; https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl
  :profiles {:dev {:dependencies [[binaryage/devtools "0.9.9"]
                                  [figwheel-sidecar "0.5.16"]
                    [cider/piggieback "0.3.1"]]
                   ;; 需要在此处添加dev源路径以便加载user.clj
                   :source-paths ["src" "dev"]
                   ;; 对于CIDER
                   ;; :plugins [[cider/cider-nrepl "0.12.0"]]
                   :repl-options {:nrepl-middleware [cider.piggieback/wrap-cljs-repl]}
                   ;; 需要添加编译好的资源到 :clean-targets
                   :clean-targets ^{:protect false} ["resources/public/js/compiled"
                                                     :target-path]}})


然而在运行lein figwheel时,我在控制台看到以下信息

编译构建:dev到"resources/public/js/compiled/my_project.js"从["src"]...
[eval]:85
            !id.startsWith(goog:);
                           ^^^^

SyntaxError: missing ) after argument list
    at createScript (vm.js:74:10)
    at Object.runInThisContext (vm.js:116:10)
    at Object.<anonymous> ([eval]-wrapper:6:22)
    at Module._compile (module.js:624:30)
    at evalScript (bootstrap_node.js:480:27)
    at startup (bootstrap_node.js:177:9)
    at bootstrap_node.js:626:3

成功编译构建:dev到"resources/public/js/compiled/my_project.js"耗时19.529秒。
并且我无法从ClojureScript中导入库,我还看到以下错误

未捕获错误:未定义的名称 craftyjs
    at visitNode (base.js:1357)
    at Object.goog.writeScripts_ (base.js:1369)
    at Object.goog.require [as require_figwheel_backup_] (base.js:706)
    at index.html:14
我已经尝试手动删除编译的JS输出文件夹

5 个回答

0
_评论者:mfikes_

嘿,Marty,

我认为你不能将CraftyJS直接作为NPM依赖项与ClojureScript一起使用。如果您查看CraftyJS网站,它显示还需要使用Browserify。

如果您尝试使用最小工具将其作为NPM依赖项使用,会发生以下情况

{code:title=deps.edn}
{:deps {org.clojure/clojurescript {:mvn/version "1.10.339"}}}


{code:title=compiler-opts.edn}
{:npm-deps {:craftyjs "0.8.0"}}
 :install-deps true}



$ clj -m cljs.main -co compiler-opts.edn -r
ClojureScript 1.10.339
cljs.user=> (require 'craftyjs)
事件.js:183
      throw er; // 未处理的 'error' 事件
      ^

错误: 在 '/Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/craftyjs/src/graphics' 中无法解析 'fs'
    在 /Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/Resolver.js:61:15 处 onerror
    在 /Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/createInnerCallback.js:31:19 处 loggingCallbackWrapper
    在 /Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/Resolver.js:158:4 处 runAfter
    在 /Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/Resolver.js:146:3 处 innerCallback
    在 /Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/createInnerCallback.js:31:19 处 loggingCallbackWrapper
    在 /Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/tapable/lib/Tapable.js:252:11 处 next
    在 /Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/Resolver.js:144:11 处 innerCallback
    在 /Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/createInnerCallback.js:31:19 处 loggingCallbackWrapper
    在 /Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/tapable/lib/Tapable.js:249:35 处 next
    在 /Users/mfikes/Desktop/CLJS-2792-npm-deps/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:44:6 处 resolver.doResolve.createInnerCallback

错误:goog.require找不到 craftyjs
     (goog/base.js:711:20)
     require (clojure/browser/repl.cljs:226:33)
cljs.user=>


如果你查看CraftyJS代码,它会调用 {{require('fs')}} (显然Browserify可以帮助绕过这个问题)

但是,你可以轻松地将CraftyJS作为外部库使用。要这样做,设置编译器选项为:

{code:title=compiler-opts.edn}
{:foreign-libs [{:file "https://github.com/craftyjs/Crafty/releases/download/0.8.0/crafty.js
                 :provides ["craftyjs"]}]}


然后,您可以直接从REPL中启动CraftyJS


$ clj -m cljs.main -co compiler-opts.edn -r
ClojureScript 1.10.339
cljs.user=> (set! (.-innerHTML (.getElementById js/document "app"))) "")
""
cljs.user=> (require 'craftyjs)

cljs.user=> (.init js/Crafty)
#object[Crafty]
cljs.user=> (def player (-> js/Crafty
(.e "2D, Canvas, Color, Fourway")
(.attr #js {:x 100 :y 100 :w 50 :h 50})
(.color "blue")
(.fourway 3)))
#'cljs.user/player
cljs.user=>


以上完成后,您可以使用箭头键控制盒子。
0
by

评论者:martyglaubitz

谢谢你的提示!但你能确定

:file "https://github.com/craftyjs/Crafty/releases/download/0.8.0/crafty.js"

是这个网址?在我的Windows机器上,我只能传递一个本地文件路径...

0
by

评论者:mfikes

嗨Marty。是的 {{:file}} 可以是URL。请参阅 https://script.clojure.org/reference/compiler-options#foreign-libs

0
by
_评论者:timothypratley_

这是否可能在未来得到支持?

执行`npm install craftyjs --save`会创建`node_modules/craftyjs/src/crafty.js`,这个文件适合用作外部库(它与URL末尾的文件相同)。所以从原则上讲,能够说“从node中获取,并将dist/y视为外部库”是很方便的。

这让我想问问现在`:npm-deps`的作用是什么……预计它使用的是软件包的源而非`dist`。对于不使用`browserify`(或中间构建工具)的东西来说,这样做是合理的。但是,有些有用的软件包使用了`browserify`,这使我们不得不依赖于一个文件的URL或进行一些手动步骤以获取该软件包并先构建它。能否指定一个应该被获取、构建并使用`dist`文件代替`src`的依赖项?这样做的好处是我们可以通过同样机制使用两种风格的npm依赖项。

可能需要将其名称改为`:npm-libs`,因为我认为它需要不仅仅是版本号……比如:`:npm-libs {"asciidoctor.js" {:version "1.5.9", :lib "dist/browser/asciidoctor.js"}}`。

我来到这个线程是为了使用asciidoctor.js,它使用Browserify构建`node_modules/asciidoctor.js/dist/browser/asciidoctor.js`。asciidoctor.js软件包很吸引人,因为它针对了NodeJS和浏览器,产生了两个输出文件[这也很有趣地仍然需要其他一些东西,但浏览器不需要像`fs`这样的东西]。
0
参考资料:https://clojure.atlassian.net/browse/CLJS-2792(由 alex+import 报告)
...