From 979d267d569734dc3cb969ed1880ed68bb79f1b5 Mon Sep 17 00:00:00 2001
From: Egor <7gorbachevm@gmail.com>
Date: Wed, 24 Jun 2026 14:56:42 +0700
Subject: [PATCH] Shorten minified error URL to reduce production bundle size
(#4677)
* Shorten minified error URL
* simpler check
* simpler code
* wording
---
.changeset/fix-minified-error-link.md | 5 +++
.gitignore | 1 +
packages/mobx/src/errors.ts | 4 +-
packages/mobx/src/internal.ts | 2 +-
website/i18n/en.json | 4 ++
website/package.json | 2 +
website/scripts/generate-error-docs.js | 57 ++++++++++++++++++++++++++
website/sidebars.json | 1 +
8 files changed, 73 insertions(+), 3 deletions(-)
create mode 100644 .changeset/fix-minified-error-link.md
create mode 100644 website/scripts/generate-error-docs.js
diff --git a/.changeset/fix-minified-error-link.md b/.changeset/fix-minified-error-link.md
new file mode 100644
index 0000000000..ac68f01ee4
--- /dev/null
+++ b/.changeset/fix-minified-error-link.md
@@ -0,0 +1,5 @@
+---
+"mobx": patch
+---
+
+Shorten minified error URL to reduce production bundle size.
diff --git a/.gitignore b/.gitignore
index 4170db41f5..4059224142 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ coverage
test/babel-tests.js
test/typescript/typescript-tests.js
dist/
+/docs/errors.md
**/.idea/*
!/.idea/icon.png
!/.idea/vcs.xml
diff --git a/packages/mobx/src/errors.ts b/packages/mobx/src/errors.ts
index 9a97bdc55c..9ec23a018c 100644
--- a/packages/mobx/src/errors.ts
+++ b/packages/mobx/src/errors.ts
@@ -1,4 +1,4 @@
-const niceErrors = {
+export const niceErrors = {
0: `Invalid value for configuration 'enforceActions', expected 'never', 'always' or 'observed'`,
1(annotationType, key: PropertyKey) {
return `Cannot apply '${annotationType}' to '${key.toString()}': Field not found.`
@@ -87,7 +87,7 @@ export function die(error: string | keyof typeof errors, ...args: any[]): never
typeof error === "number"
? `[MobX] minified error nr: ${error}${
args.length ? " " + args.map(String).join(",") : ""
- }. Find the full error at: https://github.com/mobxjs/mobx/blob/main/packages/mobx/src/errors.ts`
+ }. See http://mobx.js.org/errors`
: `[MobX] ${error}`
)
}
diff --git a/packages/mobx/src/internal.ts b/packages/mobx/src/internal.ts
index 1317b234c3..48885069a4 100644
--- a/packages/mobx/src/internal.ts
+++ b/packages/mobx/src/internal.ts
@@ -6,7 +6,7 @@ With this file that will still happen,
but at least in this file we can magically reorder the imports with trial and error until the build succeeds again.
*/
export * from "./utils/global"
-export * from "./errors"
+export { die } from "./errors"
export * from "./utils/utils"
export * from "./api/decorators"
export * from "./core/atom"
diff --git a/website/i18n/en.json b/website/i18n/en.json
index a387a8141d..85973a3fda 100644
--- a/website/i18n/en.json
+++ b/website/i18n/en.json
@@ -64,6 +64,10 @@
"title": "Decorators",
"sidebar_label": "Decorators {🚀}"
},
+ "errors": {
+ "title": "MobX error codes",
+ "sidebar_label": "Error codes"
+ },
"faq/migrate-to-6": {
"title": "Migrating from MobX 4/5"
},
diff --git a/website/package.json b/website/package.json
index 9e0ffd0f0c..3aaa2577f5 100644
--- a/website/package.json
+++ b/website/package.json
@@ -1,7 +1,9 @@
{
"scripts": {
"examples": "docusaurus-examples",
+ "prestart": "node scripts/generate-error-docs.js",
"start": "docusaurus-start",
+ "prebuild": "node scripts/generate-error-docs.js",
"build": "docusaurus-build",
"publish-gh-pages": "docusaurus-publish",
"write-translations": "docusaurus-write-translations",
diff --git a/website/scripts/generate-error-docs.js b/website/scripts/generate-error-docs.js
new file mode 100644
index 0000000000..aa9db32ec5
--- /dev/null
+++ b/website/scripts/generate-error-docs.js
@@ -0,0 +1,57 @@
+#!/usr/bin/env node
+
+const { writeFileSync } = require("fs")
+const { relative, resolve } = require("path")
+
+const repoRoot = resolve(__dirname, "../..")
+const errorsPath = resolve(repoRoot, "packages/mobx/src/errors.ts")
+const outputPath = resolve(repoRoot, "docs/errors.md")
+
+globalThis.__DEV__ = true
+const { niceErrors } = require(errorsPath)
+
+function formatMarkdownCell(message) {
+ let value = message
+
+ if (typeof message === "function") {
+ // Render dynamic errors with visible placeholders instead of real runtime values
+ const match = message.toString().match(/^[^(]*\(([^)]*)\)/)
+ const params = match ? match[1] : ""
+ const names = params.split(",").map(name => name.trim()).filter(Boolean)
+ const args = names.map(name => `{${name}}`)
+ value = message(...args).replace("String", args[0])
+ }
+
+ // Keep the generated table valid Markdown
+ return String(value).replace(/\r?\n/g, "
").replace(/\|/g, "\\|")
+}
+
+function renderDocs(errors) {
+ const rows = Object.keys(errors)
+ .sort((left, right) => Number(left) - Number(right))
+ .map(code => `| ${code} | ${formatMarkdownCell(errors[code])} |`)
+ .join("\n")
+
+ return `---
+title: MobX error codes
+sidebar_label: Error codes
+hide_title: true
+custom_edit_url: https://github.com/mobxjs/mobx/edit/main/packages/mobx/src/errors.ts
+---
+
+
+
+# MobX error codes
+
+In development builds, MobX throws full error messages. Production builds replace known messages with short numeric codes to keep the published bundle smaller.
+
+| Code | Message |
+| ---- | ------- |
+${rows}
+`
+}
+
+const docs = renderDocs(niceErrors)
+writeFileSync(outputPath, docs)
+
+console.log(`Generated ${relative(repoRoot, outputPath)} from ${relative(repoRoot, errorsPath)}`)
diff --git a/website/sidebars.json b/website/sidebars.json
index 107e059688..2d5d8196e8 100755
--- a/website/sidebars.json
+++ b/website/sidebars.json
@@ -22,6 +22,7 @@
"understanding-reactivity",
"subclassing",
"analyzing-reactivity",
+ "errors",
"computeds-with-args",
"mobx-utils",
"custom-observables",