将ClojureScript添加到现有代码库

时间:2017-01-25 05:51:35

标签: reactjs clojurescript

我有一个相当大的React + Relay代码库,它是使用Webpack构建的。是否有可能以某种方式逐步引入ClojureScript + Reagent?

我正在考虑从代码库中的一些较小的功能组件开始并将它们交换出来。这意味着Reagent组件会以某种方式需要从父母那里接收道具。

围绕这样做的任何想法或工具?一个快速的Google似乎只会在你的ClojureScript应用程序中找到包含JavaScript库的文章,而不是相反。

1 个答案:

答案 0 :(得分:6)

您可以创建试剂组件,将其导出,然后将其导入JS代码中。

由于你已经在你的js项目中有webpack / react,你需要从你的cljs项目中排除那些:

:dependencies [[org.clojure/clojure "1.8.0"]
               [org.clojure/clojurescript "1.9.229"]
               [org.clojure/core.async "0.2.391"
                :exclusions [org.clojure/tools.reader]]
               [reagent "0.6.0" :exclusions [cljsjs/react cljsjs/react-dom cljsjs/react-dom-server]]]

现在你必须让Reagent认为你刚才排除的那些反应文件仍在这里。创建这三个文件:

<强>的src / cljsjs / react.cljs

(ns cljsjs.react)

<强>的src / cljsjs /反应/ dom.cljs

(ns cljsjs.react.dom)

<强>的src / cljsjs /反应/ DOM / server.cljs

(ns cljsjs.react.dom.server)

是的,每个文件中只有一行带有名称空间声明。

现在你可以编写你的组件了:

<强> reagent_component / core.cljs:

(ns reagent-component.core
    (:require [reagent.core :as r]))

(def counter (r/atom 5))

(def ^:export test66
    (r/create-class
        {:reagent-render
         (fn [props]
             (let [{:keys [name]} props]
                 [:div 
                  {:on-click (fn [] (swap! counter inc))}
                  name ", I am counting " (clojure.string/join ", " (map inc (range @counter)))])
             )}))

project.clj中的cljsbuild部分可能如下所示:

:cljsbuild {:builds
            [{:id           "min"
              :source-paths ["src"]
              :compiler     {:output-to     "resources/public/js/compiled/reagent_component_min.js"
                             :output-dir    "resources/public/js/compiled/min"
                             :main          reagent-component.core
                             :optimizations :advanced
                             :asset-path    "js/compiled/out"
                             }}]}

为了简洁起见,我只给了你cljsbuild的min部分。

lein cljsbuild once min将生成resources/public/js/compiled/reagent_component_min.js文件,该文件必须复制到您的Webpack项目中。

在您的主要入口点之前,您的webpack.config中会添加新条目:

 entry: [`${APP_DIR}/reagent_component_min.js`, `${APP_DIR}/main.js`],

这个文件(reagent_component_min.js)应该从babelification中排除:

module: {
  loaders: [
    {
      test: /\.js$/,
      exclude: /(node_modules|bower_components|reagent_component_min.js)/,
      loader: 'babel-loader',
      query: {
        presets: ['latest']
      }
    }
  ]
}

在您的javascript中,您可以像这样使用它:

import React from 'react';
import ReactDOM from 'react-dom';

const comp = reagent_component.core.test66;

const element = <div>Hello, world
    {React.createElement(comp, {name: 'akond'})}
</div>;

ReactDOM.render(
  element,
  document.getElementById('app')
);

是的,babel jsx插件无法识别<comp name="..."/>。这就是调用React.createElement的原因。我没有弄清楚如何让它看起来更好,但它确实有效。