Transforming a js project into a clojurescript project

Hi,
I have a react/express.js project. It’s a bilingual dictionary. I want to re-write it using clojurescript/clojure.
I have 2 specific questions:

  1. Which template should I use to generate the project: shadow-cljs? reagent? Preferrably, I want to use clojure for the backend (like Express.js) and clojurescript for the frontend (like React).
  2. My data is basically an xml file of bilingual terms and their definition:
    a. where do I put the file in order to parse it. Directly under the root of the project?
    b. If I am in a cljs file (myapp.core) how do I fetch a file in the directory?
    This is what I tried so far to get into the file “domaines.xml”:
(ns my-app.core
  (:require
   [reagent.core :as reagent :refer [atom]]
   [cljs.nodejs :as nodejs]
   ["xml2js" :as xml2js]))

(def parser (xml2js/Parser "./domaines.xml"))

  (defn node-slurp [path]
  (let [fs (nodejs/require "fs")]
    (.readFileSync fs path "utf8"))) 

  (def pp (parser (node-slurp "public/domaines.xml")))

Thank you for your help!
os

  1. I would actually go without a template and setup my project from scratch. It’s a useful learning experience. You could setup an example project using the Luminus template and use that for reference.

  2. a) depends on your setup. If you want to be able to parse the file both in the frontend and backend, then you should put it in a directory that the backend serves, e.g. resources/public.
    b) Use something like cljs-http or cljs-ajax or the browser native fetch the load the file from the server. Example with cljs-ajax:

(ajax.core/GET "/domaines.xml" {:response-format :text
                                :handler (fn [text]
                                               ,,,)}

PS. I asked a similar/related question earlier here where you might find some useful information: Any example project setups for shadow-cljs + clj backend using tools.deps?

Thank you very much @greinseth I appreciate your help.
Actually when I started with clojure web dev, the first thing I tried was Luminus. But since then, I tried other things like shadow-cljs. But the amount of different ways you can set up a web project is becoming way too confusing for a beginner. I hope someday we come to a definitive template, the way React has react create app.

OS

Combining a clojurescript frontend (spa) and a clojure backend can be quite challenging to get right, I agree. It might be easier to develop them separately.

That being said, shadow-cljs and figwheel are great tools that does much of what create-react-app does, except for the css. You don’t need a template to get started with either of them, and they both require very little config.

The problem with create-react-app as I see it, is that once you need to make some customizations to the build it quickly falls apart and you need to resort to eject or some other wrapper library around it. This is not the case with either shadow-cljs or figwheel.

1 Like

Hello @eternalNewbie.

To inline the xml into the client side code like you are doing you should use rc/inline like this:

(ns demo.app
  (:require [shadow.resource :as rc]
            ["xml2js" :as xml2js]))

(def domaines-xml (xml2js/Parser (rc/inline "data/domaines.xml")))

Note that you should put the file on the classpath e.g. in src/data/domaines.xml if you use this method.

See this post for more details.

If you want to use express.js on your backend might I recommend Sitefox which is a ClojureScript backend framework I built specifically for this. It is built on top of express. You can bootstrap a new project like this:

npm init sitefox-shadow-fullstack myproject

Let me know if I can help in any way.

1 Like

@chr15m The post you linked to is indeed of great help.
as far as Express.js is concerned, I want to try first to have everything written in clojure backend/frontend. As a last resort, I will take a look into Sitefox.

Thank you for taking the time to answer my question
O.S

1 Like

No problem, thanks!

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.