4.4 KiB
0.8 Upgrade guide
The necessary changes depend on what environment you target, and how you want to provide React.
Build | Browser | Node | |
---|---|---|---|
Cljsjs | :none |
Supported | Requires Cljs 1.10.238+ |
Cljsjs | :advanced |
Supported | Requires Cljs 1.10.238+ |
node modules |
:none |
Known problems (1) | Supported |
node modules |
:advanced |
Known problems (2) | Supported |
While Reagent 0.8 supports use with React from npm, there are known problems:
-
Closure can't properly handle React 16 CommonJS module pattern: https://github.com/google/closure-compiler/issues/2841 This causes the production React code being loaded even for development builds. Using Chrome React Developer Tools with this setup will break Reagent.
-
Closure optimization currently breaks certain statically created objects which are accessed dynamically in
ReactDOM/server
: https://github.com/facebook/react/issues/12368 Fixed by using[com.google.javascript/closure-compiler-unshaded "v20180319"]
(fix commit), will be the default in next ClojureScript release.
Browser - Cljsjs
This is the recommended setup.
Using Reagent with Cljsjs packages doesn't require changes, other than making sure you update Cljsjs React dependencies, if you have direct dependencies to them.
To ensure Cljsjs libs are used instead of Node Modules, you can add :npm-deps false
, which will make sure ClojureScript compiler doesn't look into node_modules
directory if it exists.
Browser - node modules
If react
, react-dom
and create-react-class
are available in node_modules
directory, ClojureScript compiler will use these with Reagent.
If you don't want to call npm
and manage package.json
, you can use :npm-deps
and :install-deps
compiler options to
have ClojureScript install the packages automatically.
You can use :process-shim
compiler option to provide process.env.NODE_ENV
constant which is used by JS code to enable development and production
builds. ClojureScript compiler will automatically set this constant to
production
value when using :advanced
optimizations. This enables
the React production build.
When using module processing, it should be possible to split output into several modules.
Externs are required for use with node modules also! React created objects statically in several places and then accesses those dynamically. Closure-compiler will in these cases rename the statically object properties, which will break dynamically accessing the objects. Externs fix this by defining which properties must not be renamed.
Browser - loading React from CDNJS or custom Webpack bundle
TODO: Not tested properly
If you want to load React.js yourself from external JS file (CDN) or from custom bundle, it should be possible to override the Cljsjs foreign-libs, while still using externs from Cljsjs packages. To override the foreign-libs, you can provide following compiler option:
:foreign-libs
[{:file "empty.js",
:provides ["react" "react-dom" "create-react-class" "react-dom/server"],
:requires [],
:global-exports {react React
react-dom ReactDOM
create-react-class createReactClass
react-dom/server ReactDOMServer}}]
You'll also need to create the mentioned empty.js
file (FIXME: relative to project.clj
?).
If your bundle provides other libraries, you could extern :provides
and :global-exports
(e.g. prop-types
).
NodeJS - Cljsjs
Requires f7d611d87f
Available in 1.0.238
Reagent should use Cljsjs libraries by default even when running on Node.
NodeJS - node modules
Install react
, react-dom
and create-react-class
npm packages,
and ClojureScript should automatically use require
to
load React for Reagent.
Electron
???
React-native
https://github.com/drapanjanas/re-natal/issues/128
Common Problems
Mismatch with Cljsjs and npm packages
If you have one npm package installed, e.g. react
, you also need
to provide others (react-dom
and create-react-class
), else
Cljsjs packages would be used for these, and packages from different sources
don't work together.