Why is X changing to Y in discord.js v14? #7380
Replies: 4 comments 9 replies
{{title}}
{{editor}}'s edit
{{editor}}'s edit
-
The points are quite understandable. It would be good, when the upper things are thought before designing sth. |
Beta Was this translation helpful? Give feedback.
-
I understand the performance implications this has, but I also think this makes using any structure with a type harder, as we now have to check the docs to see what type 20 means, instead of just having a name from which we can easily deduce what it means. For situations where you want to check for a specific structure type this is not an issue of course, as you can simply do Also, I believe the biggest elephant in the room that wasn't addressed here, which is the fact that builders no longer support the camelCase we know and love. I recently refactored my whole bot to use discord.js builders by providing a data object in the constructor instead of executing subsequent functions which I found to be less efficient and logical. This is because, when you create an instance of a builder, you're passing the values you want initially, and you can later change them using the functions, which is a perfectly valid use case. builders didn't initially support camelCase as it was intended to be used with /rest and not discord.js directly (at least what I understood), and thus the data needed to be transformed in an API-friendly way. I believe all builders should support camelCasing (along with snake_case) in the constructor and they should convert those properties later on so that they can be passed to the API in the way that it expects them to be passed. |
Beta Was this translation helpful? Give feedback.
-
interesting |
Beta Was this translation helpful? Give feedback.
{{title}}
{{editor}}'s edit
{{editor}}'s edit
-
Now that the working list of breaking changes for v14 have been made available, there's been a lot concerns focusing on the why of the breaking changes. Some have suggested that they're unneeded and unnecessary. However like most things it's not that simple. I understand that no one likes to refactor their code for breaking change. I develop a bot, and going through and updating symbols in my code isn't what I would consider "enjoyable". I understand the frustration of this process. Nonetheless none of us are making changes just to make the change-log fluffier, there's always a reason, and some reasons are larger than others.
Why are you no longer accepting
string
s for enum values, also where did the old enums go?This can be answered quite plainly: because we don't want to keep handling different cases of input where we don't feel we need to. Enums are structures that constantly change within the discord API, this in turn means discord.js also needs to keep up with those changes.
Did you know that in v13 and lower we were maintaining up three different declarations of enums?
enums.d.ts
discord-api-types
Obviously this wasn't the best for maintainability. Ideally we could have one centralized place, a single source of truth if you will. So we decided that the best way forward was to have our source for enum come from 'discord-api-types'.
Ok, but this doesn't answer the question as to why we can't use
string
s anymore. When it comes to accepting both numbers and strings there's problems that many people may not be aware of.Here's an issue I discovered several months ago:
In typescript negating against a given enum type wouldn't work as expected:
Wait what? Why doesn't this work? I've properly narrowed the
type
?This is a nasty pitfall caused because you forgot to also check if the type wasn't equal to
Constants.ButtonStyle.LINK
. This pitfall occurred in many places and it led to many issues where users were simply confused as to why their types weren't resolving as expected.In addition to the outside effects of supporting both strings and enums there were many internal effects. For example it's extremely easy for a contributor to miss the case where they're supposed to check for a string, or the inverse where they're supposed to check for a number. Once again I'd like to reiterate this is a poor setup in terms of code maintenance. There's another aspect that wasn't covered: performance.
Interactions, messages, channels are constantly being serialized from the gateway events in discord.js. This is especially true for large bots that occupy thousands of servers. Discord.js constantly introduced if branches for checking enum types because of they could either be a
string
ornumber
. Some of our transformers were creating new objects to translate the enums. As you can imagine this has a negative affect on performance. We received an issue ticket about the particular issue, asking if we could make enum transformations optional: #6136.But you're also making builders slower?
Sorry if this wasn't made clearer earlier, but we'll be introducingUnsafe
variants of builders that have the same performance of the previous discord.js builders just without validation.Unsafe builders have landed.
So what about the builder renames?
Contrary to popular belief, the builder renames have more to do with the elimination of future class proliferation, rather than just making another aesthetic change. Let's take the
Message*
components for an example:We have
Alright this is great, I prefixed all my classes with
Message
because they can't be used anywhere else! Right!...Right? Well no, because discord adds a new feature to the API where components can be used in more than one place. If you're not aware what I'm getting at, I'm talking about modals. With modals you can have action rows within them. Ah ok! I know the solution I'll add a new class:ModalActionRow
!. I soon realize that aModalActionRow
nearly identical to aMessageAction
row. As a result I've added redundant code to the codebase just because my naming model isn't flexible. Discord has also confirmed that select menus will be available in modals, so even more redundant proliferation of classes.How would one avoid this situation? The answer is simple: make the naming conventions more agnostic. That's exactly what we did. Instead of having six different classes that support both modals and messages, we can instead have 4 agnostic classes that work or can work in both styles if needed. Basically use the agnostic classes in more areas rather than introduce new classes for each area.
Conclusion
This is all I have so far, and I'll most likely add more as time moves on. If anyone has any questions or concerns about the breaking changes please leave a reply in this discussion and we can discuss it.
Beta Was this translation helpful? Give feedback.
All reactions