compiling Promises with babel and core-js causes infinite window reload - es6-promise

I want to run the following piece of code on IE11
let myPromise = Promise.resolve(123);
myPromise.then((value) => {
console.log(value);
});
My recipe is Rollup and babel (& core-js for polyfilling) with the following .babelrc configuration:
{
"presets": [
["#babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3,
"targets": {
"browsers": ["last 2 versions", "ie >= 11"]
}
}]
]
}
When I try to load the code, I get some infinite loop. The browser's tab seems to reload every couple of milliseconds.

I just wanted you to know that your question/issue in core-js (https://github.com/zloirock/core-js/issues/627) was really helpful and solved the problem for me, which was exactly the same as yours there and here.
So I wanted to leave here the solution provided there by Denis Pushkarev - as I did find this topic first and it may help other developers to quick get an answer:
You could change options to format: 'iife' to make it work.

Related

ResizeObserver - loop limit exceeded

About two months ago we started using Rollbar to notify us of various errors in our Web App. Ever since then we have been getting the occasional error:
ResizeObserver loop limit exceeded
The thing that confuses me about this is that we are not using ResizeObserver and I have investigated the only plugin which I thought could possibly be the culprit, namely:
Aurelia Resize
But it doesn't appear to be using ResizeObserver either.
What is also confusing is that these error messages have been occuring since January but ResizeObserver support has only recently been added to Chrome 65.
The browser versions that have been giving us this error are:
Chrome: 63.0.3239 (ResizeObserver loop limit exceeded)
Chrome: 64.0.3282 (ResizeObserver loop limit exceeded)
Edge: 14.14393 (SecurityError)
Edge: 15.15063 (SecurityError)
So I was wondering if this could possibly be a browser bug? Or perhaps an error that actually has nothing to do with ResizeObserver?
You can safely ignore this error.
One of the specification authors wrote in a comment to your question but it is not an answer and it is not clear in the comment that the answer is really the most important one in this thread, and the one that made me comfortable to ignore it in our Sentry logs.
This error means that ResizeObserver was not able to deliver all observations within a single animation frame. It is benign (your site will not break). – Aleksandar Totic Apr 15 at 3:14
There are also some related issues to this in the specification repository.
It's an old question but it still might be helpful to someone. You can avoid this error by wrapping the callback in requestAnimationFrame.
For example:
const resizeObserver = new ResizeObserver(entries => {
// We wrap it in requestAnimationFrame to avoid this error - ResizeObserver loop limit exceeded
window.requestAnimationFrame(() => {
if (!Array.isArray(entries) || !entries.length) {
return;
}
// your code
});
});
If you're using Cypress and this issue bumps in, you can safely ignore it in Cypress with the following code in support/index.js or commands.ts
const resizeObserverLoopErrRe = /^[^(ResizeObserver loop limit exceeded)]/
Cypress.on('uncaught:exception', (err) => {
/* returning false here prevents Cypress from failing the test */
if (resizeObserverLoopErrRe.test(err.message)) {
return false
}
})
You can follow the discussion about it here.
As Cypress maintainer themselves proposed this solution, so I believe it'd be safe to do so.
We had this same issue. We found that a chrome extension was the culprit. Specifically, the loom chrome extension was causing the error (or some interaction of our code with loom extension). When we disabled the extension, our app worked.
I would recommend disabling certain extensions/addons to see if one of them might be contributing to the error.
For Mocha users:
The snippet below overrides the window.onerror hook mocha installs and turns the errors into a warning.
https://github.com/mochajs/mocha/blob/667e9a21c10649185e92b319006cea5eb8d61f31/browser-entry.js#L74
// ignore ResizeObserver loop limit exceeded
// this is ok in several scenarios according to
// https://github.com/WICG/resize-observer/issues/38
before(() => {
// called before any tests are run
const e = window.onerror;
window.onerror = function(err) {
if(err === 'ResizeObserver loop limit exceeded') {
console.warn('Ignored: ResizeObserver loop limit exceeded');
return false;
} else {
return e(...arguments);
}
}
});
not sure there is a better way..
add debounce like
new ResizeObserver(_.debounce(entries => {}, 200);
fixed this error for me
The error might be worth investigating. It can indicate a problem in your code that can be fixed.
In our case an observed resize of an element triggered a change on the page, which caused a resize of the first element again, which again triggered a change on the page, which again caused a resize of the first element, … You know how this ends.
Essentially we created an infinite loop that could not be fitted into a single animation frame, obviously. We broke it by holding up the change on the page using setTimeout() (although this is not perfect since it may cause some flickering to the users).
So every time ResizeObserver loop limit exceeded emerges in our Sentry now, we look at it as a useful hint and try to find the cause of the problem.
In my case, the issue "ResizeObserver - loop limit exceeded" was triggered because of window.addEventListener("resize" and React's React.useState.
In details, I was working on the hook called useWindowResize where the use case was like this const [windowWidth, windowHeight] = useWindowResize();.
The code reacts on the windowWidth/windowHeight change via the useEffect.
React.useEffect(() => {
ViewportService.dynamicDimensionControlledBy(
"height",
{ windowWidth, windowHeight },
widgetModalRef.current,
{ bottom: chartTitleHeight },
false,
({ h }) => setWidgetHeight(h),
);
}, [windowWidth, windowHeight, widgetModalRef, chartTitleHeight]);
So any browser window resize caused that issue.
I've found that many similar issues caused because of the connection old-javascript-world (DOM manipulation, browser's events) and the new-javascript-world (React) may be solved by the setTimeout, but I would to avoid it and call it anti-pattern when possible.
So my fix is to wrap the setter method into the setTimeout function.
React.useEffect(() => {
ViewportService.dynamicDimensionControlledBy(
"height",
{ windowWidth, windowHeight },
widgetModalRef.current,
{ bottom: chartTitleHeight },
false,
({ h }) => setTimeout(() => setWidgetHeight(h), 0),
);
}, [windowWidth, windowHeight, widgetModalRef, chartTitleHeight]);
One line solution for Cypress. Edit the file support/commands.js with:
Cypress.on(
'uncaught:exception',
(err) => !err.message.includes('ResizeObserver loop limit exceeded')
);
https://github1s.com/chromium/chromium/blob/master/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc#L44-L45
https://github1s.com/chromium/chromium/blob/master/third_party/blink/renderer/core/frame/local_frame_view.cc#L2211-L2212
After looking at the source code, it seems in my case the issue surfaced when the NotifyResizeObservers function was called, and there were no registered observers.
The GatherObservations function will return a min_depth of 4096, in case there are no observers, and in that case, we will get the "ResizeObserver loop limit exceeded" error.
The way I resolved it is to have an observer living throughout the lifecycle of the page.
Managed to solve this in React for our error logger setup.
The Observer error propagates to the window.onerror error handler, so by storing the original window.onerror in a ref, you can then replace it with a custom method that doesn't throw for this particular error. Other errors are allowed to propagate as normal.
Make sure you reconnect the original onerror in the useEffect cleanup.
const defaultOnErrorFn = useRef(window.onerror);
useEffect(() => {
window.onerror = (...args) => {
if (args[0] === 'ResizeObserver loop limit exceeded') {
return true;
} else {
defaultOnErrorFn.current && defaultOnErrorFn.current(...args);
}
};
return () => {
window.onerror = defaultOnErrorFn.current;
};
}, []);
I had this issue with cypress tests not being able to run.
I found that instead of handling the exception the proper way was to edit the tsconfig.json in a way to target the new es6 version like so:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"baseUrl": "../node_modules",
"target": "es5", --> old
"target": "es6", --> new
"types": ["cypress", "#testing-library/cypress"],
"sourceMap": true
},
"include": [
"**/*.ts"
]
}

Protractor tests getting stuck in between while resolving promises when executing in Chrome

My protractor tests were working perfectly fine yesterday on Chrome Browser.
Today, it started failing consistently at a point where in I resolve a Promise. On debugging further, I found that if I commented this promise statement then it would hang at the next promise resolution statement.
There has been no change in the protractor scripts between yesterday and today. There has been some changes made by the developers in the Angular app under test but not major ones.
Can anyone help me point out what might be going wrong here?
Following is the code snippet. Its hanging at the promise resolution statement template.getTemplatesCount().then :-
mainMenu.clickTemplatesMenuOption();
templatePage.getTemplatesCount().then(count => {
console.log("Count of template card is:-"+count.toString());
templateCountBeforeInsert = count;
});
templatePage.openCreateTemplatePanel();
createTemplatePage.createTemplateWithoutDocument(templateName);
My protractor conf.json looks like this:-
exports.config = {
allScriptsTimeout: 30000000,
specs: [
'./e2e/TestPlan/*.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://10.37.1.86:81/',
getPageTimeout: 120000,
framework: 'jasmine2',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 120000,
print: function () { }
}
Following are the versions of Tools I am using:-
Protractor:- 5.1.2
ChromeDriver:- `2.32
Chrome Browser :- 61.x
You should be passing a function to your .then() block, it should be this:
templatePage.getTemplatesCount().then((count) => {
console.log("Count of template card is:-"+count.toString());
templateCountBeforeInsert = count;
});
A simple way is add catch() as below:
templatePage.getTemplatesCount().then(count => {
console.log("Count of template card is:-"+count.toString());
templateCountBeforeInsert = count;
})
.catch(function(err){
console.log('getTemplatesCount error: ' + err);
});
If you get the error log, please check getTemplatesCount() inside.

How to stop Webpack-3's PurifyCSSPlugin from cleaning to much?

Problem
Everything else equal, my final pages differ in their CSS result. The prod version lacks the proper flexbox alignment as seen in the following comparison:
Dev
Prod
The problem is caused by the PurifyCSSPlugin. I don't know how to configure it still cleaning up the right parts of the css, keeping the parts I really need?
Any help would be appreciated. The complete code is available here.
Research so far
Update 2017-08-21:
In the production version there is css missing for the following classes
subtitle
title:not(.is-spaced) + .subtitle {
margin-top: -1.5rem;
}
columns
#media screen and (min-width: 769px), print
.columns:not(.is-desktop) {
display: flex;
}
Setup
I use webpack-3 together with bulma to make a webpage. I have two script tasks defined to build my application 1. in development and 2. for production.
"dev": "webpack-dev-server --progress --colors",
"prod": "npm run clean && NODE_ENV=prod webpack -p",
Inside my webpack config I switch between two configurations for the css handling, depending on the NODE_ENV variable. The config looks as follows:
const cssConfigEnvironments = {
'dev': ['style-loader', 'css-loader?sourceMap', 'sass-loader'],
'prod': ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
})
}
In addition I disable the ExtractTextPlugin for development.
new ExtractTextPlugin({ // Builds .css, see https://github.com/webpack-contrib/extract-text-webpack-plugin
filename: '[name].css',
allChunks: true,
disable: !envIsProd
}),
The only noticeable info shown inside the console is the following deprecation warning:
(node:2275) DeprecationWarning: Chunk.modules is deprecated. Use Chunk.getNumberOfModules/mapModules/forEachModule/containsModule instead.
The problem is really coming from the PurifyCSSPlugin there is an issue already open tackling it.
As a quick fix you have to whitelist the not tag:
new PurifyCSSPlugin({
// Give paths to parse for rules. These should be absolute!
paths: glob.sync(path.join(__dirname, 'src/*.html')),
minimize: envIsProd,
purifyOptions: {
info: true,
whitelist: [ '*:not*' ]
}
})

Chrome args and prefs don't seems to be work in protractor conf

Need help with below issues. I have work around for issue 1 so any tips on issue 2 would be great:
--start-maximized won't trigger full window so my current work around is adding below line in beforeEach function:
browser.driver.manage().window().maximize();
Trying to download file to default directory but the file is just going to download folder on my C drive instead of /tmp/downloads (on another drive).
My config:
capabilities: {
'browserName': 'chrome',
'chromeOption': {
args: ['--lang=en', '--start-maximized'],
prefs: {
'download': {
'prompt_for_download': false,
'default_directory': '/tmp/downloads',
},
},
},
},
As for download, I'm currently using solution from here.
There is a typo. It should be chromeOptions, not chromeOption.
I think the options in protractor conf have been updated to be without "--".
So perhaps try without "--"?
args: ['lang=en', 'start-maximized']

TypeError: dbg is undefined in angularjs

I am learning angularjs and following tutorial from - here
Here is my index.jsp -
<!doctype html>
<html lang="en" ng-app="phoneCatApp">
<head>
<title>Angular Example</title>
<script type="text/javascript" src="angular/angular.min.js"></script>
<script type="text/javascript" src="app/js/controllers.js"></script>
</head>
<body ng-controller="phoneListCtrl">
Search : -
<input ng-model="query"/> Sort by:
<select ng-model="orderProp">
<option value="name">Alphabetical</option>
<option value="age">Newest</option>
<option value="-age">Oldest</option>
</select>
<p>Total number of phones: {{phones.length}}</p>
<ul>
<li ng-repeat="phone in phones | filter:query | orderBy:orderProp"><span>{{phone.name}}</span>
<p>{{phone.snippet}}</p></li>
</ul>
</body>
</html>
this version of controller.js works -
var phonecatApp = angular.module('phoneCatApp', []);
phonecatApp.controller('phoneListCtrlOld', function($scope) {
$scope.phones = [ {
'name' : 'Nexus S',
'snippet' : 'Fast just got faster with Nexus S.',
'age' : 1
}, {
'name' : 'Motorola XOOM™ with Wi-Fi',
'snippet' : 'The Next, Next Generation tablet.',
'age' : 2
}, {
'name' : 'MOTOROLA XOOM™',
'snippet' : 'The Next, Next Generation tablet.',
'age' : 3
} ];
$scope.orderProp = 'age';
});
but in the next step i tried fetching this json data with ajax call so controller look like this -
var phonecatApp = angular.module('phoneCatApp', []);
phonecatApp.controller('phoneListCtrl', function($scope, $http) {
$http.get('app/js/phones.json').success(function(data) {
$scope.phones = data;
});
$scope.orderProp = 'age';
});
But this gives me following error -
TypeError: dbg is undefined. debuggerLib.js (line 530)
I can see in firebug the ajax call is happening with code 304 Not Modified. and i can see data in response. but response content type is not json.
Please look into it and say what is the problem? Am i missing any js file to include or something else.
I have had this same error, and after some head scratching found a cause. I can't be sure whether this is your same cause.
Restarting Firefox, rebooting the PC, removing Firebug, reinstalling, optimizing, running registry clean, etc. -- nothing helped. I got error in debuggerLib.js line 556, dbg being undefined.
However, it turns out that I have installed Firebug back in the days, and it created a directory in my Roaming profile:
C:\Users\Leonardo\AppData\Roaming\Mozilla\Firefox\Profiles\Leonardo.Serni\firebug
In that directory there is a lot of JSON files, but none of them dated today, which is when I removed and reinstalled Firebug. So I wondered, "What if the new Firebug is loading something obsolete from this directory?".
I closed Firefox, renamed the directory from "firebug" to "bugfire", reopened Firefox.
Firebug is running perfectly and the error has disappeared. I had done the same thing without renaming the directory and the error did not disappear, so I'm confident that my hypothesis was correct.
The directory has been re-created, but there are now only two files in there - "annotations.json" and "breakpoints.json", both 0 bytes in size. Possibly some day I'll try adding the files from the old directory to see when the error comes back.
Update (thanks to DevNull's comment)
Possibly it is not necessary to nuke the whole directory. Verify that the annotations.json file is zero length. If it is not, just rename it to annotations.old while Firefox is not running.
I'm beginning to suspect that the dbg is actually debugging Firebug itself, and we do not have it defined because we aren't Firebug developers. It has nothing to do with the Firebug debugger that debugs our scripts.
You're probably using FireFox with firebug activated.
Turn off firebug and your issue will go away.
I had the same problem, other browsers had no issue and the console showed the error coming from debuggerLib.js (line 556). Deactivating it removed the error and allowed my application to run as expected.
use this code html head tag.
<base href="/">
....
Try this,
First initialize JSON array value is an empty.so initialize
$scope.phones = '';
Explanation of #LSerni seems correct.
For Linux system simply remove and reinstall your Firebug plugin. The system auto deletes all related files/folders and recreates it.
This worked for me.
The error you are having is with your JSON file. It should look like this:
[{
"name" : "Nexus S",
"snippet" : "Fast just got faster with Nexus S.",
"age" : 1
}, {
"name" : "Motorola XOOM™ with Wi-Fi",
"snippet" : "The Next, Next Generation tablet.",
"age" : 2
}, {
"name" : "MOTOROLA XOOM™",
"snippet" : "The Next, Next Generation tablet.",
"age" : 3
}]
Remember the square brackets.
Use .then rather than .success. This is an improved version of .success handling all the callbacks and calls more efficiently. It brings back the entire promise and you resolve it by referencing the .data part i.e. response.data
$http.get('app/js/phones.json').then(function(response) {
$scope.phones = response.data;
});
DEMO - Using .success
DEMO - Using .then promise
You are using the number so please use number or parse value to number example below.
<code>
var myApp = angular.module('MyApp',[]);
myApp.controller("myController",function($scope){
$scope.width=50;
$scope.height=50;
});
</code>
for me the problem was that I had forgotten to define in the controller the library
app.controller("MyCtrl", function($scope, $http) { //<- here $timeout was missing
$http.get(someUrl)
.then(function(myResponse) {
$scope.myData = myResponse.data;
$timeout(function() { //<- here $timeout was called without being defined
enableWatchers = true;
});
});
});
It works after I have changed the first line of my code to:
app.controller("MyCtrl", function($scope, $http, $timeout) { //<- here I put the $timeout