From ddf640aa0de9e5af3f001d1d4ae149609c660ab3 Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Mon, 21 Jan 2019 01:23:43 +0700 Subject: [PATCH] polyfill `queueMicrotask` on Node 11 because of ExperimentalWarning, https://github.com/nodejs/node/issues/25592 --- packages/core-js-compat/src/data.js | 4 ++- .../core-js-pure/override/internals/export.js | 33 ++++++++++++------- packages/core-js/internals/export.js | 31 +++++++++-------- packages/core-js/internals/microtask.js | 11 ++++--- packages/core-js/internals/redefine.js | 3 +- .../core-js/modules/web.queue-microtask.js | 2 +- 6 files changed, 52 insertions(+), 32 deletions(-) diff --git a/packages/core-js-compat/src/data.js b/packages/core-js-compat/src/data.js index 1f9e5b514057..9c84055227f4 100644 --- a/packages/core-js-compat/src/data.js +++ b/packages/core-js-compat/src/data.js @@ -1338,7 +1338,9 @@ module.exports = { }, 'web.queue-microtask': { chrome: '71', - node: '11.0', + // Node.js 11 shows ExperimentalWarning on getting `queueMicrotask` + // Waition for https://github.com/nodejs/node/pull/25594 + // node: '11.0', }, 'web.timers': { ie: '10', diff --git a/packages/core-js-pure/override/internals/export.js b/packages/core-js-pure/override/internals/export.js index 1f578242245f..6ea16824ac00 100644 --- a/packages/core-js-pure/override/internals/export.js +++ b/packages/core-js-pure/override/internals/export.js @@ -1,5 +1,6 @@ 'use strict'; var global = require('../internals/global'); +var getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f; var isForced = require('../internals/is-forced'); var path = require('../internals/path'); var bind = require('../internals/bind-context'); @@ -21,16 +22,18 @@ var wrapConstructor = function (NativeConstructor) { }; /* - options.target - name of the target object - options.global - target is the global object - options.stat - export as static methods of target - options.proto - export as prototype methods of target - options.real - real prototype method for the `pure` version - options.forced - export even if the native feature is available - options.bind - bind methods to the target, required for the `pure` version - options.wrap - wrap constructors to preventing global pollution, required for the `pure` version - options.unsafe - use the simple assignment of property instead of delete + defineProperty - options.sham - add a flag to not completely full polyfills + options.target - name of the target object + options.global - target is the global object + options.stat - export as static methods of target + options.proto - export as prototype methods of target + options.real - real prototype method for the `pure` version + options.forced - export even if the native feature is available + options.bind - bind methods to the target, required for the `pure` version + options.wrap - wrap constructors to preventing global pollution, required for the `pure` version + options.unsafe - use the simple assignment of property instead of delete + defineProperty + options.sham - add a flag to not completely full polyfills + options.enumerable - export as enumerable property + options.noTargetGet - prevent calling a getter on target */ module.exports = function (options, source) { var TARGET = options.target; @@ -43,7 +46,8 @@ module.exports = function (options, source) { var target = GLOBAL ? path : path[TARGET] || (path[TARGET] = {}); var targetPrototype = target.prototype; - var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE, key, sourceProperty, targetProperty, resultProperty; + var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE; + var key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor; for (key in source) { FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); @@ -52,8 +56,13 @@ module.exports = function (options, source) { targetProperty = target[key]; + if (USE_NATIVE) if (options.noTargetGet) { + descriptor = getOwnPropertyDescriptor(nativeSource, key); + nativeProperty = descriptor && descriptor.value; + } else nativeProperty = nativeSource[key]; + // export native or implementation - sourceProperty = USE_NATIVE ? nativeSource[key] : source[key]; + sourceProperty = (USE_NATIVE && nativeProperty) ? nativeProperty : source[key]; if (USE_NATIVE && typeof targetProperty === typeof sourceProperty) continue; diff --git a/packages/core-js/internals/export.js b/packages/core-js/internals/export.js index 74d7b90e3458..324e804133f5 100644 --- a/packages/core-js/internals/export.js +++ b/packages/core-js/internals/export.js @@ -1,4 +1,5 @@ var global = require('../internals/global'); +var getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f; var hide = require('../internals/hide'); var redefine = require('../internals/redefine'); var setGlobal = require('../internals/set-global'); @@ -6,23 +7,24 @@ var copyConstructorProperties = require('../internals/copy-constructor-propertie var isForced = require('../internals/is-forced'); /* - options.target - name of the target object - options.global - target is the global object - options.stat - export as static methods of target - options.proto - export as prototype methods of target - options.real - real prototype method for the `pure` version - options.forced - export even if the native feature is available - options.bind - bind methods to the target, required for the `pure` version - options.wrap - wrap constructors to preventing global pollution, required for the `pure` version - options.unsafe - use the simple assignment of property instead of delete + defineProperty - options.sham - add a flag to not completely full polyfills - options.enumerable - export as enumerable property + options.target - name of the target object + options.global - target is the global object + options.stat - export as static methods of target + options.proto - export as prototype methods of target + options.real - real prototype method for the `pure` version + options.forced - export even if the native feature is available + options.bind - bind methods to the target, required for the `pure` version + options.wrap - wrap constructors to preventing global pollution, required for the `pure` version + options.unsafe - use the simple assignment of property instead of delete + defineProperty + options.sham - add a flag to not completely full polyfills + options.enumerable - export as enumerable property + options.noTargetGet - prevent calling a getter on target */ module.exports = function (options, source) { var TARGET = options.target; var GLOBAL = options.global; var STATIC = options.stat; - var FORCED, target, key, targetProperty, sourceProperty; + var FORCED, target, key, targetProperty, sourceProperty, descriptor; if (GLOBAL) { target = global; } else if (STATIC) { @@ -31,8 +33,11 @@ module.exports = function (options, source) { target = (global[TARGET] || {}).prototype; } if (target) for (key in source) { - targetProperty = target[key]; sourceProperty = source[key]; + if (options.noTargetGet) { + descriptor = getOwnPropertyDescriptor(target, key); + targetProperty = descriptor && descriptor.value; + } else targetProperty = target[key]; FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); // contained in target if (!FORCED && targetProperty !== undefined) { diff --git a/packages/core-js/internals/microtask.js b/packages/core-js/internals/microtask.js index b09ef4fc0cae..cea0d275db5a 100644 --- a/packages/core-js/internals/microtask.js +++ b/packages/core-js/internals/microtask.js @@ -1,12 +1,15 @@ var global = require('../internals/global'); +var getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f; var classof = require('../internals/classof-raw'); var macrotask = require('../internals/task').set; var userAgent = require('../internals/user-agent'); var MutationObserver = global.MutationObserver || global.WebKitMutationObserver; var process = global.process; var Promise = global.Promise; -var queueMicrotask = global.queueMicrotask; -var isNode = classof(process) == 'process'; +var IS_NODE = classof(process) == 'process'; +// Node.js 11 shows ExperimentalWarning on getting `queueMicrotask` +var queueMicrotaskDescriptor = getOwnPropertyDescriptor(global, 'queueMicrotask'); +var queueMicrotask = queueMicrotaskDescriptor && queueMicrotaskDescriptor.value; var flush, head, last, notify, toggle, node, promise; @@ -14,7 +17,7 @@ var flush, head, last, notify, toggle, node, promise; if (!queueMicrotask) { flush = function () { var parent, fn; - if (isNode && (parent = process.domain)) parent.exit(); + if (IS_NODE && (parent = process.domain)) parent.exit(); while (head) { fn = head.fn; head = head.next; @@ -30,7 +33,7 @@ if (!queueMicrotask) { }; // Node.js - if (isNode) { + if (IS_NODE) { notify = function () { process.nextTick(flush); }; diff --git a/packages/core-js/internals/redefine.js b/packages/core-js/internals/redefine.js index 5dfae3bc0296..6ac294bd08b0 100644 --- a/packages/core-js/internals/redefine.js +++ b/packages/core-js/internals/redefine.js @@ -15,6 +15,7 @@ require('../internals/shared')('inspectSource', function (it) { (module.exports = function (O, key, value, options) { var unsafe = options ? !!options.unsafe : false; var simple = options ? !!options.enumerable : false; + var noTargetGet = options ? !!options.noTargetGet : false; if (typeof value == 'function') { if (typeof key == 'string' && !has(value, 'name')) hide(value, 'name', key); enforceInternalState(value).source = TEMPLATE.join(typeof key == 'string' ? key : ''); @@ -24,7 +25,7 @@ require('../internals/shared')('inspectSource', function (it) { return; } else if (!unsafe) { delete O[key]; - } else if (O[key]) { + } else if (!noTargetGet && O[key]) { simple = true; } if (simple) O[key] = value; diff --git a/packages/core-js/modules/web.queue-microtask.js b/packages/core-js/modules/web.queue-microtask.js index cb425686b197..08e4e941607b 100644 --- a/packages/core-js/modules/web.queue-microtask.js +++ b/packages/core-js/modules/web.queue-microtask.js @@ -4,7 +4,7 @@ var microtask = require('../internals/microtask'); var process = require('../internals/global').process; var isNode = require('../internals/classof-raw')(process) == 'process'; -require('../internals/export')({ global: true }, { +require('../internals/export')({ global: true, noTargetGet: true }, { queueMicrotask: function queueMicrotask(fn) { var domain = isNode && process.domain; microtask(domain ? domain.bind(fn) : fn);