I have the following gulp task in my gulpfile.js:
gulp.task('build-scripts', function () {
var b = browserify({ debug: false });
b.transform(reactify);
b.transform(envify({
_: 'purge',
NODE_ENV: 'production'
}));
b.add('./src/scripts/index.js');
return b.bundle()
.pipe(source('./www/scripts/dist/bundle.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('.'))
});
The task completes with status 0 and the React transform happens, but in bundle.js I still see:
if (process.env.NODE_ENV !== 'production') {
Wasn't this supposed to go away with the envify transform?
Am I doing something wrong here?
I have done some digging, but all the solutions I can find are os x / linux specific (I'm on a windows machine).
EDIT: I am running the gulp build from within visual studio's Task Runner Explorer.
The doc says:
By default, environment variables that are not defined will be left untouched.
https://github.com/hughsk/envify#purging-processenv
Have you tried defining it before running that? i.e.
process.env.NODE_ENV = 'production';
Related
I'm trying to upgrade my project to React 18, everything works in dev and production mode in the browser. But after upgrading to the latest version of #testing-library/react some of my unit tests are failing and a lot of them are logging the following warning:
console.error
Warning: The current testing environment is not configured to support act(...)
at printWarning (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:86:30)
at error (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:60:7)
at isConcurrentActEnvironment (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:25057:7)
at warnIfUpdatesNotWrappedWithActDEV (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:27351:12)
at scheduleUpdateOnFiber (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:25292:5)
at setLoading (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:17342:16)
at _callee2$ (node_modules/.pnpm/#cubejs-client+react#0.29.51_react#18.0.0/node_modules/#cubejs-client/react/src/hooks/cube-query.js:56:7)
First thing I did was check my versions, cleared node modules and lock file just in case:
react 18.0.0
react-dom 18.0.0
#testing-library/react version: "13.1.1",
Testing Framework and version: "jest": "27.5.1",
DOM Environment: jsdom 16.7.0
But everything looks right?
I checked the migration docs for React 18: https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html
Which says the latest version of #testing-library/react shouldn't require the globalThis.IS_REACT_ACT_ENVIRONMENT = true setting.
But I tried setting that manually anyway before my tests run. But that didn't fix it either, (I tried several versions)
// #ts-ignore
global.IS_REACT_ACT_ENVIRONMENT = true
// #ts-ignore
globalThis.IS_REACT_ACT_ENVIRONMENT = true
// #ts-ignore
self.IS_REACT_ACT_ENVIRONMENT = true
// #ts-ignore
window.IS_REACT_ACT_ENVIRONMENT = true
// #ts-ignore
this.IS_REACT_ACT_ENVIRONMENT = true
None of those fixes the Warning or the unit tests.
I'm using jest v. 27.x with jsdom which I imagine would be the most common configuration? So I'm quite surprised to be running into this error?
Here is my jest.config
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
moduleNameMapper: {
'^src/(.*)$': '<rootDir>/src/$1',
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
},
transform: {
'^.+\\.(t|j)sx?$': ['ts-jest'],
},
setupFilesAfterEnv: ['./src/setupTests.tsx'],
modulePathIgnorePatterns: ['src/common/config.ts'],
coverageReporters: ['text', 'json'],
}
Any ideas why a relatively simple setup like this, would be running into this warning with RTL v. 13.1.1?
In my case this warning was appearing because I had accidentally imported act from react-dom/test-utils instead of #testing-library/react. Fixing the import made the warning disappear.
In my case this happened because I had a useless act that I implemented as a workaround in v12.
await act(async () => {
const hours = await screen.findByText('-6h')
expect(hours).toBeInTheDocument()
})
I removed the useless act around my assertion in this test, and the warning about the "environment not configured to support act" was resolved.
In my case, this particular test was failing after upgrading to v13, which is how I ended up trying to clean it up.
The warning message was essentially not helpful in debugging this.
I didn't find the reason why the global flag was not working for me, so the following monkey patch resolved the log lines for me
const originalConsoleError = console.error;
console.error = (...args) => {
const firstArg = args[0];
if (
typeof args[0] === 'string' &&
(args[0].startsWith(
"Warning: It looks like you're using the wrong act()"
) ||
firstArg.startsWith(
'Warning: The current testing environment is not configured to support act'
) ||
firstArg.startsWith('Warning: You seem to have overlapping act() calls'))
) {
return;
}
originalConsoleError.apply(console, args);
};
Yes, it's super ugly and likely not the best solution to the problem, but then again React does something pretty similar in their codebase.
It can also happen if the tested code has a timeout that executes a callback after the test has finished. For instance with a throttle on a user input.
It can be avoided by either using the done callback provided by jest or to make the timers to finish instantly with the timer mocks.
I created a rust-wasm module and use workerize-loader to load it:
export const getQRCode = async (
arg: string,
width: number,
height: number
) => {
const { qrcode } = await import('uranus-qrcode');
return qrcode(arg, width, height);
};
and then I use the worker as such:
// #ts-ignore
// eslint-disable-next-line import/no-webpack-loader-syntax
import qrCodeWorker from 'workerize-loader!workers/qrCodeWorker';
...
const workerizeQRLoader = async () => {
try {
const instance = qrCodeWorker();
const qr = await instance.getQRCode(href, 150, 150);
setQRCode({
__html: qr
});
} catch (e) {
console.warn(e);
}
};
...
useEffect(() => {
workerizeQRLoader();
// qrLoader();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
...
The above works in dev mode, but after compiling it says:
TypeError: a.getQRCode is not a function
at 8.a2ac9b2e.chunk.js:1
at l (0.69608c56.chunk.js:2)
at Generator._invoke (0.69608c56.chunk.js:2)
at Generator.forEach.e.<computed> [as next] (0.69608c56.chunk.js:2)
at r (0.69608c56.chunk.js:2)
at s (0.69608c56.chunk.js:2)
at 0.69608c56.chunk.js:2
at new Promise (<anonymous>)
at 0.69608c56.chunk.js:2
at 8.a2ac9b2e.chunk.js:1
If I import the rust-wasm module directly into the main thread it works:
...
const qrLoader = async () => {
const { qrcode: render } = await import('uranus-qrcode');
const qr = await render(href, 150, 150);
setQRCode({
__html: qr
});
};
useEffect(() => {
// workerizeQRLoader();
qrLoader();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
...
Basically I try to get React (Webpack & TypeScript flavor) to load WebAssembly modules (aka wasm, created via Rust-Wasmbindgen) through web workers. I've tried workerize-loader + wasm-loader, and it works pretty well in the dev mode but once it is compiled, the prototype will not be added to the worker (suspecting it's a bug in workerize-loader because all workerized modules behave the same). I also tried to work with worker-loader + comlink, but the worker-loader doesn't seem to work with wasm-loader (would not be able to import wasm into the worker). The only way to get this to work is to load wasm into the main thread via wasm-loader and just give up the multi-threads setup which is basically a shame...so does anyone have successfully use a WebAssembly module loaded through a web worker in a React TypeScript project? What's your setup?
I also created a starter project: https://github.com/aeroxy/react-typescript-webassembly-starter.git
You can checkout the "workerize" branch and see how it works in dev mode but after compiling, it throws "not a function" error.
This is a bit much for a comment but I got some bad and good news. Executed the following commands using node v12.16.1 and yarn 1.22.4:
git clone https://github.com/aeroxy/react-typescript-webassembly-starter.git
cd react-typescript-webassembly-starter
yarn # some warnings that packages need to be updated to later version
yarn start # dev version works
yarn build
cd build
npx serve
When opening the build version in Google Chrome 81.0.4044.113 (Official Build) (64-bit) on my Fedora 31 I can see the qr code, no errors in console.
That means that there is no fault in the project (good news) but something maybe wrong in settings on your machine (bad news), the os you are using or some other machine specific difference.
You could try a to clone the project again and run the commands exactly like I did to see if that's working. Older npm could have some problems with cached packages but that's been fixed for a while now. A while ago you needed to change the repository for npm or use vpn because it was blocked, this could also be causing you trouble.
This is a duplicate of my original answer but got deleted for some odd reason by a moderator without leaving a reason.
Now the workerize method works!
I've originally tried workerize-loader + wasm-loader, and it works pretty well in the dev mode but once it is compiled, the prototype will not be added to the worker (suspecting it's a bug in workerize-loader because all workerized modules behave the same). This indeed turns out to be a bug in workerize-loader (see workerize-loader failed to work after compiling and Version 1.2.0 does not export function on worker instance in production mode). After upgrading to the workerize-loader 1.2.1, it works in both dev and prod code.
I have updated the Master repo: https://github.com/aeroxy/react-typescript-webassembly-starter.git
I am having some trouble getting process.env.NODE_ENV set in webpack production build.
I am setting this via
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
},
}),
In my app code this is working fine I have:
console.log(process.env.NODE_ENV);
which gets converted to
console.log("production");
in the compiled output from the build.
However I am getting errors from redux that this has not been set.
in the output I have this code
if (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {
(0, _warning2['default'])('You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.');
}
and process.env is an empty object. So it looks as though webpack is not injecting this correctly. The function that contains the redux check starts like this:
/* 152 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(process) {
I'm not sure what I'm missing here but looks like I'm not getting the optimised build version of redux and maybe some other dependencies inn my build because of this error.
I am usually splitting vendor code and app code into separate files during production build and uglifing but I have run this test outputting to a single file and without the minification just to test this issue
When compiling a React and Redux application with Webpack and Babel I get:
Uncaught TypeError: Cannot assign to read only property '__esModule' of #<Object>
In some older browsers (<= Chrome 1, Android 4, Safari 5).
This issue seems to stem from redux and react-redux outputting the line exports.__esModule = true; in the lib build but my application using Object.defineProperty instead (because they build loosely and I do not).
Two solutions are:
Building my application in loose mode also.
Importing react-redux/src and redux/src and building it with the same .babelrc as the application (everything is not loose).
As long as they are consistent and both:
Object.defineProperty(exports, "__esModule", {
value: true
});
and exports.__esModule = true; do not co-exist in my output, everything works.
My question is, what is the right solution? Why does this only affect older browsers? And why do they conflict?
Here is a similar question.
Object.defineProperty is broken on some Android 4 stock browser versions and probably other browsers that made use of a buggy implementation in Webkit.
Check this bug report
and and this other one reported to the chromium project.
The good news is you can apply this polyfill to fix the problem.
To make thing easy, you can simply copy and paste that polyfill on a <script> tag before your bundle.
This will fix your issues.
My guess is, you need to install babel-plugin-add-module-exports and in your .babelrc register this plugin:
"plugins": [
"babel-plugin-add-module-exports"
]
For more information visit this website.
In my case, I solved to add babel-register library in entry points.
In webpack.config.js (Webpack 1.x version of configuration)
// As is
entry: {
main: 'index.js'
},
// To be
entry: {
main: ['babel-register', 'index.js']
},
We met this problem on Android 4.0 and currently we cannot cut the support for Android 4.0.
For webpack 1.0, just set loose: true when you are using babel-preset-env.
However for Webpack 2, loose mode can't resolve this problem.
Finally, we found this trick, a little ugly.
// client_patch.js, For Android 4.0
var defineProperty = Object.defineProperty;
Object.defineProperty = function (exports, name) {
if (name === '__esModule') {
exports[name] = true;
return;
}
return defineProperty.apply(this, arguments);
};
And in your webpack config file.
// webpack.config.js
entry: {
main: [
path.resolve(__dirname, 'client_patch.js'),
'index.js'
]
}
Hello!
I'm trying to take screenshots in protractor and browserstack, I've the following conf.js file:
var HtmlReporter = require('protractor-html-screenshot-reporter');
var reporter=new HtmlReporter({
baseDirectory: './protractor-result', // a location to store screen shots.
docTitle: 'Report Test Summary',
docName: 'protractor-tests-report.html'
});
// An example configuration file.
exports.config = {
// The address of a running selenium server.
seleniumAddress: 'http://hub.browserstack.com/wd/hub',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome',
'version': '22.0',
'browserstack.user' : 'user_name',
'browserstack.key' : 'user_key',
'browserstack.debug' : 'true'
},
// Spec patterns are relative to the current working directly when
// protractor is called.
specs: ['./specs/home_page_spec.js'],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000
},
onPrepare: function() {
jasmine.getEnv().addReporter(reporter);
}
};
And the browserstack help says that I need to add the following lines:
var fs = require('fs');
webdriver.WebDriver.prototype.saveScreenshot = function(filename) {
return driver.takeScreenshot().then(function(data) {
fs.writeFile(filename, data.replace(/^data:image\/png;base64,/,''), 'base64', function(err) {
if(err) throw err;
});
})
};
driver.saveScreenshot('snapshot1.png');
Does any one could point me to where to add these lines? and how? (I'm also using PageObject pattern)
I think you are talking about two things, one is the plugin for making screenshots and the second is a creating screeshots manually within your test code regardless a plugin.
In theory, the plugin should make screenshots for you. If not you can create them manually with the code provided from browserstack, just put in anywhere in your test code after some expects.
Anyway, to make screenshots from protractor I recommend use protractor-screenshoter-plugin
(disclaimer: I am the author), also you can have a look at Protractor-Screenshots-Alernatives
Now in one of the branches I have a new support for parallelization. Have a look at https://github.com/azachar/protractor-screenshoter-plugin/tree/feat-parallel-support.
To install the unstable version that contains the parallelization support use
npm install azachar/protractor-screenshoter-plugin#feat-parallel-support
to install stable version without parallel support, just type as usual:
npm install protractor-screenshoter-plugin
Let me know if it works as expected!
Cheers,
Andrej