2017-01-25 35 views
6

Mam dość dużą bazę kodu React + Relay, która jest budowana przy użyciu Webpacka. Czy możliwe jest stopniowe wprowadzenie do tego ClojureScript + Reagent?Dodawanie ClojureScript do istniejącej bazy kodów

Zastanawiam się nad uruchomieniem niektórych mniejszych składników funkcjonalnych w naszej bazie kodu i ich zamianie. Oznaczałoby to, że komponent Odczynnik musiałby w jakiś sposób otrzymywać rekwizyty od rodzica.

Jakieś myśli lub narzędzia w tym kierunku? Wydaje się, że szybkie Google publikuje artykuły zawierające biblioteki JavaScript w twojej aplikacji ClojureScript, a nie na odwrót.

+0

Widziałeś ten artykuł? http://blob.tomerweller.com/reagent-import-react-components-from-npm –

+0

Tak jak powiedziałem w pytaniu, znalazłem wiele artykułów na temat importowania JS do istniejącego projektu ClojureScript, ale nic o używaniu ClojureScript z istniejący projekt JS. – Samuel

+0

W takim razie musisz znaleźć clojurescript-loader dla webpacka. –

Odpowiedz

3

Można utworzyć komponent odczynnika, wyeksportować go, a następnie zaimportować do kodu JS.

Skoro masz już WebPack/reagować w projekcie js, trzeba wykluczyć te z projektu 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]]] 

Teraz trzeba oszukać odczynnik do myślenia, że ​​te pliki reagują właśnie wykluczonych wciąż tu są. Tworzyć te trzy pliki:

src/cljsjs/react.cljs

(ns cljsjs.react) 

src/cljsjs/reagują/dom.cljs

(ns cljsjs.react.dom) 

src/cljsjs/reagują/dom/server.cljs

(ns cljsjs.react.dom.server) 

Tak, tylko jedna linia z deklaracją przestrzeni nazw w każdym pliku.

Teraz można napisać komponent:

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

Twój sekcja cljsbuild w project.clj może wyglądać następująco:

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

Dla purpouse zwięzłości podałem tylko sekcję cljsbuild z zakresu min.

lein cljsbuild once min będzie produkować plik resources/public/js/compiled/reagent_component_min.js, który należy skopiować do projektu Webpack.

Nowy wpis zostanie dodany do webpack.config przed głównym punkcie wejścia:

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

ten plik (reagent_component_min.js) powinny być wyłączone z babelification:

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

aw JavaScript go używać tak:

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

Tak, babel JSX plugin nie rozpoznaje <comp name="..."/>. Właśnie dlatego wywoływany jest React.createElement. Nie wymyśliłem, jak poprawić wygląd, ale działa.

+0

Dziękuję bardzo, to jest doskonałe. – Samuel