babel-polyfill 使用場景javascript
Babel 默認只轉換新的 JavaScript 語法,而不轉換新的 API。例如,Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局對象,以及一些定義在全局對象上的方法(好比 Object.assign)都不會轉譯。若是想使用這些新的對象和方法,必須使用 babel-polyfill,爲當前環境提供一個墊片。java
babel-runtime 使用場景json
Babel 轉譯後的代碼要實現源代碼一樣的功能須要藉助一些幫助函數,例如,{ [name]: 'JavaScript' }
轉譯後的代碼以下所示:babel
'use strict'; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var obj = _defineProperty({}, 'name', 'JavaScript');
相似上面的幫助函數 _defineProperty 可能會重複出如今一些模塊裏,致使編譯後的代碼體積變大。Babel 爲了解決這個問題,提供了單獨的包 babel-runtime
供編譯模塊複用工具函數。函數
啓用插件 babel-plugin-transform-runtime
後,Babel 就會使用 babel-runtime
下的工具函數,轉譯代碼以下:工具
'use strict'; // 以前的 _defineProperty 函數已經做爲公共模塊 `babel-runtime/helpers/defineProperty` 使用 var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var obj = (0, _defineProperty3.default)({}, 'name', 'JavaScript');
除此以外,babel 還爲源代碼的非實例方法(Object.assign
,實例方法是相似這樣的 "foobar".includes("foo")
)和 babel-runtime/helps 下的工具函數自動引用了 polyfill。這樣能夠避免污染全局命名空間,很是適合於 JavaScript 庫和工具包的實現。例如 const obj = {}, Object.assign(obj, { age: 30 });
轉譯後的代碼以下所示:ui
'use strict'; // 使用了 core-js 提供的 assign var _assign = require('babel-runtime/core-js/object/assign'); var _assign2 = _interopRequireDefault(_assign); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var obj = {}; (0, _assign2.default)(obj, { age: 30 });
思考:babel-runtime 爲何適合 JavaScript 庫和工具包的實現?es5
避免 babel 編譯的工具函數在每一個模塊裏重複出現,減少庫和工具包的體積;spa
在沒有使用 babel-runtime 以前,庫和工具包通常不會直接引入 polyfill。不然像 Promise 這樣的全局對象會污染全局命名空間,這就要求庫的使用者本身提供 polyfill。這些 polyfill 通常在庫和工具的使用說明中會提到,好比不少庫都會有要求提供 es5 的 polyfill。在使用 babel-runtime 後,庫和工具只要在 package.json 中增長依賴 babel-runtime,交給 babel-runtime 去引入 polyfill 就好了;插件
總結:
具體項目仍是須要使用 babel-polyfill,只使用 babel-runtime 的話,實例方法不能正常工做(例如 "foobar".includes("foo")
);
JavaScript 庫和工具可使用 babel-runtime,在實際項目中使用這些庫和工具,須要該項目自己提供 polyfill;