Skip to content

Commit 18b46ca

Browse files
rwjblueRobert Jackson
authored andcommitted
[BUGFIX release] Fix Embroider compatibility with ember-source@3.27.2+
Fixes a few things: * Ensures that Embroider has a consistent protocol for ensuring the global is bootstrapped * Allows our override code to be transpiled * Ensures that any bootstrapping tweaks force us out of "prebuilt" mode (allowing that customized bootstrap code to actually run) Refactors the work in #19557 to address some of the recent comments there. (cherry picked from commit 5ad6f79)
1 parent 5db188b commit 18b46ca

File tree

11 files changed

+1537
-367
lines changed

11 files changed

+1537
-367
lines changed

lib/index.js

Lines changed: 20 additions & 301 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const buildStripClassCallcheckPlugin = require('./build-strip-class-callcheck-pl
1010
const injectBabelHelpers = require('./transforms/inject-babel-helpers').injectBabelHelpers;
1111
const debugTree = require('broccoli-debug').buildDebugCallback('ember-source:addon');
1212
const vmBabelPlugins = require('@glimmer/vm-babel-plugins');
13-
const semver = require('semver');
13+
const Overrides = require('./overrides');
1414

1515
const PRE_BUILT_TARGETS = [
1616
'last 1 Chrome versions',
@@ -41,17 +41,6 @@ add(
4141
path.join(__dirname, '..', 'dist', 'ember-template-compiler.js')
4242
);
4343

44-
function* walkAddonTree(project, pathToAddon = []) {
45-
for (let addon of project.addons) {
46-
yield [addon, pathToAddon];
47-
yield* walkAddonTree(addon, [...pathToAddon, `${addon.name}@${addon.pkg.version}`]);
48-
}
49-
}
50-
51-
function requirementFor(pkg, deps = {}) {
52-
return deps[pkg];
53-
}
54-
5544
module.exports = {
5645
init() {
5746
this._super.init && this._super.init.apply(this, arguments);
@@ -76,13 +65,21 @@ module.exports = {
7665
name: 'ember-source',
7766
paths,
7867
absolutePaths,
79-
_bootstrapEmber: "require('@ember/-internals/bootstrap').default();",
8068
_jqueryIntegrationEnabled: true,
69+
_overrideTree: undefined,
8170

8271
included() {
8372
this._super.included.apply(this, arguments);
8473

85-
this._issueGlobalsDeprecation();
74+
let overrides = Overrides.for(this.project);
75+
76+
if (overrides.hasOverrides) {
77+
this._overrideTree = overrides.toTree();
78+
}
79+
80+
if (overrides.hasBuildTimeWarning) {
81+
this.ui.writeWarnLine('[DEPRECATION] ' + overrides.buildTimeWarning);
82+
}
8683

8784
const { has } = require('@ember/edition-utils');
8885

@@ -224,6 +221,10 @@ module.exports = {
224221
},
225222

226223
buildEmberBundles(tree, isProduction) {
224+
if (this._overrideTree) {
225+
tree = new MergeTrees([tree, this._overrideTree], { overwrite: true });
226+
}
227+
227228
let packages = this.transpileTree(new Funnel(tree, { srcDir: 'packages' }), isProduction);
228229

229230
let dependencies = this.transpileTree(
@@ -259,7 +260,7 @@ module.exports = {
259260
return new MergeTrees([
260261
concatBundle(emberFiles, {
261262
outputFile: 'ember.js',
262-
footer: this._bootstrapEmber,
263+
footer: `require('@ember/-internals/bootstrap')`,
263264
}),
264265

265266
concatBundle(emberTestingFiles, {
@@ -304,10 +305,13 @@ module.exports = {
304305

305306
if (
306307
!isProduction &&
308+
// do the running applications targets match our prebuilt assets targets?
307309
PRE_BUILT_TARGETS.every((target) => targets.includes(target)) &&
308310
targets.length === PRE_BUILT_TARGETS.length &&
309311
// if node is defined in targets we can't reliably use the prebuilt bundles
310-
!targetNode
312+
!targetNode &&
313+
// if we have a custom override (e.g. for globals deprecations) we can't use the prebuilt bundles
314+
!this._overrideTree
311315
) {
312316
ember = new Funnel(tree, {
313317
destDir: 'ember',
@@ -324,289 +328,4 @@ module.exports = {
324328

325329
return debugTree(new MergeTrees([ember, templateCompiler, jquery]), 'vendor:final');
326330
},
327-
328-
_issueGlobalsDeprecation() {
329-
if (process.env.EMBER_ENV === 'production') {
330-
return;
331-
}
332-
333-
let isYarnProject = ((root) => {
334-
try {
335-
// eslint-disable-next-line node/no-unpublished-require
336-
return require('ember-cli/lib/utilities/is-yarn-project')(root);
337-
} catch {
338-
return undefined;
339-
}
340-
})(this.project.root);
341-
342-
let groupedByTopLevelAddon = Object.create(null);
343-
let groupedByVersion = Object.create(null);
344-
let projectInfo;
345-
346-
for (let [addon, pathToAddon] of walkAddonTree(this.project)) {
347-
let version = addon.pkg.version;
348-
349-
if (addon.name === 'ember-cli-babel' && semver.lt(version, '7.26.6')) {
350-
let info;
351-
352-
if (addon.parent === this.project) {
353-
let requirement = requirementFor('ember-cli-babel', this.project.pkg.devDependencies);
354-
let compatible = semver.satisfies('7.26.6', requirement);
355-
356-
info = projectInfo = {
357-
parent: `${this.project.name()} (your app)`,
358-
version,
359-
requirement,
360-
compatible,
361-
dormant: false,
362-
path: pathToAddon,
363-
};
364-
} else {
365-
let requirement = requirementFor('ember-cli-babel', addon.parent.pkg.dependencies);
366-
let compatible = semver.satisfies('7.26.6', requirement);
367-
let dormant = addon.parent._fileSystemInfo
368-
? addon.parent._fileSystemInfo().hasJSFiles === false
369-
: false;
370-
371-
let topLevelAddon = addon.parent;
372-
373-
while (topLevelAddon.parent !== this.project) {
374-
topLevelAddon = topLevelAddon.parent;
375-
}
376-
377-
info = {
378-
parent: `${addon.parent.name}@${addon.pkg.version}`,
379-
version,
380-
requirement,
381-
compatible,
382-
dormant,
383-
path: pathToAddon,
384-
};
385-
386-
let addons = groupedByTopLevelAddon[topLevelAddon.name] || [];
387-
groupedByTopLevelAddon[topLevelAddon.name] = [...addons, info];
388-
}
389-
390-
let group = groupedByVersion[version] || Object.create(null);
391-
groupedByVersion[version] = group;
392-
393-
let addons = group[info.parent] || [];
394-
group[info.parent] = [...addons, info];
395-
}
396-
}
397-
398-
if (Object.keys(groupedByVersion).length === 0) {
399-
return;
400-
}
401-
402-
let dormantTopLevelAddons = [];
403-
let compatibleTopLevelAddons = [];
404-
let incompatibleTopLevelAddons = [];
405-
406-
for (let addon of Object.keys(groupedByTopLevelAddon)) {
407-
let group = groupedByTopLevelAddon[addon];
408-
409-
if (group.every((info) => info.dormant)) {
410-
dormantTopLevelAddons.push(addon);
411-
} else if (group.every((info) => info.compatible)) {
412-
compatibleTopLevelAddons.push(addon);
413-
} else {
414-
incompatibleTopLevelAddons.push(addon);
415-
}
416-
}
417-
418-
let suggestions = 'The following steps may help:\n\n';
419-
420-
let hasActionableSuggestions = false;
421-
422-
if (projectInfo) {
423-
suggestions += '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`.\n';
424-
hasActionableSuggestions = true;
425-
} else if (compatibleTopLevelAddons.length > 0) {
426-
// Only show the compatible addons if the project itself is up-to-date, because updating the
427-
// project's own dependency on ember-cli-babel to latest may also get these addons to use it
428-
// as well. Otherwise, there is an unnecessary copy in the tree and it needs to be deduped.
429-
if (isYarnProject === true) {
430-
suggestions +=
431-
'* Run `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.\n';
432-
} else if (isYarnProject === false) {
433-
suggestions += '* Run `npm dedupe`.\n';
434-
} else {
435-
suggestions +=
436-
'* If using yarn, run `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.\n' +
437-
'* If using npm, run `npm dedupe`.\n';
438-
}
439-
440-
hasActionableSuggestions = true;
441-
}
442-
443-
if (incompatibleTopLevelAddons.length > 0) {
444-
suggestions += '* Upgrade the following addons to the latest version:\n';
445-
446-
for (let addon of incompatibleTopLevelAddons) {
447-
suggestions += ` * ${addon}\n`;
448-
}
449-
450-
hasActionableSuggestions = true;
451-
}
452-
453-
if (!hasActionableSuggestions) {
454-
// Only show the dormant addons if there are nothing else to do because they are unlikely to
455-
// be the problem.
456-
suggestions += '* Upgrade the following addons to the latest version, if available:\n';
457-
458-
for (let addon of dormantTopLevelAddons) {
459-
suggestions += ` * ${addon}\n`;
460-
}
461-
}
462-
463-
let details =
464-
'\n### Details ###\n\n' +
465-
'Prior to v7.26.6, ember-cli-babel sometimes transpiled imports into the equivalent Ember Global API, ' +
466-
'potentially triggering this deprecation message indirectly, ' +
467-
'even when you did not observe these deprecated usages in your code.\n\n' +
468-
'The following outdated versions are found in your project:\n';
469-
470-
let hasDormantAddons = false;
471-
let hasCompatibleAddons = false;
472-
473-
for (let version of Object.keys(groupedByVersion).sort(semver.compare)) {
474-
details += `\n* ember-cli-babel@${version}, currently used by:\n`;
475-
476-
for (let parent of Object.keys(groupedByVersion[version]).sort()) {
477-
let info = groupedByVersion[version][parent][0];
478-
479-
details += ` * ${parent}`;
480-
481-
if (info.dormant) {
482-
details += ' (Dormant)\n';
483-
hasDormantAddons = true;
484-
} else if (info.compatible) {
485-
details += ' (Compatible)\n';
486-
hasCompatibleAddons = true;
487-
} else {
488-
details += '\n';
489-
}
490-
491-
details += ` * Depends on ember-cli-babel@${groupedByVersion[version][parent][0].requirement}\n`;
492-
493-
for (let info of groupedByVersion[version][parent]) {
494-
let adddedBy = info.path.slice(0, -1);
495-
496-
if (adddedBy.length) {
497-
details += ` * Added by ${adddedBy.join(' > ')}\n`;
498-
}
499-
500-
if (info.compatible) {
501-
hasCompatibleAddons = true;
502-
}
503-
}
504-
}
505-
}
506-
507-
if (hasDormantAddons) {
508-
details +=
509-
'\nNote: Addons marked as "Dormant" does not appear to have any JavaScript files. ' +
510-
'Therefore, even if they are using an old version ember-cli-babel, they are ' +
511-
'unlikely to be the cuplrit of this deprecation and can likely be ignored.\n';
512-
}
513-
514-
if (hasCompatibleAddons) {
515-
details += `\nNote: Addons marked as "Compatible" are already compatible with ember-cli-babel@7.26.6. `;
516-
517-
if (projectInfo) {
518-
details += 'Try upgrading your `devDependencies` on `ember-cli-babel` to `^7.26.6`.\n';
519-
} else {
520-
if (isYarnProject === true) {
521-
details +=
522-
'Try running `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.\n';
523-
} else if (isYarnProject === false) {
524-
details += 'Try running `npm dedupe`.\n';
525-
} else {
526-
details +=
527-
'If using yarn, try running `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.' +
528-
'If using npm, try running `npm dedupe`.\n';
529-
}
530-
}
531-
}
532-
533-
let globalMessage =
534-
'Usage of the Ember Global is deprecated. ' +
535-
'You should import the Ember module or the specific API instead.\n\n' +
536-
'See https://deprecations.emberjs.com/v3.x/#toc_ember-global for details.\n\n' +
537-
'Usages of the Ember Global may be caused by an outdated ember-cli-babel dependency. ' +
538-
suggestions;
539-
540-
if (hasActionableSuggestions && process.env.EMBER_GLOBAL_DEPRECATIONS !== 'all') {
541-
globalMessage +=
542-
'\n### Important ###\n\n' +
543-
'In order to avoid repeatedly showing the same deprecation messages, ' +
544-
'no further deprecation messages will be shown for usages of the Ember Global ' +
545-
'until ember-cli-babel is upgraded to v7.26.6 or above.\n\n' +
546-
'To see all instances of this deprecation message, ' +
547-
'set the `EMBER_GLOBAL_DEPRECATIONS` environment variable to "all", ' +
548-
'e.g. `EMBER_GLOBAL_DEPRECATIONS=all ember test`.\n';
549-
}
550-
551-
globalMessage += details;
552-
553-
if (hasActionableSuggestions) {
554-
this.ui.writeWarnLine('[DEPRECATION] ' + globalMessage);
555-
}
556-
557-
let onDotAccess = `function (dotKey, importKey, module) {
558-
var message =
559-
'Using \`' + dotKey + '\` has been deprecated. Instead, import the value directly from ' + module + ':\\n\\n' +
560-
' import { ' + importKey + ' } from \\'' + module + '\\';\\n\\n' +
561-
'These usages may be caused by an outdated ember-cli-babel dependency. ' +
562-
${JSON.stringify(suggestions)};
563-
564-
if (${
565-
hasActionableSuggestions &&
566-
process.env.EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS !== 'all'
567-
}) {
568-
message +=
569-
'\\n### Important ###\\n\\n' +
570-
'In order to avoid repeatedly showing the same deprecation messages, ' +
571-
'no further deprecation messages will be shown for theses deprecated usages ' +
572-
'until ember-cli-babel is upgraded to v7.26.6 or above.\\n\\n' +
573-
'To see all instances of this deprecation message, ' +
574-
'set the \`EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS\` environment variable to "all", ' +
575-
'e.g. \`EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS=all ember test\`.\\n';
576-
}
577-
578-
message += ${JSON.stringify(details)};
579-
580-
return message;
581-
}`;
582-
583-
this._bootstrapEmber = `
584-
require('@ember/-internals/bootstrap').default(
585-
${JSON.stringify(globalMessage)},
586-
${hasActionableSuggestions && process.env.EMBER_GLOBAL_DEPRECATIONS !== 'all'}
587-
);
588-
589-
(function(disabled, once, _onDotAccess) {
590-
var onDotAccess = function () {
591-
if (disabled) {
592-
return null;
593-
} else {
594-
disabled = once;
595-
return _onDotAccess.apply(undefined, arguments);
596-
}
597-
};
598-
599-
require('@ember/object')._onDotAccess(onDotAccess);
600-
601-
require('@ember/runloop')._onDotAccess(onDotAccess);
602-
})(
603-
false,
604-
${
605-
hasActionableSuggestions &&
606-
process.env.EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS !== 'all'
607-
},
608-
${onDotAccess}
609-
);
610-
`;
611-
},
612331
};

0 commit comments

Comments
 (0)