javascript - es6 - webpack org js
¿Por qué Object.assign() requiere un polyfill cuando se usa babel-loader? (4)
Estoy intentando usar
Object.assign()
en una aplicación web ES6 compilada por Babel con webpack, pero recibo un error:
Uncaught TypeError: Object.assign is not a function
Ya estoy usando
babel-loader
para transpilar ES6 a ES5, por lo que todo mi otro código ES6 está funcionando.
Sin embargo,
Object.assign()
solo funciona después de
import "babel-core/polyfill"
también
import "babel-core/polyfill"
en mi base de código.
Veo que también puedo solucionar esto
importando babel-runtime
, pero me gustaría entender
por qué
Object.assign()
requiere más de lo que realiza
babel-loader
; no debería preprocesar todo el
babel-loader
, incluido
Object.assign()
?
Babel, a través de
babel-loader
, transpila las diferencias en la
sintaxis de
ES6.
Babel por sí solo no hace absolutamente nada para agregar en la funcionalidad de la biblioteca estándar ES6 (como
Object.assign
).
Cargar el polyfill carga un polyfill
core-js
separado para usted, pero puede cargar cualquier polyfill que desee.
Incluso algunas conversiones de sintaxis dependen de la funcionalidad específica de polyfill para ser cargas, ya que algunas sintaxis dependen de algoritmos y comportamientos implementados en el código de la biblioteca. Las características de ES6 en http://babeljs.io/docs/learn-es2015/ enumeran cada funcionalidad de biblioteca estándar que se supone que se ha cargado.
Me enfrenté al mismo problema. Pensé que era seguro usar todas las características de ES2015 + cuando estaba respaldado por babel. Pero como se mencionó anteriormente, babel polyfills solo sintaxis, no funciones (Object.assign, Array.incluye solo por nombrar algunos). Para Object.assign, prefiero no usar polyfill, sino usar el operador spread. En este caso, babel realmente polyfills Object.assign si no se encuentra. Echa un vistazo a este código:
let obj = {a: 1};
let obj2 = {...obj};
let obj3 = Object.assign({}, obj);
Babel lo transportará a:
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var obj = { a: 1 };
var obj2 = _extends({}, obj);
var obj3 = Object.assign({}, obj);
Para el operador de propagación, babel intenta usar el método Object.assign nativo y usar polyfill si no se encuentra. Pero el método Object.assign explícito no se modifica ¯ / _ (ツ) _ / ¯
Si baja a Compatibilidad, puede ver que IE 11 no es compatible tanto en Web como en Mobile para object.assign. También te da el pollyfill para eso.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
if (typeof Object.assign != ''function'') {
Object.assign = function(target, varArgs) {
''use strict'';
if (target == null) { // TypeError if undefined or null
throw new TypeError(''Cannot convert undefined or null to object'');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
};
}
Si usa Babel
https://babeljs.io/docs/plugins/transform-object-assign/
Si usa NPM
Object.assign()
es una nueva API que forma parte de la especificación ES6, por lo que aún no está implementada en la mayoría de los navegadores.
Ver:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Entonces, cuando importa
babel-core/polyfill
, agrega polyfills a esta y otras API nuevas, para que su código ES6 pueda usarlas.
babel-loader
es solo el transpiler que convierte la sintaxis de ES6 en código compatible con ES5.