# 0.8 Upgrade guide The necessary changes depend on what environment you target, and how you want to provide React. While Reagent 0.8 supports use with React from npm, there are known problems. | | 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 | 1. 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. 2. Closure optimization currently breaks certain statically created objects which are accessed dynamically in `ReactDOM/server`: https://github.com/facebook/react/issues/12368 ## Browser - Cljsjs 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. ## Browser - node modules If `react`, `react-dom` and `create-react-class` are available in `node_modules` directory, ClojureScript compiler will use these with Reagent. To disable this by adding `:npm-deps false` compiler option. If you don't want to call `npm` and manage `package.json`, you can use `:npm-deps` and `:install-deps` compiler options to 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](https://clojurescript.org/reference/compiler-options#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: ```clj :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 https://github.com/clojure/clojurescript/commit/f7d611d87f6ea8a605eae7c0339f30b79a840b49 Available in 1.0.46+ 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.