'`ReferenceError: TextEncoder is not defined` when running `react-scripts test --env=jsdom`
I'm using a TensorFlow encoder in my application. It works fine in my browser when the application is running but I get issues when testing that it builds:
$ npx react-scripts test --env=jsdom
FAIL src/App.test.js
● Test suite failed to run
ReferenceError: TextEncoder is not defined
16 | import TextField from '@material-ui/core/TextField';
17 | import Typography from '@material-ui/core/Typography';
> 18 | import * as mobilenet from '@tensorflow-models/mobilenet';
| ^
19 | import * as UniversalSentenceEncoder from '@tensorflow-models/universal-sentence-encoder';
20 | import * as tf from '@tensorflow/tfjs';
21 | import axios from 'axios';
at new PlatformBrowser (node_modules/@tensorflow/tfjs-core/src/platforms/platform_browser.ts:26:28)
at Object.<anonymous> (node_modules/@tensorflow/tfjs-core/src/platforms/platform_browser.ts:50:30)
at Object.<anonymous> (node_modules/@tensorflow/tfjs-core/src/index.ts:29:1)
at Object.<anonymous> (node_modules/@tensorflow/tfjs-converter/src/executor/graph_model.ts:18:1)
at Object.<anonymous> (node_modules/@tensorflow/tfjs-converter/src/index.ts:17:1)
at Object.<anonymous> (node_modules/@tensorflow-models/mobilenet/dist/index.js:38:14)
at Object.<anonymous> (src/components/model.js:18:1)
at Object.<anonymous> (src/App.js:8:1)
at Object.<anonymous> (src/App.test.js:3:1)
I'd like to get rid of that error. I've tried using the 'text-encoding' package but I'm not sure how get TextEncoder properly defined before the import happens.
Maybe I can set a different option for --env?
I get the same error without --env=jsdom. I believe I added it after getting similar types of not defined errors and it corrected an issue.
Here is my test:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});
So setting --env=node does not work either because: ReferenceError: document is not defined.
Solution 1:[1]
I am getting same error for my Node.Js project. For testing purpose I used jest there. So following steps are resolved my issue
step-1: on the root folder of your project add a file named as jest.config.js
step-2: Add the following lines in the jest.config.file:
module.exports = {
testEnvironment: "node"
};
Solution 2:[2]
I faced this problem when using mongodb. I used @Phoenix solution with a little change.
First I used jest-environment-node instead of jest-environment-jsdom:
const NodeEnvironment = require('jest-environment-node');
// A custom environment to set the TextEncoder that is required by mongodb.
module.exports = class CustomTestEnvironment extends NodeEnvironment {
async setup() {
await super.setup();
if (typeof this.global.TextEncoder === 'undefined') {
const { TextEncoder } = require('util');
this.global.TextEncoder = TextEncoder;
}
}
}
Then I added the environment in the jest configs for all tests as Cava said in the comments:
// package.json
{
...
"jest": {
...
"testEnvironment": "<rootDir>/tests/custom-test-env.js"
}
...
}
Solution 3:[3]
According to the latest jest v28 (https://jestjs.io/docs/upgrading-to-jest28) and react 18 I had to modify a bit the script
so my preSetup.js
const Environment = require('jest-environment-jsdom-global');
/**
* A custom environment to set the TextEncoder
*/
module.exports = class CustomTestEnvironment extends Environment {
constructor({ globalConfig, projectConfig }, context) {
super({ globalConfig, projectConfig }, context);
if (typeof this.global.TextEncoder === 'undefined') {
const { TextEncoder } = require('util');
this.global.TextEncoder = TextEncoder;
}
}
};
Solution 4:[4]
Doesnt work using below config
"testEnvironment": "<rootDir>/tests/custom-test-env.js"
const NodeEnvironment = require('jest-environment-node');
// A custom environment to set the TextEncoder that is required by mongodb.
module.exports = class CustomTestEnvironment extends NodeEnvironment {
async setup() {
await super.setup();
if (typeof this.global.TextEncoder === 'undefined') {
const { TextEncoder } = require('util');
this.global.TextEncoder = TextEncoder;
}
}
}
using "jest": "^28.0.3",
Solution 5:[5]
Thanks for these answers. A simpler format that seems to work, at least with testEnvironment: 'jsdom' is:
setupFiles: [`<rootDir>/jest-shim.js`],
jest-shim.js:
import { ArrayBuffer, TextDecoder, TextEncoder, Uint8Array } from 'util';
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
global.ArrayBuffer = ArrayBuffer;
global.Uint8Array = Uint8Array;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nibedita Pattnaik |
| Solution 2 | Mostafa Rowghanian |
| Solution 3 | ayxos |
| Solution 4 | Brendon |
| Solution 5 | Mosesoak |
