首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Node.js上运行ClojureScripts Om?

如何在Node.js上运行ClojureScripts Om?
EN

Stack Overflow用户
提问于 2015-04-20 04:40:35
回答 3查看 663关注 0票数 2

我想知道是否可以在Node.js上使用Om来生成超文本标记语言。我已经找到了ClojureScript running on Node.js,显然还有React can be run on Node.js。我按照basic guide创建了一个Leiningen项目,如下所示

代码语言:javascript
复制
lein new figwheel om-tut -- --om

修改project.clj文件以启动,如下所示

代码语言:javascript
复制
(defproject om-tut "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"}

  :dependencies [[org.clojure/clojure "1.6.0"]
                 [org.clojure/clojurescript "0.0-2850"]
                 [figwheel "0.2.5-SNAPSHOT"]
                 [org.clojure/core.async "0.1.346.0-17112a-alpha"]
                 [sablono "0.3.4"]
                 [org.omcljs/om "0.8.8"]]

  :plugins [[lein-cljsbuild "1.0.4"]
            [lein-figwheel "0.2.5-SNAPSHOT"]
            [lein-npm "0.4.0"]]

  :source-paths ["src"]

  :clean-targets ^{:protect false} ["resources/public/js/compiled" "out/server" "out/server/om_tut.js"]

  :cljsbuild {
    :builds [{:id "dev"
              :source-paths ["src" "dev_src"]
              :compiler {:output-to "resources/public/js/compiled/om_tut.js"
                         :output-dir "resources/public/js/compiled/out"
                         :optimizations :none
                         :main om-tut.dev
                         :asset-path "js/compiled/out"
                         :source-map true
                         :source-map-timestamp true
                         :cache-analysis true }}
             {:id "min"
              :source-paths ["src"]
              :compiler {:output-to "resources/public/js/compiled/om_tut.js"
                         :main om-tut.core                         
                         :optimizations :advanced
                         :pretty-print false}}
             {:id "server"
              :source-paths ["src"]
              :compiler {
                :main pow.core
                :output-to "out/server/om_tut.js"
                :output-dir "out/server"
                :optimizations :simple
                :target :nodejs
                :cache-analysis true
                :source-map "out/server/om_tut.js.map"}}]}

并将core.cljs更改为

代码语言:javascript
复制
(ns ^:figwheel-always om-tut.core
    (:require[om.core :as om :include-macros true]
              [om.dom :as dom :include-macros true]))

(enable-console-print!)

(println "Edits to this text should show up in your developer console.")

;; define your app data so that it doesn't get over-written on reload

(defonce app-state (atom {:text "Hello world!"}))

(defn render [data owner]
  (reify om/IRender
    (render [_]
      (dom/h1 nil (:text data)))))

(om/root
  render
  app-state
  {:target (. js/document (getElementById "app"))})

(defn -main []
  om.dom/render-to-str (render app-state nil))

(set! *main-cli-fn* -main)

使用以下命令成功编译项目

代码语言:javascript
复制
lein cljsbuild once server

但是,当我尝试从Windows cmd shell运行如下生成输出时

代码语言:javascript
复制
node out\server\om_tut.js

我得到了

代码语言:javascript
复制
    ...\om-tut\out\server\om_tut.js:40237
om.dom.input = om.dom.wrap_form_element.call(null, React.DOM.input, "input");
                                                   ^
ReferenceError: React is not defined
    at Object.<anonymous> (...\om-tut\out\server\
om_tut.js:40237:52)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

我认为未定义的React对象应该来自...\om-tut\out\react.inc.js文件,该文件存在并且应该已经在生成的om_tut.js文件的第37532行加载

代码语言:javascript
复制
cljs.core.load_file("react.inc.js");

有没有可能出问题的原因?

EN

回答 3

Stack Overflow用户

发布于 2015-05-21 12:10:44

您可能想要在project.clj中添加一个前导,例如:preamble ["include.js"]。前导码隐式引用相对于project.clj/resources目录。来源:https://github.com/Sparrho/supper/blob/master/project.clj

include.js中,您将为React提供一个引用:

代码语言:javascript
复制
var React = require("react");

来源:https://github.com/Sparrho/supper/blob/master/resources/include.js

作为参考,这里是来自project.clj的build块:

代码语言:javascript
复制
{:id "server"
:source-paths ["src"]
:compiler {:main myapp.core-server
           :target :nodejs
           :output-to "deploy/index.js"
           :output-dir "out-server"
           :preamble ["include.js"] ;; Implicitly nested in /resources                       
           :optimizations :simple
           :language-in :ecmascript5
           :language-out :ecmascript5}}

我还读到过:preamble可以直接引用react.min.js,因为它被捆绑在Om依赖的WebJar中。来源:https://groups.google.com/forum/#!topic/clojurescript/TL8Cv-jPkzM

票数 1
EN

Stack Overflow用户

发布于 2015-08-17 02:34:32

您可以尝试使用以下内容解决:preamble ["include.js"]问题:

代码语言:javascript
复制
module.exports = '';

但它只适用于只有一些cljsjs/包(在本例中是cljsjs/react)的情况。例如,包含cljsjs/jquery 2.1.4将不起作用。

出现问题的原因是React定义:

代码语言:javascript
复制
!function(e){
    if ("object" == typeof exports && "undefined" != typeof module) {
        module.exports = e();
    }
    else if ("function" == typeof define && define.amd) {
        define([],e);
    }
    else{
        var t;
        t= "undefined" != typeof window ? window
            : "undefined" != typeof global ? global
            : "undefined" != typeof self ? self
            : this,
            t.React = e()
    }
}(function(){/* React definition */})

环境在NodeJS中没有window对象,但它有modulemodule.exports。我们通过将module.exports重置为string来对环境进行欺骗。

在安装了react模块的NpmJS环境下,React = require('react')无法正常工作。

在我看来,正确的解决方案不是包含React to模块的代码,而是在具有react依赖关系的NpmJS环境下使用此模块。

在这种情况下,tyronep's的答案是好的。我们应该:

  1. 使用以下:preamble

global.React = require('react')

  • don't include cljsjs/react to NpmJS dependencies.

in NpmJScljsjs/react

不幸的是,如果我们想使用om,那么必须包含cljsjs/react (即冗余包含)

票数 1
EN

Stack Overflow用户

发布于 2015-05-13 01:32:03

你目前的问题是加载React模块,我相信你可以通过调整你的配置来解决这个问题,但是你不能在Node上调用om.core/rootom.core/root将React组件挂载在DOM中,这是Node所缺少的。您需要的是定义组件,将静态数据传递给它们,然后调用React.renderToString(https://facebook.github.io/react/docs/top-level-api.html#react.rendertostring)。Om用render-to-str包装它。

代码语言:javascript
复制
(def static-data {:text "Hello world!"})

(defn title-component [data owner]
  (reify om/IRender
    (render [_]
      (dom/h1 nil (:text data)))))

(def component-html-as-string
  (dom/render-to-str (title-component static-data)))

此外,要在Node上进行开发,最好从mies-node开始

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29735585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档