reagent/doc/0.8-upgrade.md

4.3 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 Requires Cljs 1.10.312 Supported
node modules :advanced Requires Cljs 1.10.312 Supported

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 - Webpack

https://clojurescript.org/guides/webpack

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 "bundje.js",
   :provides ["react" "react-dom" "create-react-class" "react-dom/server"],
   :global-exports {react React
                    react-dom ReactDOM
                    create-react-class createReactClass
                    react-dom/server ReactDOMServer}}]

NodeJS - Cljsjs

Requires f7d611d87f

Available in 1.10.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.

Previous problems

Before ClojureScript 1.10.312 there were couple of problems with npm support:

  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. Fixed by [com.google.javascript/closure-compiler-unshaded "v20180610"] (PR), will be the included in next the ClojureScript release.

  2. 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.