dom-testing-library
dom-testing-library copied to clipboard
ReferenceError: process is not defined when using with karma, webpack, and jasmine
-
@testing-library/dom
version:8.19.0
but I verified this has been present since at least7.31.2
-
Testing Framework and version:
karma-webpack 5.0.0
,karma-jasmine 4.0.0
,jasmine-core 3.7.0
-
DOM Environment:
Chrome Headless 105.0.5177.0 (Mac OS 10.15.7)
Relevant code or config:
In a Jasmine test:
import screen from '@testing-library/dom';
What you did:
Execute the test suite in Chromium using karma:
karma start karma.conf.js --browsers=ChromeHeadlessOpt --single-run
The karma.conf.js uses karma-webpack
to bundle the tests.
What happened:
When evaluating the @testing-library/dom
import, some code that @testing-library/dom
imports assumes that it is running in a Node environment and tries to access the process
variable. It's not defined since the test is running in a browser environment, so we get this error:
An error was thrown in afterAll
Uncaught ReferenceError: process is not defined
ReferenceError: process is not defined
at Object.push.b (/var/folders/3h/v_p6s_s50s39ydrwn9r7r4300000gn/T/_karma_webpack_545704/webpack:/node_modules/react-is/index.js:3:1)
at __webpack_require__ (http://localhost:9876/webpack:/@ni/nimble-components/webpack/bootstrap:19:1)
at Object.<anonymous> (/var/folders/3h/v_p6s_s50s39ydrwn9r7r4300000gn/T/_karma_webpack_545704/webpack:/node_modules/@testing-library/dom/node_modules/pretty-format/build/plugins/ReactElement.js:8:39)
at __webpack_require__ (http://localhost:9876/webpack:/@ni/nimble-components/webpack/bootstrap:19:1)
at Object.<anonymous> (/var/folders/3h/v_p6s_s50s39ydrwn9r7r4300000gn/T/_karma_webpack_545704/webpack:/node_modules/@testing-library/dom/node_modules/pretty-format/build/index.js:26:44)
at __webpack_require__ (http://localhost:9876/webpack:/@ni/nimble-components/webpack/bootstrap:19:1)
at Object.push.__webpack_unused_export__.value (/var/folders/3h/v_p6s_s50s39ydrwn9r7r4300000gn/T/_karma_webpack_545704/commons.js:18062:13)
at __webpack_require__ (http://localhost:9876/webpack:/@ni/nimble-components/webpack/bootstrap:19:1)
at Object.push.__webpack_require__.d.ListOption (/var/folders/3h/v_p6s_s50s39ydrwn9r7r4300000gn/T/_karma_webpack_545704/commons.js:13638:15)
at __webpack_require__ (http://localhost:9876/webpack:/@ni/nimble-components/webpack/bootstrap:19:1)
Reproduction:
I have a reproduction in my project repo which I could share or try to pare down if needed, but I wanted to start the discussion first to ensure this seems like something that maintainers think should and could be fixed in this repo.
Problem description:
The code that tries to access process
is in react-is
index.js.
That code is pulled in because @testing-library/dom
is importing everything from pretty-format
which includes its React support.
My project doesn't use React at all so it would be nice if the React code could be tree shaken away.
Suggested solution:
This is similar to https://github.com/testing-library/angular-testing-library/issues/244 in angular-testing-library
which I believe was fixed by guarding against accessing the process
variable. However since the code that's accessing process
is not part of testing-library, that fix doesn't seem feasible here. If we can't come up with a fix in testing-library then we could consider filing a bug to pretty-format
or react-is
asking them to do this.
I'd hope testing-library could sever this dependency chain somewhere when a test suite isn't using React but I'm not sure what the right place to do this would be.
Workaround
Define process
globally so that the code that accesses it doesn't fail. Once the react-is
code gets past the place that it tries to access process
, it isn't needed so using a stubbed process
is ok.
In setup.ts
which is part of the files
array in karma.conf.js
, add code like:
window.process = {
env: {
NODE_ENV: 'production'
}
};
Is it possible to use https://webpack.js.org/plugins/environment-plugin/ ?
Thanks for the idea @juanca! I verified that I can use environment plugin in our karma-webpack config and it has a similar effect as the workaround I listed in the description (and I like it better because it's using an official webpack API rather than messing with the global scope).
// karma.conf.js
const webpackEnvironmentPlugin = new webpack.EnvironmentPlugin({ NODE_ENV: 'production' });
module.exports = config => {
const options = {
webpack: {
plugins: [ webpackEnvironmentPlugin ]
}
}
}
However for my use case I think I'd still call it a workaround. I'm a library developer trying to leverage testing-library to provide better testing utilities for my library's clients. I'd like to avoid having to tell my clients that they need to configure their build in a particular way in order to use my library's testing utilities. It would be cleaner if testing-library didn't pull in a dependency that required that. (I acknowledge that the dependency presumably provides value and it wouldn't be trivial to remove it, just speaking as someone trying to build a library that clients can treat as a "black box").