Adding ClojureScript to an Existing Codebase

I have a fairly large React + Relay code base that is built using Webpack. Can ClojureScript + Reagent be gradually introduced?

I was thinking of starting with some smaller functional components in our code base and replacing them. This would mean that the Reagent component must somehow get props from the parent.

Any thoughts or tools around this? Quick Google only seems to include articles around, including JavaScript libraries in your ClojureScript application, and not vice versa.

+6
source share
1 answer

You can create a reagent component, export it, and then import it into your JS code.

Since you already have the web package / reaction in the js project, you need to exclude cljs from the project:

: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]]] 

Now you need to trick the Reagent into thinking that these reaction files that you just excluded are still here. Create these three files:

Src / cljsjs / react.cljs

 (ns cljsjs.react) 

Src / cljsjs / react / dom.cljs

 (ns cljsjs.react.dom) 

Src / cljsjs / react / home / server.cljs

 (ns cljsjs.react.dom.server) 

Yes, only one line with a namespace declaration in each file.

Now you can write your component:

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)))]) )})) 

Your cljsbuild section in project.clj might look like this:

 :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" }}]} 

For brevity, in the form I gave you only the min section in cljsbuild.

lein cljsbuild once min will create a resources/public/js/compiled/reagent_component_min.js that should be copied to your Webpack project.

A new entry is added to your webpack.config in front of your main entry point:

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

This file (reagent_component_min.js) should be excluded from babelification:

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

and in your javascript you use it like this:

 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') ); 

Yes, the babel jsx plugin does not recognize <comp name="..."/> . This is why React.createElement is called. I did not understand how to make it better, but it works.

+3
source

Source: https://habr.com/ru/post/1014402/


All Articles