5

I am trying to use components from http://react-components.com (eg. react-youtube) in Reagent based application, but probably my naive approach is not the right one. I tried to install NPM packages with lein-npm module, include script in html page and use them via reagent/adapt-react-class as in this SO question. But for except this sample I wasn't successful.

Usually I get errors like "require/import/module is not defined" or "Youtube is undefined" (by having (def yt-test [] (r/adapt-react-class js/Youtube)). I am confused about what is needed to do. I read something about webpack/browserify, saw cljsjs packages - are those required in order to make this working?

Community
  • 1
  • 1
Jan Hamrský
  • 150
  • 1
  • 7
  • In theory this should be simpler now: https://clojurescript.org/news/2017-07-12-clojurescript-is-not-an-island-integrating-node-modules but I'm not sure of some of the details. See also this test reagent project: https://github.com/reagent-project/reagent-site-npm-deps-test – Wodin Jul 30 '17 at 07:34
  • Should have pointed at this pull request: https://github.com/reagent-project/reagent/pull/306 – Wodin Jul 30 '17 at 07:40

2 Answers2

8

I wrote a step by step guide on how to achieve this with webpack: blob.tomerweller.com/reagent-import-react-components-from-npm

The general concept is the same as @scttnlsn suggested: bundle all npm packages in an external JS file and expose them through the global window object.

Tomer Weller
  • 2,812
  • 3
  • 26
  • 26
  • Thanks for this guide. I'm trying to adapt it for https://www.npmjs.com/package/react-mathjax but don't know what to put in the view part as hiccup code? Do you have an idea? – Gra Jul 17 '17 at 16:10
  • Answering my own question: `[:> ctx [:> node "2+2"]]` – Gra Jul 17 '17 at 19:55
  • I have another problem for which you could have a solution: https://stackoverflow.com/questions/45201315/a-is-undefined-when-compiling-a-cljs-prj-with-an-npm-module-under-prod-profil – Gra Jul 19 '17 at 21:27
3

Those components are packaged as CommonJS modules. One approach for accessing CommonJS modules from ClojureScript is to bundle them into a single JavaScript file that can be included with your ClojureScript build.

You'll need to create a JavaScript entry point file which requires your various NPM dependencies and exposes them to ClojureScript (for example, by setting them on window). Create a file (let's call it index.js) containing:

window.YouTube = require('react-youtube');

Then use a tool like Browserify to bundle your entry point file and all of the dependencies it requires:

npm install -g browserify
browserify index.js --standalone window > bundle.js

Include bundle.js in your ClojureScript build and you'll be able to access the React component from ClojureScript via js/YouTube

scttnlsn
  • 2,976
  • 1
  • 33
  • 39
  • Looks to me like react-youtube is exported as a CommonJS module. https://github.com/troybetz/react-youtube/blob/master/src/YouTube.js – Emil Ahlbäck Mar 02 '16 at 09:27
  • 1
    For other people - don't forget to remove direct import of package ([SO require not defined](http://stackoverflow.com/questions/28696511/require-is-not-defined-error-with-browserify)) and in case of that youtube player I had also to use `require("react-youtube").default`. – Jan Hamrský Mar 03 '16 at 21:46