Maria D. Campbell

requestAnimationFrame and polyfill in React 16

September 27th, 2017

If you read my previous post, My first time using React 16.0, you know that I got the following warning when I typed npm run test in Terminal:

react-universal-blog-app@1.0.0 test /Users/mariacam/Development/react-universal-blog-app> jest

PASS  src/sum.test.jsPASS  src/App.test.js

● Console
console.error node_modules/fbjs/lib/warning.js:33

Warning: React depends on requestAnimationFrame. Make sure that you load a polyfill in older browsers. http://fb.me/react-polyfills

Test Suites: 2 passed, 2 totalTests: 2 passed, 2 totalSnapshots: 0 totalTime: 1.669sRan all test suites.

Notice something different?

console.error node_modules/fbjs/lib/warning.js:33  
Warning: React depends on requestAnimationFrame. 
Make sure that you load a polyfill in older browsers. http://fb.me/react-polyfills

The React Polyfills link took me to the gist on Github entitled React 16 JavaScript Environment.md. There, I learned that React 16 depends on the collection types Map and Set. And, that if developers

are supporting older browsers and devices which may not yet provide these natively (e.g. IE < 11), (they should) consider including a global polyfill in (their) bundled application, such as core-js or babel-polyfill.

Since their example used core-js, I decided to go that route. Next, the warning in Terminal also let me know that React depends on requestAnimationFrame, even in test environments. And the React Team, specifically @gaearon (Dan Abramov), states:

React also depends on requestAnimationFrame (even in test environments). A simple shim for testing environments would be: global.requestAnimationFrame = function(callback) {setTimeout(callback, 0);};

So I first installed core-js using npm:

npm install core-js --save-dev

Then, in index.js, I added the following at the top:

import React, { Component } from 'react';
import { render } from 'react-dom';
import 'core-js/es6/map';
import 'core-js/es6/set';
import './images/favicon.ico';

And in App.test.js, right below my imports, I added:

global.requestAnimationFrame = function(callback) { 
    setTimeout(callback, 0);
};

Next, I installed raf:

npm install raf --save-dev

After that, I added the following in my package.json within my Jest configuration:

"jest": {
    "setupFiles": [
      "raf/polyfill"
    ],
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less)$": "identity-obj-proxy"
    }
},

And lastly, I decided to install the identity-obj-proxy npm package so that I could mock a proxy for my className lookups in Jest Snapshot Testing because I use CSS Modules:

npm install identity-obj-proxy --save-dev

t comes recommended.

Then I typed npm run test again to see what happens. This is what was returned in Terminal:

PASS  src/App.test.js PASS  src/sum.test.js
Test Suites: 2 passed, 2 totalTests: 2 passed, 2 totalSnapshots: 0 totalTime: 1.274s

Success! I added all the new features required for React 16 (so far), and all my warnings and errors were gone.

I think the React Team is realizing that there are more and more developers either customizing create-react-app or developing their own workflows. Either way, I am grateful for all this awesome documentation. Thanks React, espcially @gaearon (Dan Abramov), who made this gist!

Related Articles:

Tagged in: react react-16 dependencies new-features workflows
  • ← Prev
  • Next →