From e20c0e45dbe5fa7c5f4e9e6bf6d76c140677ca90 Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Wed, 5 May 2021 20:30:50 -0400 Subject: [PATCH] Fix compatibility with Ember 3.27+ when using compileModules: false. When using libraries that leverage `compileModules: false` (commonly used to transpile `vendor` tree's without introducing a wrapping AMD module) on Ember 3.27+ (where we don't transpile away the various `@ember/*` modules any longer) we would leave the debug module imports alone during transpilation. This resulted (in most cases) in there being a bare unwrapped and untranspiled `import` statement in `vendor.js`. This would then fail **everything**. This changes the logic slightly to continue transpiling to globals mode when `compileModules: false` is set. Note: this is really just a stop gap solution (and will still cause deprecations to be emitted, addons that are currently leveraging `compileModules: false` _will_ need to make some changes for Ember 4.0 (where a global `window.Ember` will not be ambiently available). --- lib/babel-options-util.js | 6 ++-- node-tests/addon-test.js | 59 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/lib/babel-options-util.js b/lib/babel-options-util.js index 73f3078a..6123a407 100644 --- a/lib/babel-options-util.js +++ b/lib/babel-options-util.js @@ -85,7 +85,9 @@ function _getDebugMacroPlugins(config, project) { }, }; - if (_emberVersionRequiresModulesAPIPolyfill(project)) { + // we have to use the global form when not compiling modules, because it is often used + // in the context of an `app.import` where there is no wrapped in an AMD module + if (addonOptions.compileModules === false || _emberVersionRequiresModulesAPIPolyfill(project)) { emberDebugOptions.externalizeHelpers = { global: "Ember", }; @@ -420,7 +422,7 @@ function _shouldIncludeDecoratorPlugins(config) { * be deduped as part of `ember-engines`. The reason this is important is because * `ember-engines` dedupe is _stateful_ so it's possible for `ember-cli-typescript` * to not be part of the addons array when `ember-cli-babel` is running. - * + * * For more info on `ember-engines` dedupe logic: * https://github.com/ember-engines/ember-engines/blob/master/packages/ember-engines/lib/utils/deeply-non-duplicated-addon.js#L35 * diff --git a/node-tests/addon-test.js b/node-tests/addon-test.js index 903754bd..2a4a7d5b 100644 --- a/node-tests/addon-test.js +++ b/node-tests/addon-test.js @@ -457,6 +457,65 @@ describe('ember-cli-babel', function() { "foo.js": `define("foo", ["@ember/debug"], function (_debug) {\n "use strict";\n\n (true && !(isNotBad()) && (0, _debug.assert)('stuff here', isNotBad()));\n});`, }); })); + + it("when transpiling with compileModules: false, it should use Ember global even on Ember 3.27+", co.wrap(function* () { + process.env.EMBER_ENV = 'development'; + + dependencies[ + "ember-source" + ] = POST_EMBER_MODULE_IMPORTS_VERSION; + input.write( + buildEmberSourceFixture(POST_EMBER_MODULE_IMPORTS_VERSION) + ); + + input.write({ + app: { + "foo.js": stripIndent` + import { assert } from '@ember/debug'; + assert('stuff here', isNotBad()); + `, + "bar.js": stripIndent` + import { deprecate } from '@ember/debug'; + deprecate( + 'foo bar baz', + false, + { + id: 'some-id', + until: '1.0.0', + } + ); + `, + "baz.js": stripIndent` + import { deprecate } from '@ember/application/deprecations'; + deprecate( + 'foo bar baz', + false, + { + id: 'some-id', + until: '1.0.0', + } + ); + `, + }, + }); + + subject = this.addon.transpileTree(input.path('app'), { + 'ember-cli-babel': { + compileModules: false, + } + }); + output = createBuilder(subject); + + yield output.build(); + + expect( + output.read() + ).to.deep.equal({ + "bar.js": `(true && !(false) && Ember.deprecate('foo bar baz', false, {\n id: 'some-id',\n until: '1.0.0'\n}));`, + "baz.js": `(true && !(false) && Ember.deprecate('foo bar baz', false, {\n id: 'some-id',\n until: '1.0.0'\n}));`, + "foo.js": `(true && !(isNotBad()) && Ember.assert('stuff here', isNotBad()));`, + }); + })); }); describe('in production', function() {