I had this error,
Attempted import error: 'LeafletProvider' is not exported from 'react-leaflet'.
when I tried to import LeafletProvider to one of my component file as follows:
import { withLeaflet, MapControl, LeafletProvider } from "react-leaflet";
I believe I have installed the latest version of react-leaflet (v.3.2.2) and have read the documentation as much as I could but I didn't see LeafletProvider in it.
Hope someone could help me fathom what to do with this. Basically, I just want to be able to change between two or more leaflet map tilelayers.
It seems the Provider has to be imported as such:
import { LeafletContext } from '#react-leaflet/core';
and used as :
<LeafletContext.Provider>
according to this page of the documentation:
https://react-leaflet.js.org/docs/core-api/#leafletprovider
Following the documentation in #Ivo's answer, here's what I did:
First install:
npm install #react-leaflet/core
Then import it like this:
import { LeafletContext } from "#react-leaflet/core"
And then use as:
<LeafletContext.Provider>
// enter code here
</LeafletContext.Provider>
I'm trying to use pdfjs-dist's example for a Typescript-React-Electron app.
import pdfjsLib from 'pdfjs-dist';
pdfjsLib.GlobalWorkerOptions.workerSrc = 'src/node_modules/pdfjs-
dist/build/pdf.worker.js';
I get GlobalWorkerOptions of undefined.
Based on what I found here
in package.json I've put:
"source": "src/app/components/pdfHandling/entry/entry.js",
where src/app/components/pdfHandling/entry/entry.js:
import * as pdfjs from 'pdfjs-dist';
pdfjs.GlobalWorkerOptions.workerSrc = 'pdf.worker.js';
export {
pdfjs,
};
I posted the same problem in Mozilla's GitHub. And this is the answer I received:
The standalone examples in our repository work, so this must be some
integration issue with React/Electron, for which we cannot provide
assistance since we're not familiar with them. I would suggest to ask
on StackOverflow or other React/Electron-specific forums instead.
Any ideas about how to make pdfjs.GlobalWorkerOptions working?
The problem was silly and subtle....
It is enough to substitute
import * as pdfjs from 'pdfjs-dist';
with
var pdfjsLib = require("pdfjs-dist");
to make the problem disappearing....
Scenario
npm test used to work without issue. Over the course of a month or so (I neglected tests) something changed and now I receive ReferenceError: document is not defined when trying to run Jest-Puppeteer tests via npm test.
This error shows up even with document removed so it seems like a puppeteer issue but I'm not sure why this is showing up now. I've checked out code from over a month ago and the tests still work but so much has changed that it's difficult to chase down the actually issue.
Attempted Solutions
upgrade node
reinstall npm packages
revert jest-puppeteer.config.js to previous version
add #jest-environment jsdom to tests which fixes the document issue but then causes ReferenceError: page is undefined
Question
How can I troubleshoot this problem short of starting over from scratch? That said, I'm prepared to start over if that's what it's going to take, which sometimes it does.
Code
this is a basic jest file
import "core-js/stable";
import "regenerator-runtime/runtime";
import {Provider} from "react-redux"
import mockState from "./mocks/mockState"
import configureStore from "redux-mock-store"
import ShallowRenderer from 'react-test-renderer/shallow'
import API from '../src/API'
import getNavigationResponse from '../src/nocks/getNavigation'
import expectedNavigationState from "./static/expectedNavigationState"
import pageObjects from "./static/pageObjects"
import utils from './utils'
import constants from '../src/constants'
describe('API tests', () => {
beforeEach(async() => {
await page.goto('http://localhost:3000');
await page.setViewport({ width: 900, height: 600 });
await page.goto('http://localhost:3000/');
await page.evaluate(() => {
document.getElementById('root').classList.add('animated-test');
});
await page.waitForSelector(pageObjects.navFactory);
});
// PASS
test('API data to be in store', async () => {
await page.waitForSelector(pageObjects.primaryNavLink);
// get state from root
const store = await utils.getStore();
expect(store[0].navigation.urlHashMap).toEqual(expectedNavigationState);
});
test.todo('Make sure content==true on vanity urls (home)')
test.todo('Make sure content==false on url items with children (visitor)')
// PASS
test('API cancel should cancel the API request', async () => {
API.dispatch = () => {
};
API.fetch(constants.NAVIGATION_HREF, 'API_FETCH_TYPE_NAVIGATION');
const promiseCanceled = API.cancel('API_FETCH_TYPE_NAVIGATION');
expect(promiseCanceled).hasOwnProperty('promise');
expect(promiseCanceled).hasOwnProperty('cancel');
});
});
** EDIT **
From what I can find out, this "ReferenceError" seems to be a babel error that is caused because babel can't seem to figure out what "document" is. I traced down where the issue is happening and it is within a third party plugin so I left a note on the developer's github page in the mean time. Currently my "solution" is to comment this test out - I'll put more effort into this again when I have time to find a proper solution
** EDIT 2 **
If I add <rootDir>/node_modules/react-json-view/dist/main.js to babel config's transformIgnorePatterns then I get a different error of
ReferenceError: regeneratorRuntime is not defined
Which is odd because I explicitly have import "regenerator-runtime/runtime" at the top. This seems to be a step closer but I'm not sure. I switched back to babel-polyfill (deprecated) just to try it but ended with a different error of TypeError: jest: failed to cache transform results.
Normally you can do something like this answer which is to add:
npm test --env=jsdom
But since I also need Puppeteer's environment there's a clash because node only seems to support ONE environment.
Ultimately I removed the troubled plugin.
Normally I write like below, when it comes to D3.
var q = d3.queue()
q.defer(d3.json, "/data/tokyo.json")
.defer(d3.csv, "/data/city_name.csv")
.await(mainFunc);
function mainFunc(_error, _json, _csv){
.....
}
However I have no idea how to write code in React Component.
It should be imported like this.
import {queue} from 'd3-queue'
import {json} from 'd3-json' // <- There is no npm package.
import {csv} from 'd3-csv' // <- There is no npm package.
var q = d3.queue()
q.defer(json, "/data/tokyo.json")
.defer(csv, "/data/city_name.csv")
.await(mainFunc);
However there are no npm module like d3-json and d3-csv.
How can I write code?
You import the name queue but then you don't use it anywhere. Instead you use the name d3 which you did not import at all. The npm package you are searching for is d3-request:
import {queue} from 'd3-queue';
import {json, csv} from 'd3-request';
Got this error after upgrading to React when I ran my Jest unit tests:
React depends on requestAnimationFrame. Make sure that you load a polyfill in older browsers.
How do I fix it?
I'm using Jest 18.1.0.
Found a workaround!
Steps:
Create the file __mocks__/react.js
Add the following into __mocks__/react.js
const react = require('react');
// Resolution for requestAnimationFrame not supported in jest error :
// https://github.com/facebook/react/issues/9102#issuecomment-283873039
global.window = global;
window.addEventListener = () => {};
window.requestAnimationFrame = () => {
throw new Error('requestAnimationFrame is not supported in Node');
};
module.exports = react;
Run jest !
As marked on comments on the code
This is the solution from
https://github.com/facebook/react/issues/9102#issuecomment-283873039
this worked for me:
Install raf
npm install --saveDev raf or yarn add -D raf
Add the polyfill to your setupFiles in your jest config in package.json like this:
'setupFiles': ['raf/polyfill']
Note: if you have other setup files in this array, you may want to put raf/polyfill first.
If you just need to polyfill it for tests, then you don't actually need the throttling.
Create a new file with this code:
global.requestAnimationFrame = function (cb) {
return setTimeout(cb, 0);
};
Add that file to the jest/setupFiles array in your package.json.
If you are using create-react-app, some of these solutions will not work well (or at all, in the case of setupFiles). What does work well is creating a file at src/setupTests.js and adding your mock in there:
global.requestAnimationFrame = (cb) => { cb(); };
You can also add other global mocks in there (e.g. localStorage and navigator.serviceWorker).
Another working solution!
The idea is to load a simple shim before each spec, by using the setupFiles property in the jest config.
Create a file shim.js file (preferably in your root dir) and have this code in it:
global.requestAnimationFrame = (callback) => {
setTimeout(callback, 0);
};
Next, you may be having redundant code that keep reappearing in all/most of your files - and you want to put them in a single file and have them run before each spec also, to do that:
Create a setup.js file in the root dir too. A good piece of redundant code to D.R.Y is the react enzyme adapter configuration code. Paste it here
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
Now create the jest.config.js file, to specify the paths of the two files
{
module.exports = {
"setupFiles": ["<rootDir>shim.js", "<rootDir>setup.js"]
}
}
N.B: The jest config file take json, so make sure json's in. Also, if your shim.js and setup.js files are not in the same dir as your jest.config.js, adjust the path accordingly.
Hope this helps!
Credit: https://github.com/facebook/jest/issues/4545
Here's a realistic way to mock requestAnimationFrame:
let time;
const maxTimeElapsed = 2000;
beforeEach(() => {
time = 0;
jest.spyOn(window, 'requestAnimationFrame').mockImplementation(cb => {
time += 100;
if (time < maxTimeElapsed) {
return cb(time) as any;
}
});
});
in your test, it repeatedly calls the RAF callback until it reaches the max elapsed time that you set. It happens instantly, so you don't need to stall it.
Just upgrade your react-scripts to 1.0.15 or above. It has been officially fixed after that version. See more details in https://github.com/facebook/create-react-app/issues/3199
Search the comment of gaearon commented on 31 Oct 2017
If you use TypeScript, the best solution is;
window.requestAnimationFrame = (): number => {
window.clearTimeout();
return 0;
};
Before all your describe and test suits.
According raf package docs at this moment need to run polyfill() function and specify object that need to be polyfilled. In my case works:
require('raf').polyfill(global.window)
Turns out it was because I upgraded enzyme without upgrading react and react-dom.
React 15.5 brings about some deprecations that caused many dependent libraries to have to update too. Make sure you are updating react, react-dom and check the README of those dependent packages for new libraries you have to install. For instance, Enzyme 2.8.2 now requires react-addons-test-utils as a dependency.