Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unfixable deprecation issue [deprecation id: ember-string.add-package] #370

Open
st-h opened this issue Feb 19, 2023 · 18 comments
Open

unfixable deprecation issue [deprecation id: ember-string.add-package] #370

st-h opened this issue Feb 19, 2023 · 18 comments

Comments

@st-h
Copy link

st-h commented Feb 19, 2023

DEPRECATION: Importing from `@ember/string` without having the `@ember/string` package in your project is deprecated. Please add `@ember/string` to your `package.json [deprecation id: ember-string.add-package] This will be removed in ember-source 5.0.0. See https://deprecations.emberjs.com/v4.x/#toc_ember-string-add-package for more details.

After upgrading to ember 4.10, I noticed that I am seeing thousands of this deprecation warnings when my app boots up. I checked and to my surprise I was having "@ember/string": "^3.0.1" within devDependencies in my package.json. A discussion on discord pointed be to @ef4 comment: #235 (comment)
Looks like this is describing a similar issue, where it is unclear which implementation (ember-string vs ember internals) is being used.

Is there anything that can be done other waiting for ember to remove its own implementation, or manually silence deprecation warnings?

Additionally it looks like in this case the deprecation message is quite misleading - however, I guess that is part of ember and not ember-string?

@kategengler
Copy link
Member

@st-h I believe in this case the deprecations are likely coming from an addon that itself needs to have @ember/string added? Do you have a further stacktrace?

@st-h
Copy link
Author

st-h commented Mar 27, 2023

@kategengler thanks for the reply. Yes, I have plenty of stacktraces. Usually more than 1.500 when the app is rendered once. The problem is that they only reference the content of my vendor.js file and I need to go into the js file and try to find out what add-on the source I am looking at might belong to. I have tried a few and they all seem to come from different addons. I am not totally sure about this, but they sometimes could even stem from ember itself.

Here is one:

DEPRECATION: Importing from `@ember/string` without having the `@ember/string` package in your project is deprecated. Please add `@ember/string` to your `package.json [deprecation id: ember-string.add-package] This will be removed in ember-source 5.0.0. See https://deprecations.emberjs.com/v4.x/#toc_ember-string-add-package for more details.
    @http://localhost:4200/assets/vendor.js:16322:17
    raiseOnDeprecation@http://localhost:4200/assets/vendor.js:16225:13
    @http://localhost:4200/assets/vendor.js:16322:17
    invoke@http://localhost:4200/assets/vendor.js:16331:23
    deprecate@http://localhost:4200/assets/vendor.js:16298:28
    deprecateImportFromInternalString@http://localhost:4200/assets/vendor.js:27379:47
    underscore@http://localhost:4200/assets/vendor.js:27352:38
    chooseModuleName@http://localhost:4200/assets/vendor.js:104465:58
    findModuleName@http://localhost:4200/assets/vendor.js:104451:48
    resolveOther@http://localhost:4200/assets/vendor.js:104293:51
    resolve@http://localhost:4200/assets/vendor.js:104350:37
    resolve@http://localhost:4200/assets/vendor.js:1236:43
    resolve@http://localhost:4200/assets/vendor.js:994:28
    resolve@http://localhost:4200/assets/vendor.js:996:40
    factoryFor@http://localhost:4200/assets/vendor.js:709:45
    componentFor@http://localhost:4200/assets/vendor.js:5868:28
    lookupComponentPair@http://localhost:4200/assets/vendor.js:5875:33
    lookupComponent@http://localhost:4200/assets/vendor.js:5998:37
    resolveComponent@http://localhost:4200/assets/vendor.js:29776:49
    pushOp@http://localhost:4200/assets/vendor.js:31649:15
    @http://localhost:4200/assets/vendor.js:31297:9
    compile@http://localhost:4200/assets/vendor.js:29999:11
    compileStatements@http://localhost:4200/assets/vendor.js:31652:24
    maybeCompile@http://localhost:4200/assets/vendor.js:31631:35
    compile@http://localhost:4200/assets/vendor.js:37863:57
    @http://localhost:4200/assets/vendor.js:35038:28
    evaluate@http://localhost:4200/assets/vendor.js:34109:27
    evaluateSyscall@http://localhost:4200/assets/vendor.js:37271:30
    evaluateInner@http://localhost:4200/assets/vendor.js:37242:29
    evaluateOuter@http://localhost:4200/assets/vendor.js:37235:27
    next@http://localhost:4200/assets/vendor.js:38066:37
    _execute@http://localhost:4200/assets/vendor.js:38053:27
    execute@http://localhost:4200/assets/vendor.js:38028:36
    handleException@http://localhost:4200/assets/vendor.js:37380:30
    handleException@http://localhost:4200/assets/vendor.js:37588:46
    throw@http://localhost:4200/assets/vendor.js:37327:33
    evaluate@http://localhost:4200/assets/vendor.js:35148:17
    _execute@http://localhost:4200/assets/vendor.js:37314:24
    runInTrackingTransaction@http://localhost:4200/assets/vendor.js:40125:23
    execute@http://localhost:4200/assets/vendor.js:37288:51
    rerender@http://localhost:4200/assets/vendor.js:37614:17
    @http://localhost:4200/assets/vendor.js:6168:16
    @http://localhost:4200/assets/vendor.js:6461:24
    inTransaction@http://localhost:4200/assets/vendor.js:37147:11
    _renderRoots@http://localhost:4200/assets/vendor.js:6443:36
    _renderRootsTransaction@http://localhost:4200/assets/vendor.js:6487:26
    _revalidate@http://localhost:4200/assets/vendor.js:6519:35
    invoke@http://localhost:4200/assets/vendor.js:41434:20
    flush@http://localhost:4200/assets/vendor.js:41349:19
    flush@http://localhost:4200/assets/vendor.js:41512:26
    _end@http://localhost:4200/assets/vendor.js:41953:39
    end@http://localhost:4200/assets/vendor.js:41744:16
    _runExpiredTimers@http://localhost:4200/assets/vendor.js:42060:17
    _runExpiredTimers@[native code]

When I add this code to my application routes constructor, I can filter out most of them. Then I end up with around 150 stacktraces when initially rendering the app:

    registerDeprecationHandler((message, options, next) => {
      return;
    });

I have no clue why some still remain, though...

@kategengler
Copy link
Member

@st-h You can use ember-cli-deprecation-workflow if you want to silence a deprecation.

On the version ember-source in which we added the deprecation, no code in Ember itself uses the deprecated code.

The stacktrace you posted looks like it is coming from ember-resolver. Can you confirm you are using v10.0.0 of ember-resolver and have added @ember/string to your package.json?

@st-h
Copy link
Author

st-h commented Mar 27, 2023

Ok, probably it would be good to update the docs and remove the registerDeprecationHandler stuff, if that no longer works reliably?

Yes, I can confirm both:

yarn list ember-resolver
└─ [email protected]

yarn list @ember/string
└─ @ember/[email protected]

package.json:

"devDependencies": {
    ...
    "@ember/string": "^3.0.1",
    ...
}

On the version ember-source in which we added the deprecation, no code in Ember itself uses the deprecated code.

If I understand what I read correctly, it seems to happen that both implementations - ember internal and @ember/string - get mixed up and it is not clear when which implementation is being used, which leads to the deprecation warnings being printed.

@kategengler
Copy link
Member

registerDeprecationHandler absolutely works, that is, in fact, how ember-cli-deprecation-workflow is implemented.

I don't believe the implementations ever were mixed up but that when any addon previous brought in @ember/string, it would win over the built-in version.

Even with the correct versions in your app, the deprecations can show up when addons are using those ember string methods without having @ember/string as a dependency. You can investigate with the stack traces to see which addon(s) are causing the deprecations.

@st-h
Copy link
Author

st-h commented Mar 28, 2023

registerDeprecationHandler absolutely works, that is, in fact, how ember-cli-deprecation-workflow is implemented.

Ah, I figured it out. Even when the registerDeprecationHandler is registered via an initializer, there are deprecations that are triggered before registerDeprecationHandler is being called. That's why I am seeing unexpected deprecations.

You can investigate with the stack traces to see which addon(s) are causing the deprecations.

Unfortunately it is not that simple. I checked that multiple times before opening the issues. But let's have a look. This is with ember 4.10.0 and ember data 4.11.3.

This is one of the 5000 deprecations I am facing.
Screenshot 2023-03-28 at 15 23 22
The trace shows normalizeModelNames, which calls Object.dasherize, which looks like it is code from embers internal string implementation. If we look at the implementation of normalizeModelNames, we can clearly see that it is ember data code.

Here is another example involving ember-resolver 10.0.0. All traces originate from ember-resolver code.
Screenshot 2023-03-28 at 15 02 18

If I look at the source, it specifies @ember/string 3.0.1 as a peer dependency, which my app provides:
Screenshot 2023-03-28 at 15 06 16

my package.json:
Screenshot 2023-03-28 at 15 31 24

This is the entry in my yarn.lock:
Screenshot 2023-03-28 at 15 32 04

I played this game over and over with different stack traces and different addons. But when I have been looking at the source of the addon, it has been providing @ember/string 3.0 as it should.

Please show me how to find out which addons are causing the thousands of deprecations by looking at their traces. I must be clearly missing something fundamental here.

@ef4
Copy link
Contributor

ef4 commented Mar 28, 2023

I don't think the addon reliably wins over ember's internal deprecated version.

And the deprecation message is misleading. It doesn't really have any package-awareness. If the addon was reliably winning, adding @ember/string anywhere in the dependencies graph would be enough to silence it everywhere, even in addons that (incorrectly) import from @ember/string without declaring their own (peer)dependency on it. If it's failing anywhere, it's failing everywhere, so these stack traces aren't really saying anything useful about their own callsites.

The way to debug this is to look at all the places in your /dist that are calling define('@ember/string', and what order they happen in.

All of that goes for classic builds. Under embroider, packages that declare a dependency on the addon should reliably get the addon. (EDIT to add: as long as you disable the part of the compat system that is mimicking the bad old behavior, by setting staticAddonTrees to true.)

@kategengler
Copy link
Member

@ef4 I tested a bunch with classic builds when I implemented the deprecation -- having @ember/string with a suitably modern version of ember-cli-babel (that attempts to choose whether to use the addon here) seemed to reliably win, but each addon that used it seemed to have to at least specify it as a peerDependency or dependency for that to work.

@st-h Trying 5.0 via the alpha tag should let us know if the implementations are being mixed or if there are still deprecated uses in your project

@st-h
Copy link
Author

st-h commented Mar 28, 2023

@kategengler unfortunately, that is not an easy thing to do. I started patching a few addons to make them ember 5 compatible, but more and more keep popping up. And as things look, there is no real alternative to removing embers internal implementation of the string package, right? So, all I can do is bear with the massive deprecation warnings until v5 is ready and out - unless there will be a v4 release that removes the duplicate implementation, which will likely solve a few headaches for other people as well.

@kategengler
Copy link
Member

@st-h v4 cannot remove the internal implementation, it would be a breaking change.

I want to be sure that v5 will solve your problem, which, right now, I am not sure it will. I've tried to reproduce this in a clean app (starting with ember-new-output) and I haven't yet been able to do so.

@st-h
Copy link
Author

st-h commented Mar 28, 2023

@kategengler I understand that. However, at this moment in time, given the state the ember ecosystem is in, it is not possible for me to provide that information. First, there is no documentation I am aware of, so I need to encounter every breaking change by trial and error. Then I need to find a way to fix those issues. Then I need to patch all the addons in my app, that are not ember v5 compatible. Then there are addons that simply do not link locally, which makes it very difficult to patch them.

v4 cannot remove the internal implementation, it would be a breaking change.

I think a branch where the duplicated implementation is removed could be a good way forward, if you want to further investigate this. Building ember locally would certainly be easier than to fix all the quirks that exist in often quite popular addons that our app relies on. I am absolutely ok with the deprecations that remain after applying registerDeprecationHandler until v5 is out. But I am happy to help, if I can.

@eugenioenko
Copy link

eugenioenko commented Apr 22, 2023

Any updates on this?

I have a project that started throwing hundred of ember/string deprecation warnings even when ember/string is a dev dependency.
The issue surfaced after upgrading ember-source from ember-source": "^4.9.3" to 4.12.0 (4.11.0 and 4.10.0 same issue)

Here a list of the main project dependencies

"devDependencies": {
 ...
    "@ember/string": "^3.0.1",
    "autoprefixer": "^10.4.13",
    "broccoli-asset-rev": "^3.0.0",
    "ember-auto-import": "^2.6.3",
    "ember-cli": "^4.12.1",
    "ember-cli-app-version": "^6.0.0",
    "ember-cli-babel": "^7.26.11",
    "ember-cli-dependency-checker": "^3.3.1",
     ...
    "ember-cli-htmlbars": "^6.2.0",
    "ember-load-initializers": "^2.1.2",
    "ember-modifier": "^4.1.0",
   ...
    "ember-resolver": "^10.0.0",
    "ember-source": "^4.12.0",
    "webpack": "^5.80.0",
  },

Downgrading ember-source to 4.9.3 fixes the issue.

Following up one of the multiple stack trace errors, I traced one down to ember-resolver in the method chooseModuleName

chooseModuleName(moduleName, parsedName) {
   import { dasherize, classify, underscore } from '@ember/string';
   ...
   chooseModuleName(moduleName, parsedName) {
    let underscoredModuleName = underscore(moduleName);

The weird thing is that ember-resolver is importing @ember/strings as a peer dependency and is correctly using the import from @ember/string syntax. The warning shouldn't trigger, but it does.

@eugenioenko
Copy link

eugenioenko commented Apr 22, 2023

Alright, took some time to create reproduction steps.
Seems like the culprit is ember-cli-fastboot

Here is the repo that reproduces this error
https://github.com/eugenioenko/ember-string-deprecation-warning-with-fastboot

The steps taken to create were: new ember project, upgraded all dependencies, added fastboot.

Only after adding fastboot the issue happens.
After checking the ember-cli-fastboot repo, seems like it doesn't include ember/strings into package.json

@kategengler
Copy link
Member

There's an ordering issue. Right now, the only option is to silence the deprecation with something like ember-cli-deprecation-workflow, but we are working on a fix to make the deprecation solveable.

@boris-petrov
Copy link

Another case of this is in ember-classic-decorator. I haven't found a workaround and I removed ember-classic-decorator from my project as it's completely broken with Ember 5.

@kategengler
Copy link
Member

@boris-petrov I just reproduced this -- the @ember/string deprecation isn't exactly why ember-classic-decorator isn't working under 5.0. Can you please open an issue on ember-classic-decorator for not working on 5.0? I believe it is due to it referencing globals off of Ember that no longer exist in 5.0

@boris-petrov
Copy link

@kategengler yes, I noticed it's not the same. Are you saying that actually the deprecation warnings that are triggered on Ember 4 because of ember-classic-decorator actually won't be a problem and Ember 5 will run file (once the other issue is resolved)? I'll open an issue right now, sure.

@kategengler
Copy link
Member

kategengler commented May 16, 2023

@boris-petrov Yes. The @ember/string deprecation is a weird case. In 4.x there are two copies, one from the addon, one from internal Ember and the the internal Ember one is the one that issues deprecations. The bug right now is that which copy is used is completely random but it should be that the addon always wins. Adding ember-classic-decorator just happens to change that random choice and the deprecations are issue from ember-resolver getting the wrong copy of @ember/string. Going to 5.0, the internal version no longer exists and so the correct version is used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants