Issues caused by low-version browsers
Recently developed a project based on webpack+babel+react
, generally local is in chrome browsing above development, Chrome browser development because support most of the new JS features, so generally do not need polyfill, such as Promise,string instance includes method. Even in the low version of the browser, through babel-runtime
the Polyfill can also be converted, but things do not unexpectedly, the project in the IE9 browser error, errors are as follows:
Obviously, the project is used Promise
, but IE9 does not support the new feature, which results in an error.
So, the problem comes, babel-runtime
not automatically polyfill the function in the project Promise
, why not? Here's a discussion.
Babel-runtime really helped us convert?
According to the Babel official website, and the babel-runtime
babel-polyfill
same, are not supported by the new features Polyfill, just:
babel-runtime: He will not pollute the global environment, will be polyfill locally, and will not convert some instance methods, such as ' abc '. Includes (' A '), where the includes method will not be translated. It is generally combined babel-plugin-transform-runtime
to use.
Babel-polyfill: Simple Brute, he will pollute the global environment, such as in the browser does not support promise Polyfill a global promise object for the call; Unsupported instance methods also add methods to Polyfill on the corresponding constructor prototype chain.
So the promise,babel-runtime in the above example really helped us convert it, tested it in the project, and it did convert.
let _promise = new Promise()
As above, test the code to see the corresponding conversion file:
Can see, in the project, babel-runtime
really helped us to carry out the Polyfill, then why also reported above promise undefined error???
Promise Undefined Error true killer
Now that the code for the babel-runtime
Babel compiled code is converted, you can guess:
The real reason for the error is that some code has not been babel-runtime compiled for conversion .
The first thing to think about is the node_modules module, because some NPM packages do not require Babel compilation in the Webpack configuration, and these packages may require promise native support functionality.
For example vuex
, a similar question has been raised on GitHub before vuex requires a promise polyfill in this browser
. Because it is judged in the source code:
assert(typeof Promise !== ‘undefined‘, "vuex requires a Promise polyfill in this browser.");
This situation needs to be mainly, after the investigation, in this project, did not discover is because the NPM package causes. Then there is the possibility thatWEBAPCK itself produces some code .
By locating where errors occur, it is true that the code that Webpack itself produces needs to be promise. In Webpack's official website also found the answer :
It can be found that when Webpack uses the asynchronous load module, it require.ensure
needs to natively support promise, because our project is loaded on demand, which is why the above problem arises. That
The new promise-related code generated by Webpack is beyond the control of Babel Babel-runtime, and only Polyfill global promise can resolve this issue.
To solve the above problem, most people will think of using other promise Polyfill libraries, such as babel-polyfill
or es6-promise
, this is a solution, but can be combined with babel-runtime conversion function for the global promise Polyfill, No additional libraries are introduced. The code is as follows:
// 将Promise抛出为全局对象window.Promise= Promise
Then Babel-runtime will convert it to the following:
// 将Promise抛出为全局对象window.Promise=__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_promise___default.a()
In this way, the polyfill of the Babel-runtime promise is hung under the window to achieve the Polyfill effect of the other promise.
Selection in cross-browser
Most of my back-Office projects, usually require people to use Chrome browser, only choose babel-runtime
to meet the needs, because most of Chrome JS new features are supported, such as the includesof string instances, Although Babel-runtime will not compile, the browser will support itself and will not cause problems. For cross-browser projects, however, special consideration is required.
For cross-browser projects, especially when the low version of IE, it is recommended babel-polyfill
that it can be converted to static or instance methods
For the specified browser's project, such as Chrome, which is used directly for babel-runtime
conversion, it does not convert the instance method .
Reference documents
1. Webpack Documents
2. The difference between Polyfill and runtime of Babel
3, Babel principle and the difference between Polyfill and runtime
4, Webpack+babel+transform-runtime, IE prompt promise not defined?
Webpack+babel Project under IE Report promise the thought of undefined error