Bundler Updates: Difference between revisions

From Discord Client Modding Wiki
Jump to navigation Jump to search
(SWC was not a new bundler)
mNo edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
__NOTOC__
Discord uses a bundler to compress individual files into bigger, singular files known as chunks. This article documents major and minor changes to the bundler or its config over the years that have caused client mods to break.
Discord uses a bundler to compress individual files into bigger, singular files known as chunks. This article documents major and minor changes to the bundler or its config over the years that have caused client mods to break.


== Unique CSS class names ==
== Unique CSS class names ==
In 2017 or 2018, Discord introduced a bundler plugin that made CSS class names unique by adding a random 6-character string at the end of the class.
Starting on June 1, 2017, Discord introduced a bundler plugin that made CSS class names unique by adding a 6-character hash string at the end of the class. The change was gradual and impacted only the guild channels wrapper at first, but over a short period of time hashed class names became used throughout the entire client.


== 1000 character line splitting ==
== 1000 character line splitting ==
Line 17: Line 16:
On September 26, 2022, Discord switched from Babel to [https://swc.rs/ SWC]. This is considered the great cataclysmic event that killed off almost every client mod.
On September 26, 2022, Discord switched from Babel to [https://swc.rs/ SWC]. This is considered the great cataclysmic event that killed off almost every client mod.


React component display names were removed, making it harder for mods to find components.
React component display names were removed, making it harder for mods to find components. There were plans for Discord to find a way to keep display names for debugging purposes<ref>{{cite web|title=Ability to add displayName to all React components to prevent names from getting mangled|url=https://github.com/swc-project/swc/issues/5958}}</ref>, but they opted not to bother<ref>{{cite web|title="We might just stick with not having displayNames"|url=https://github.com/swc-project/swc/issues/5958#issuecomment-1258764673}}</ref>.
There were plans for Discord to find a way to keep display names for debugging purposes<ref>{{cite web|title=Ability to add displayName to all React components to prevent names from getting mangled|url=https://github.com/swc-project/swc/issues/5958}}</ref>, but they opted not to bother<ref>{{cite web|title="We might just stick with not having displayNames"|url=https://github.com/swc-project/swc/issues/5958#issuecomment-1258764673}}</ref>.


Module export names were mangled. Finding specific functions without searching for the function's code was even harder. There were specific patterns, such as <code>default</code> becoming <code>Z</code> or <code>ZP</code>.
Module export names were mangled. Finding specific functions without searching for the function's code was even harder. There were specific patterns, such as <code>default</code> becoming <code>Z</code> or <code>ZP</code>.
Line 27: Line 25:
Module export names return. This caused parts of mods broken by SWC to work in some capacity, excluding React component display names.
Module export names return. This caused parts of mods broken by SWC to work in some capacity, excluding React component display names.


Every theme was now broken as Rspack's unique class name plugin uses <code>_</code> or <code>__</code> as the separator between the name and the random string.
Every theme was now broken as Rspack's unique class name plugin uses <code>_</code> or <code>__</code> as the separator between the name and the random string. In addition, every stylesheet was loaded in the body instead of the head, forcing client mods to put their stylesheets in <code>document.documentElement</code> for the highest priority.
In addition, every stylesheet was loaded in the body instead of the head, forcing client mods to put their stylesheets in <code>document.documentElement</code> for the highest priority.


More than 100 chunk files are initially loaded instead of 4.
More than 100 chunk files are initially loaded instead of 4.

Latest revision as of 22:17, 23 March 2024

Discord uses a bundler to compress individual files into bigger, singular files known as chunks. This article documents major and minor changes to the bundler or its config over the years that have caused client mods to break.

Unique CSS class names

Starting on June 1, 2017, Discord introduced a bundler plugin that made CSS class names unique by adding a 6-character hash string at the end of the class. The change was gradual and impacted only the guild channels wrapper at first, but over a short period of time hashed class names became used throughout the entire client.

1000 character line splitting

On July 29, 2021, Discord added a Babel rule to split every line of code into 1000 characters within the limits of syntax. At the time, no public client mods broke because none searched modules by code or used module patching.

Webpack 5

On October 21, 2021, Discord updated from Webpack 4 to 5. This introduced lazy-loaded chunks and WebAssembly support.

The Webpack global was renamed from webpackJsonp to webpackChunkdiscord_app. Entrypoint modules were changed from an array of module IDs to a function with Webpack's require function as the only argument.

SWC

On September 26, 2022, Discord switched from Babel to SWC. This is considered the great cataclysmic event that killed off almost every client mod.

React component display names were removed, making it harder for mods to find components. There were plans for Discord to find a way to keep display names for debugging purposes[1], but they opted not to bother[2].

Module export names were mangled. Finding specific functions without searching for the function's code was even harder. There were specific patterns, such as default becoming Z or ZP.

Rspack

On October 26, 2023, Discord switched from Webpack to Rspack. While not as cataclysmic, it wasn't without issues.

Module export names return. This caused parts of mods broken by SWC to work in some capacity, excluding React component display names.

Every theme was now broken as Rspack's unique class name plugin uses _ or __ as the separator between the name and the random string. In addition, every stylesheet was loaded in the body instead of the head, forcing client mods to put their stylesheets in document.documentElement for the highest priority.

More than 100 chunk files are initially loaded instead of 4.

Sentry's chunk would overwrite the module storage, causing two instances of modules to exist but only one to be accessible.

The chunk loader chunk loads later than expected, forcing mods that use module patching to disregard further calls to binding webpackChunkdiscord_app.push.

Accidental Early Rspack testing on production

On September 29, 2023, a build on Canary was released that broke everything. It was not known at the time this was Rspack. It was using a non-production-ready config.

Chunk names were not transformed into numbers, which leaked some file names. An example name would be defaultVendors~node_modules_lodash_lodash_js~_36ba.

Script tags had the defer property set, causing loading race conditions in some mods.

Config Issues

Config issues refer to minor changes to the config as opposed to entire bundler updates.

iOS CI

A message of a (Discord?) moderator (in the TestFlight server?) confirming that iOS CI builds being pushed to Canary weren't intentional and had to be reverted. Also confirming Discord's build times at the time

At the beginning of August 2021, Discord had an older CI for iOS builds that would push builds to Canary that would have to be reverted.

ES version indecisiveness

ECMAScript is a standard for scripting languages, namely JavaScript. It was formerly numerically versioned but is now versioned by year. Targeting a specific version tells the bundler what modern features need to be transpiled to compatible features supported by that version.

Changing this version breaks mods that use module patching.

December 21, 2023

The targeted version was downgraded to what it was set to pre-Rspack (ES5?). It was reverted and unreverted several times within a 3-hour window.

Vee messaged Discord developer Brandon (aweary) about it, and it was confirmed as unintentional.

February 28, 2024

The targeted version was bumped to ES 2020 or newer. It was reverted within 24 hours.

  1. "Ability to add displayName to all React components to prevent names from getting mangled".
  2. ""We might just stick with not having displayNames"".