强制启用 Vue Devtools

强制启用 Vue Devtools,适用于 Vue 2 或 Vue 3 的生产环境构建应用。

  1. // ==UserScript==
  2. // @name Force Enable Vue Devtools
  3. // @name:zh-CN 强制启用 Vue Devtools
  4. // @name:zh-TW 強制啟用 Vue Devtools
  5. // @version 1.0.1
  6. // @description Force enable Vue Devtools for production-build apps of Vue 2 or Vue 3.
  7. // @description:zh-CN 强制启用 Vue Devtools,适用于 Vue 2 或 Vue 3 的生产环境构建应用。
  8. // @description:zh-TW 強制啟用 Vue Devtools,適用於 Vue 2 或 Vue 3 的生產環境構建應用。
  9. // @author 三咲智子 Kevin Deng <sxzz@sxzz.moe>
  10. // @homepage https://github.com/sxzz/userscripts
  11. // @supportURL https://github.com/sxzz/userscripts/issues
  12. // @license MIT
  13. // @contributionURL https://github.com/sponsors/sxzz
  14. // @namespace https://github.com/sxzz/userscripts/blob/main/dist/vue-devtools.user.js
  15. // @run-at document-start
  16. // @noframes
  17. // @include *
  18. // ==/UserScript==
  19. (function() {
  20.  
  21.  
  22. //#region src/vue-devtools.ts
  23. /* @license
  24. * Refer from https://github.com/EHfive/userscripts/tree/master/userscripts/enbale-vue-devtools
  25. */
  26. let initted = false;
  27. main();
  28. document.addEventListener("DOMContentLoaded", () => main());
  29. globalThis.requestIdleCallback?.(() => main());
  30. function main() {
  31. if (initted) return;
  32. const devtoolsHook = getDevtoolsHook();
  33. if (!devtoolsHook) {
  34. console.warn("No Vue Devtools hook found, waiting");
  35. return;
  36. }
  37. initted = true;
  38. observePage();
  39. }
  40. function getDevtoolsHook() {
  41. return globalThis.__VUE_DEVTOOLS_GLOBAL_HOOK__;
  42. }
  43. function registerVue2App(app) {
  44. let Vue = app.constructor;
  45. while (Vue.super) Vue = Vue.super;
  46. Vue.config.devtools = true;
  47. console.info("enabling devtools for Vue instance", app);
  48. const devtoolsHook = getDevtoolsHook();
  49. devtoolsHook.emit("init", Vue);
  50. }
  51. function registerVue3App(app) {
  52. const devtoolsHook = getDevtoolsHook();
  53. if (!Array.isArray(devtoolsHook.apps)) return;
  54. if (devtoolsHook.apps.includes(app)) return;
  55. const version = app.version;
  56. if (!version) return;
  57. console.info("enabling devtools for Vue 3 instance", app);
  58. const types = {
  59. Fragment: void 0,
  60. Text: void 0,
  61. Comment: void 0,
  62. Static: void 0
  63. };
  64. devtoolsHook.emit("app:init", app, version, types);
  65. const unmount = app.unmount.bind(app);
  66. app.unmount = function() {
  67. devtoolsHook.emit("app:unmount", app);
  68. unmount();
  69. };
  70. }
  71. function checkVue2Instance(target) {
  72. const vue = target && target.__vue__;
  73. return !!(vue && typeof vue === "object" && vue._isVue && typeof vue.constructor === "function");
  74. }
  75. function checkVue3Instance(target) {
  76. const app = target && target.__vue_app__;
  77. return !!app;
  78. }
  79. function observePage() {
  80. const roots = /* @__PURE__ */ new WeakSet();
  81. const observer = new MutationObserver(() => {
  82. for (const el of Array.from(document.querySelectorAll("*"))) if (checkVue3Instance(el)) {
  83. const app = el.__vue_app__;
  84. if (roots.has(app)) continue;
  85. roots.add(app);
  86. registerVue3App(app);
  87. } else if (checkVue2Instance(el)) {
  88. const instance = el.__vue__;
  89. const root = instance.$parent ? instance.$root : instance;
  90. if (roots.has(root)) continue;
  91. roots.add(root);
  92. registerVue2App(root);
  93. }
  94. });
  95. observer.observe(document.documentElement, {
  96. attributes: true,
  97. subtree: true,
  98. childList: true
  99. });
  100. return observer;
  101. }
  102.  
  103. //#endregion
  104. })();