emberjs / ember-cli-babel

Ember CLI plugin for Babel
MIT License
153 stars 119 forks source link

deprecate is not available from `@ember/debug` pre 4.0.0 #441

Open NullVoxPopuli opened 2 years ago

NullVoxPopuli commented 2 years ago

I was originally going to report this on the embroider repo, as I had thought it was a v2-addon issue. But it is not!

reproduction is super easy:

// app/app.js
import { deprecate } from '@ember/debug';

console.log(deprecate);

Repro repo: https://github.com/NullVoxPopuli/repo-repro-ember-cli-babel-441 just run ember test


This was discovered while trying to add deprecate usage to a v2-addon over in this PR

In the scenarios test suite, it seems that any interaction from a v2 addon with deprecate from @ember/debug causes the test suite to hang.

In a real app / addon ( < ember-source @ v4), a different behavior occurs (and what I was trying to re-create in this change):

ERROR in ../../ember-resources/dist/deprecated-in-v4/use.js
Module build failed (from ../../node_modules/.pnpm/babel-loader@8.2.3_9351ded4f79a023849d74b5df047d562/node_modules/babel-loader/lib/index.js):
SyntaxError: /✂️/ember-resources/ember-resources/dist/deprecated-in-v4/use.js: @ember/debug does not have a deprecate export
  1 | import { getValue } from '@glimmer/tracking/primitives/cache';
> 2 | import { deprecate, assert } from '@ember/debug';
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  3 | import { invokeHelper } from '@ember/helper';
  4 | import { normalizeThunk } from './utils.js';
  5 |
    at File.buildCodeFrameError (/✂️/ember-resources/node_modules/.pnpm/@babel+core@7.17.5_supports-color@8.1.1/node_modules/@babel/core/lib/transformation/file/file.js:249:12)
    at NodePath.buildCodeFrameError (/✂️/ember-resources/node_modules/.pnpm/@babel+traverse@7.17.3_supports-color@8.1.1/node_modules/@babel/traverse/lib/path/index.js:143:21)
    at /✂️/ember-resources/node_modules/.pnpm/babel-plugin-ember-modules-api-polyfill@3.5.0/node_modules/babel-plugin-ember-modules-api-polyfill/src/index.js:228:20
    at Array.forEach (<anonymous>)
    at processImportDeclaration (/✂️/ember-resources/node_modules/.pnpm/babel-plugin-ember-modules-api-polyfill@3.5.0/node_modules/babel-plugin-ember-modules-api-polyfill/src/index.js:188:16)
    at PluginPass.ImportDeclaration (/✂️/ember-resources/node_modules/.pnpm/babel-plugin-ember-modules-api-polyfill@3.5.0/node_modules/babel-plugin-ember-modules-api-polyfill/src/index.js:321:9)
    at newFn (/✂️/ember-resources/node_modules/.pnpm/@babel+traverse@7.17.3_supports-color@8.1.1/node_modules/@babel/traverse/lib/visitors.js:177:21)
    at NodePath._call (/✂️/ember-resources/node_modules/.pnpm/@babel+traverse@7.17.3_supports-color@8.1.1/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (/✂️/ember-resources/node_modules/.pnpm/@babel+traverse@7.17.3_supports-color@8.1.1/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (/✂️/ember-resources/node_modules/.pnpm/@babel+traverse@7.17.3_supports-color@8.1.1/node_modules/@babel/traverse/lib/path/context.js:100:31)
 @ ../../ember-resources/dist/index.js 1:263-306 1:263-306
 @ ../../../../../../../tmp/broccoli-2446401zQEKH5Rl0yks/cache-323-webpack_bundler_ember_auto_import_webpack/tests.js 15:49-75}

According to the docs for @ember/debug, deprecate exists, so the above code should work (I don't yet know why -- first step is a failing test reproduction, but ran in to the test suite hanging issue.)

For ember-source@4.0+, the above issue is not present -- and judging by how (I happen to know that) pre 3.27, all ember apis were on the Ember global and that embroider has no compat-adapter for @ember/debug, my hunch is that this is actually ember-cli-bable related -- but I wanted to open a test here, since embroider has a much better "e2e"-style test suite than ember-cli-babel does.

Also, the stack trace shows babel-plugin-ember-modules-api-polyfill, which is managed by ember-cli-babel.

however in writing this commit message / PR description_, I've found that this behavior exists on a vanilla 3.25 app (new as of now). So since the reproduction is not at all embroider or v2 addon related, I'm going to post on ember-cli-babel

NullVoxPopuli commented 2 years ago

In trying to fix this, I wound up at: https://github.com/ember-cli/ember-rfc176-data/pull/431

NullVoxPopuli commented 2 years ago

So, starting analysis over, as changes to ember-rfc176-data did not fix my issue.

The output of ember build (development): shows this:

;define("my-app-test-deprecate/app", ["exports", "ember-resolver", "ember-load-initializers", "my-app-test-deprecate/config/environment"], function (_exports, _emberResolver, _emberLoadInitializers, _environment) {
  "use strict";

  Object.defineProperty(_exports, "__esModule", {
    value: true
  });
  _exports.default = void 0;

  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; }

  console.log(deprecate);

  class App extends Ember.Application {
    constructor() {
      super(...arguments);

      _defineProperty(this, "modulePrefix", _environment.default.modulePrefix);

      _defineProperty(this, "podModulePrefix", _environment.default.podModulePrefix);

      _defineProperty(this, "Resolver", _emberResolver.default);
    }

  }

  _exports.default = App;
  (0, _emberLoadInitializers.default)(App, _environment.default.modulePrefix);
});

which aligns with the current error I'm getting in the stand-alone app / reproduction:

{"type":"error","text":"Uncaught ReferenceError: deprecate is not defined at http://localhost:7357/assets/my-app-test-deprecate.js, line 28\n","testContext":{}}

reproduction: https://github.com/NullVoxPopuli/repo-repro-ember-cli-babel-441

NullVoxPopuli commented 2 years ago

Changing the "reproduction code" to:

import { assert, deprecate } from '@ember/debug';

console.log(deprecate, assert);

gives this output:

;define("my-app-test-deprecate/app", ["exports", "ember-resolver", "ember-load-initializers", "my-app-test-deprecate/config/environment"], function (_exports, _emberResolver, _emberLoadInitializers, _environment) {
  "use strict";

  Object.defineProperty(_exports, "__esModule", {
    value: true
  });
  _exports.default = void 0;

  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; }

  console.log(deprecate, assert);

  class App extends Ember.Application {
    constructor() {
      super(...arguments);

      _defineProperty(this, "modulePrefix", _environment.default.modulePrefix);

      _defineProperty(this, "podModulePrefix", _environment.default.podModulePrefix);

      _defineProperty(this, "Resolver", _emberResolver.default);
    }

  }

  _exports.default = App;
  (0, _emberLoadInitializers.default)(App, _environment.default.modulePrefix);
});

which is weird, cause now assert isn't defined either....

So it seems everything from @ember/debug is failing? :thinking:

NullVoxPopuli commented 2 years ago

I put some breakpoints into ember-cli-babel and see this in the config sent to babel: image

image

So next step is to see what these plugins are doing

NullVoxPopuli commented 2 years ago

As an aside, having these "watches" in ember-cli-babel's index.js is super helpful: image

I can skip the things that are being compiled that aren't my app (or whatever other code I'm trying to look at being compiled)

NullVoxPopuli commented 2 years ago

ah-ha! There is no externalized helpers config! image

Let's see if adding that fixes the issue

NullVoxPopuli commented 2 years ago

oh but wait! It's supposed to be added here: image

NullVoxPopuli commented 2 years ago

hmm image

NullVoxPopuli commented 2 years ago

So, this leads me to believe that ember-cli-babel is setting things up correctly, and we need to go deeper.

next up: babel plugins!

NullVoxPopuli commented 2 years ago

goofy thing (maybe correct thing?) with debugging this is that all the dependencies of my linked ember-cli-babel package are relative to that linked package. so I made the mistake of putting breakpoints in my app's babel plugins, but those babel plugins are not in use!

NullVoxPopuli commented 2 years ago

looks like babel-plugin-debug-macros's goal is to remove imports. :thinking: so the deprecate => Ember.deprecate (which isn't happening) must be in the modules polyfill plugin

NullVoxPopuli commented 2 years ago

ah-ha!

the modules polyfill is ignoring assert, deprecate, warn, etc!

booo!

image

NullVoxPopuli commented 2 years ago

this could make sense, if the debug-macros plugin was handling the deprecate -> Ember.deprecate conversion, but I don't think it does.

NullVoxPopuli commented 2 years ago

Confirm!

if I comment out lines 219, 220, and 221, then deprecate gets converted to Ember.deprecate.

Progress!

NullVoxPopuli commented 2 years ago

but this code was added in 2020.... why am I running in to this now?

I need to investigate how ignore got built (it's passed in as "options")

NullVoxPopuli commented 2 years ago

ah, back in ember-cli-babel:

  // 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 (!useModulesVersion) {
    const ignore = _getEmberModulesAPIIgnore(parent, project);

    return [
      [require.resolve("babel-plugin-ember-modules-api-polyfill"), { ignore }],
    ];
  }

but this was also added in 2020

NullVoxPopuli commented 2 years ago

This is the PR that introduced these changes (or changed them): https://github.com/babel/ember-cli-babel/pull/371

NullVoxPopuli commented 2 years ago

but, why am I running in to this now?

NullVoxPopuli commented 2 years ago

removing ignore isn't the solution, even though it solves the problem for my repro-repo. when webpack gets involved, we get a related, but different error:

ERROR in ../../ember-resources/dist/deprecated-in-v4/use.js
Module build failed (from ../../node_modules/.pnpm/babel-loader@8.2.3_9351ded4f79a023849d74b5df047d562/node_modules/babel-loader/lib/index.js):
SyntaxError: <repo>/ember-resources/dist/deprecated-in-v4/use.js: @ember/debug does not have a deprecate export
  1 | import { getValue } from '@glimmer/tracking/primitives/cache';
> 2 | import { deprecate, assert } from '@ember/debug';
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  3 | import { invokeHelper } from '@ember/helper';
  4 | import { normalizeThunk } from './utils.js';
  5 |
    at File.buildCodeFrameError (<repo>/node_modules/.pnpm/@babel+core@7.17.5_supports-color@8.1.1/node_modules/@babel/core/lib/transformation/file/file.js:249:12)
    at NodePath.buildCodeFrameError (<repo>/node_modules/.pnpm/@babel+traverse@7.17.3_supports-color@8.1.1/node_modules/@babel/traverse/lib/path/index.js:143:21)
    at <repo>/node_modules/.pnpm/babel-plugin-ember-modules-api-polyfill@3.5.0/node_modules/babel-plugin-ember-modules-api-polyfill/src/index.js:228:20
    at Array.forEach (<anonymous>)
    at processImportDeclaration (<repo>/node_modules/.pnpm/babel-plugin-ember-modules-api-polyfill@3.5.0/node_modules/babel-plugin-ember-modules-api-polyfill/src/index.js:188:16)
    at PluginPass.ImportDeclaration (<repo>/node_modules/.pnpm/babel-plugin-ember-modules-api-polyfill@3.5.0/node_modules/babel-plugin-ember-modules-api-polyfill/src/index.js:321:9)
    at newFn (<repo>/node_modules/.pnpm/@babel+traverse@7.17.3_supports-color@8.1.1/node_modules/@babel/traverse/lib/visitors.js:177:21)
    at NodePath._call (<repo>/node_modules/.pnpm/@babel+traverse@7.17.3_supports-color@8.1.1/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (<repo>/node_modules/.pnpm/@babel+traverse@7.17.3_supports-color@8.1.1/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (<repo>/node_modules/.pnpm/@babel+traverse@7.17.3_supports-color@8.1.1/node_modules/@babel/traverse/lib/path/context.js:100:31)
 @ ../../ember-resources/dist/index.js 1:263-306 1:263-306
 @ ../../../../../../../tmp/broccoli-2686183H6GjySmSkr3O/cache-323-webpack_bundler_ember_auto_import_webpack/tests.js 15:49-75}

still points at babel-plugin-ember-modules-api-polyfill :thinking:

NullVoxPopuli commented 2 years ago

bah, I need a break from this :sweat_smile: babel stuff is dizzying

christianarty commented 1 year ago

For whomever finds this useful thread, this has been fixed in this dependency: https://github.com/ember-cli/ember-rfc176-data/blob/master/CHANGELOG.md#bug-bug-fix

Dependencies that depend on ember-rfc176-data will need to bump to ^0.3.18 to resolve this issue. Thanks @NullVoxPopuli !