diff --git a/lib/index.js b/lib/index.js index 580469b2275..6bb6a231626 100644 --- a/lib/index.js +++ b/lib/index.js @@ -415,101 +415,86 @@ module.exports = { } } - let message = - 'Usage of the Ember Global is deprecated. ' + - 'You should import the Ember module or the specific API instead.\n\n' + - 'See https://deprecations.emberjs.com/v3.x/#toc_ember-global for details.\n\n' + - 'Usages of the Ember Global may be caused by an outdated ember-cli-babel dependency. ' + - 'The following steps may help:\n\n'; + let suggestions = 'The following steps may help:\n\n'; - let hasActionableSteps = false; + let hasActionableSuggestions = false; if (projectInfo) { - message += '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`.\n'; - hasActionableSteps = true; + suggestions += '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`.\n'; + hasActionableSuggestions = true; } else if (compatibleTopLevelAddons.length > 0) { // Only show the compatible addons if the project itself is up-to-date, because updating the // project's own dependency on ember-cli-babel to latest may also get these addons to use it // as well. Otherwise, there is an unnecessary copy in the tree and it needs to be deduped. if (isYarnProject === true) { - message += + suggestions += '* Run `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.\n'; } else if (isYarnProject === false) { - message += '* Run `npm dedupe`.\n'; + suggestions += '* Run `npm dedupe`.\n'; } else { - message += + suggestions += '* If using yarn, run `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.\n' + '* If using npm, run `npm dedupe`.\n'; } - hasActionableSteps = true; + hasActionableSuggestions = true; } if (incompatibleTopLevelAddons.length > 0) { - message += '* Upgrade the following addons to the latest version:\n'; + suggestions += '* Upgrade the following addons to the latest version:\n'; for (let addon of incompatibleTopLevelAddons) { - message += ` * ${addon}\n`; + suggestions += ` * ${addon}\n`; } - hasActionableSteps = true; + hasActionableSuggestions = true; } - if (!hasActionableSteps) { + if (!hasActionableSuggestions) { // Only show the dormant addons if there are nothing else to do because they are unlikely to // be the problem. - message += '* Upgrade the following addons to the latest version, if available:\n'; + suggestions += '* Upgrade the following addons to the latest version, if available:\n'; for (let addon of dormantTopLevelAddons) { - message += ` * ${addon}\n`; + suggestions += ` * ${addon}\n`; } } - if (hasActionableSteps && process.env.EMBER_GLOBAL_DEPRECATIONS !== 'all') { - message += - '\n### Important ###\n\n' + - 'In order to avoid repeatedly showing the same deprecation messages, ' + - 'no further deprecation messages will be shown for usages of the Ember Global ' + - 'until ember-cli-babel is upgraded to v7.26.6 or above.\n\n' + - 'To see all instances of this deprecation message at runtime, ' + - 'set the `EMBER_GLOBAL_DEPRECATIONS` environment variable to "all", ' + - 'e.g. `EMBER_GLOBAL_DEPRECATIONS=all ember test`.\n'; - } - - message += + let details = '\n### Details ###\n\n' + 'Prior to v7.26.6, ember-cli-babel sometimes transpiled imports into the equivalent Ember Global API, ' + - 'potentially triggering this deprecation message even when you did not directly reference the Ember Global.\n\n' + + 'potentially triggering this deprecation message indirectly, ' + + 'even when you did not observe these deprecated usages in your code.\n\n' + 'The following outdated versions are found in your project:\n'; let hasDormantAddons = false; let hasCompatibleAddons = false; for (let version of Object.keys(groupedByVersion).sort(semver.compare)) { - message += `\n* ember-cli-babel@${version}, currently used by:\n`; + details += `\n* ember-cli-babel@${version}, currently used by:\n`; for (let parent of Object.keys(groupedByVersion[version]).sort()) { let info = groupedByVersion[version][parent][0]; - message += ` * ${parent}`; + details += ` * ${parent}`; if (info.dormant) { - message += ' (Dormant)\n'; + details += ' (Dormant)\n'; hasDormantAddons = true; } else if (info.compatible) { - message += ' (Compatible)\n'; + details += ' (Compatible)\n'; hasCompatibleAddons = true; } else { - message += '\n'; + details += '\n'; } - message += ` * Depends on ember-cli-babel@${groupedByVersion[version][parent][0].requirement}\n`; + details += ` * Depends on ember-cli-babel@${groupedByVersion[version][parent][0].requirement}\n`; for (let info of groupedByVersion[version][parent]) { let adddedBy = info.path.slice(0, -1); if (adddedBy.length) { - message += ` * Added by ${adddedBy.join(' > ')}\n`; + details += ` * Added by ${adddedBy.join(' > ')}\n`; } if (info.compatible) { @@ -520,40 +505,110 @@ module.exports = { } if (hasDormantAddons) { - message += + details += '\nNote: Addons marked as "Dormant" does not appear to have any JavaScript files. ' + 'Therefore, even if they are using an old version ember-cli-babel, they are ' + 'unlikely to be the cuplrit of this deprecation and can likely be ignored.\n'; } if (hasCompatibleAddons) { - message += `\nNote: Addons marked as "Compatible" are already compatible with ember-cli-babel@7.26.6. `; + details += `\nNote: Addons marked as "Compatible" are already compatible with ember-cli-babel@7.26.6. `; if (projectInfo) { - message += 'Try upgrading your `devDependencies` on `ember-cli-babel` to `^7.26.6`.\n'; + details += 'Try upgrading your `devDependencies` on `ember-cli-babel` to `^7.26.6`.\n'; } else { if (isYarnProject === true) { - message += + details += 'Try running `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.\n'; } else if (isYarnProject === false) { - message += 'Try running `npm dedupe`.\n'; + details += 'Try running `npm dedupe`.\n'; } else { - message += + details += 'If using yarn, try running `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.' + 'If using npm, try running `npm dedupe`.\n'; } } } - if (hasActionableSteps) { - this.ui.writeWarnLine('[DEPRECATION] ' + message); + let globalMessage = + 'Usage of the Ember Global is deprecated. ' + + 'You should import the Ember module or the specific API instead.\n\n' + + 'See https://deprecations.emberjs.com/v3.x/#toc_ember-global for details.\n\n' + + 'Usages of the Ember Global may be caused by an outdated ember-cli-babel dependency. ' + + suggestions; + + if (hasActionableSuggestions && process.env.EMBER_GLOBAL_DEPRECATIONS !== 'all') { + globalMessage += + '\n### Important ###\n\n' + + 'In order to avoid repeatedly showing the same deprecation messages, ' + + 'no further deprecation messages will be shown for usages of the Ember Global ' + + 'until ember-cli-babel is upgraded to v7.26.6 or above.\n\n' + + 'To see all instances of this deprecation message, ' + + 'set the `EMBER_GLOBAL_DEPRECATIONS` environment variable to "all", ' + + 'e.g. `EMBER_GLOBAL_DEPRECATIONS=all ember test`.\n'; + } + + globalMessage += details; + + if (hasActionableSuggestions) { + this.ui.writeWarnLine('[DEPRECATION] ' + globalMessage); } + let onDotAccess = `(dotKey, importKey, module) => { + let message = + \`Using \\\`\${dotKey}\\\` has been deprecated. Instead, import the value directly from \${module}:\\n\\n\` + + \` import { \${importKey} } from '\${module}';\\n\\n\` + + 'These usages may be caused by an outdated ember-cli-babel dependency. ' + + ${JSON.stringify(suggestions)}; + + if (${ + hasActionableSuggestions && + process.env.EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS !== 'all' + }) { + message += + '\\n### Important ###\\n\\n' + + 'In order to avoid repeatedly showing the same deprecation messages, ' + + 'no further deprecation messages will be shown for theses deprecated usages ' + + 'until ember-cli-babel is upgraded to v7.26.6 or above.\\n\\n' + + 'To see all instances of this deprecation message, ' + + 'set the \`EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS\` environment variable to "all", ' + + 'e.g. \`EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS=all ember test\`.\\n'; + } + + message += ${JSON.stringify(details)}; + + return message; + }`; + this._bootstrapEmber = ` require('@ember/-internals/bootstrap').default( - ${JSON.stringify(message)}, - ${hasActionableSteps && process.env.EMBER_GLOBAL_DEPRECATIONS !== 'all'} + ${JSON.stringify(globalMessage)}, + ${hasActionableSuggestions && process.env.EMBER_GLOBAL_DEPRECATIONS !== 'all'} ); + + { + let disabled = false; + + let once = ${ + hasActionableSuggestions && + process.env.EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS !== 'all' + }; + + let _onDotAccess = ${onDotAccess}; + + let onDotAccess = (...args) => { + if (disabled) { + return null; + } else { + disabled = once; + return _onDotAccess(...args); + } + }; + + require('@ember/object')._onDotAccess(onDotAccess); + + require('@ember/runloop')._onDotAccess(onDotAccess); + } `; }, }; diff --git a/packages/@ember/object/index.js b/packages/@ember/object/index.js index f2fe18b27f9..af4dd9d5735 100644 --- a/packages/@ember/object/index.js +++ b/packages/@ember/object/index.js @@ -55,23 +55,31 @@ import { uniq, } from '@ember/object/computed'; +export let _onDotAccess; + // eslint-disable-next-line no-undef if (DEBUG) { + let _callback = (dotKey, importKey, module) => { + return `Using \`${dotKey}\` has been deprecated. Instead, import the value directly from ${module}:\n\n import { ${importKey} } from '${module}';`; + }; + + _onDotAccess = (callback) => { + _callback = callback; + }; + let defineDeprecatedComputedFunc = (key, func) => { Object.defineProperty(computed, key, { get() { - deprecate( - `Using \`computed.${key}\` has been deprecated. Instead, import the value directly from @ember/object/computed:\n\n import { ${key} } from '@ember/object/computed';`, - false, - { - id: 'deprecated-run-loop-and-computed-dot-access', - until: '4.0.0', - for: 'ember-source', - since: { - enabled: '3.27.0', - }, - } - ); + let message = _callback(`computed.${key}`, key, '@ember/object/computed'); + + deprecate(message, message === null, { + id: 'deprecated-run-loop-and-computed-dot-access', + until: '4.0.0', + for: 'ember-source', + since: { + enabled: '3.27.0', + }, + }); return func; }, diff --git a/packages/@ember/runloop/index.js b/packages/@ember/runloop/index.js index d3ae2d1e780..6ce847c96db 100644 --- a/packages/@ember/runloop/index.js +++ b/packages/@ember/runloop/index.js @@ -743,23 +743,31 @@ export function throttle() { export let _deprecatedGlobalGetCurrentRunLoop; +export let _onDotAccess; + // eslint-disable-next-line no-undef if (DEBUG) { + let _callback = (dotKey, importKey, module) => { + return `Using \`${dotKey}\` has been deprecated. Instead, import the value directly from ${module}:\n\n import { ${importKey} } from '${module}';`; + }; + + _onDotAccess = (callback) => { + _callback = callback; + }; + let defineDeprecatedRunloopFunc = (key, func) => { Object.defineProperty(run, key, { get() { - deprecate( - `Using \`run.${key}\` has been deprecated. Instead, import the value directly from @ember/runloop:\n\n import { ${key} } from '@ember/runloop';`, - false, - { - id: 'deprecated-run-loop-and-computed-dot-access', - until: '4.0.0', - for: 'ember-source', - since: { - enabled: '3.27.0', - }, - } - ); + let message = _callback(`run.${key}`, key, '@ember/runloop'); + + deprecate(message, message === null, { + id: 'deprecated-run-loop-and-computed-dot-access', + until: '4.0.0', + for: 'ember-source', + since: { + enabled: '3.27.0', + }, + }); return func; }, @@ -767,18 +775,16 @@ if (DEBUG) { }; _deprecatedGlobalGetCurrentRunLoop = () => { - deprecate( - `Using \`run.currentRunLoop\` has been deprecated. Instead, import the getCurrentRunLoop() directly from @ember/runloop:\n\n import { getCurrentRunLoop } from '@ember/runloop';`, - false, - { - id: 'deprecated-run-loop-and-computed-dot-access', - until: '4.0.0', - for: 'ember-source', - since: { - enabled: '3.27.0', - }, - } - ); + let message = _callback('run.currentRunLoop', 'getCurrentRunLoop', '@ember/runloop'); + + deprecate(message, message === null, { + id: 'deprecated-run-loop-and-computed-dot-access', + until: '4.0.0', + for: 'ember-source', + since: { + enabled: '3.27.0', + }, + }); return _getCurrentRunLoop(); };