react org es6 javascript ecmascript-6 webpack babeljs

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

https://www.npmjs.com/package/object-assign


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.