index.cjs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. var __create = Object.create;
  2. var __defProp = Object.defineProperty;
  3. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  4. var __getOwnPropNames = Object.getOwnPropertyNames;
  5. var __getProtoOf = Object.getPrototypeOf;
  6. var __hasOwnProp = Object.prototype.hasOwnProperty;
  7. var __export = (target, all) => {
  8. for (var name in all)
  9. __defProp(target, name, { get: all[name], enumerable: true });
  10. };
  11. var __copyProps = (to, from, except, desc) => {
  12. if (from && typeof from === "object" || typeof from === "function") {
  13. for (let key of __getOwnPropNames(from))
  14. if (!__hasOwnProp.call(to, key) && key !== except)
  15. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  16. }
  17. return to;
  18. };
  19. var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  20. // If the importer is in node compatibility mode or this is not an ESM
  21. // file that has been converted to a CommonJS file using a Babel-
  22. // compatible transform (i.e. "__esModule" has not been set), then set
  23. // "default" to the CommonJS "module.exports" for node compatibility.
  24. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  25. mod
  26. ));
  27. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  28. // src/index.ts
  29. var src_exports = {};
  30. __export(src_exports, {
  31. DEFAULT_INSPECTOR_OPTIONS: () => DEFAULT_INSPECTOR_OPTIONS,
  32. default: () => src_default,
  33. normalizeComboKeyPrint: () => normalizeComboKeyPrint
  34. });
  35. module.exports = __toCommonJS(src_exports);
  36. // ../../node_modules/.pnpm/tsup@7.2.0_postcss@8.4.49_typescript@5.2.2/node_modules/tsup/assets/cjs_shims.js
  37. var getImportMetaUrl = () => typeof document === "undefined" ? new URL("file:" + __filename).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
  38. var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
  39. // src/index.ts
  40. var import_node_path2 = __toESM(require("path"));
  41. var import_node_url = require("url");
  42. var import_node_fs = __toESM(require("fs"));
  43. var import_node_process = __toESM(require("process"));
  44. var import_kolorist = require("kolorist");
  45. var import_vite2 = require("vite");
  46. var import_magic_string2 = __toESM(require("magic-string"));
  47. // src/compiler/template.ts
  48. var import_node_path = __toESM(require("path"));
  49. var import_magic_string = __toESM(require("magic-string"));
  50. var import_compiler_dom = require("@vue/compiler-dom");
  51. var import_core = require("@babel/core");
  52. var import_babel_plugin_jsx = __toESM(require("@vue/babel-plugin-jsx"));
  53. var import_plugin_transform_typescript = __toESM(require("@babel/plugin-transform-typescript"));
  54. var import_plugin_syntax_import_meta = __toESM(require("@babel/plugin-syntax-import-meta"));
  55. var import_plugin_proposal_decorators = __toESM(require("@babel/plugin-proposal-decorators"));
  56. var import_plugin_syntax_import_attributes = __toESM(require("@babel/plugin-syntax-import-attributes"));
  57. var import_vite = require("vite");
  58. var EXCLUDE_TAG = ["template", "script", "style"];
  59. var KEY_DATA = "data-v-inspector";
  60. async function compileSFCTemplate({ code, id, type }) {
  61. const s = new import_magic_string.default(code);
  62. const relativePath = (0, import_vite.normalizePath)(import_node_path.default.relative(process.cwd(), id));
  63. const result = await new Promise((resolve) => {
  64. switch (type) {
  65. case "template": {
  66. const ast = (0, import_compiler_dom.parse)(code, { comments: true });
  67. (0, import_compiler_dom.transform)(ast, {
  68. nodeTransforms: [
  69. (node) => {
  70. if (node.type === 1) {
  71. if ((node.tagType === 0 || node.tagType === 1) && !EXCLUDE_TAG.includes(node.tag)) {
  72. if (node.loc.source.includes(KEY_DATA))
  73. return;
  74. const insertPosition = node.props.length ? Math.max(...node.props.map((i) => i.loc.end.offset)) : node.loc.start.offset + node.tag.length + 1;
  75. const { line, column } = node.loc.start;
  76. const content = ` ${KEY_DATA}="${relativePath}:${line}:${column}"`;
  77. s.prependLeft(
  78. insertPosition,
  79. content
  80. );
  81. }
  82. }
  83. }
  84. ]
  85. });
  86. break;
  87. }
  88. case "jsx": {
  89. const ast = (0, import_core.parse)(code, {
  90. babelrc: false,
  91. configFile: false,
  92. comments: true,
  93. plugins: [
  94. import_plugin_syntax_import_meta.default,
  95. [import_babel_plugin_jsx.default, {}],
  96. [
  97. import_plugin_transform_typescript.default,
  98. { isTSX: true, allowExtensions: true }
  99. ],
  100. [
  101. import_plugin_proposal_decorators.default,
  102. { legacy: true }
  103. ],
  104. [
  105. import_plugin_syntax_import_attributes.default,
  106. { deprecatedAssertSyntax: true }
  107. ]
  108. ]
  109. });
  110. (0, import_core.traverse)(ast, {
  111. enter({ node }) {
  112. if (node.type === "JSXElement" && !EXCLUDE_TAG.includes(s.slice(node.openingElement.name.start, node.openingElement.name.end))) {
  113. if (node.openingElement.attributes.some(
  114. (attr) => attr.type !== "JSXSpreadAttribute" && attr.name.name === KEY_DATA
  115. ))
  116. return;
  117. const insertPosition = node.openingElement.end - (node.openingElement.selfClosing ? 2 : 1);
  118. const { line, column } = node.loc.start;
  119. const content = ` ${KEY_DATA}="${relativePath}:${line}:${column}"`;
  120. s.prependLeft(
  121. insertPosition,
  122. content
  123. );
  124. }
  125. }
  126. });
  127. break;
  128. }
  129. default:
  130. break;
  131. }
  132. resolve(s.toString());
  133. });
  134. return result;
  135. }
  136. // src/utils/index.ts
  137. function parseVueRequest(id) {
  138. const [filename] = id.split("?", 2);
  139. const url = new URL(id, "http://domain.inspector");
  140. const query = Object.fromEntries(url.searchParams.entries());
  141. if (query.vue != null)
  142. query.vue = true;
  143. if (query.src != null)
  144. query.src = true;
  145. if (query.index != null)
  146. query.index = Number(query.index);
  147. if (query.raw != null)
  148. query.raw = true;
  149. if (query.hasOwnProperty("lang.tsx") || query.hasOwnProperty("lang.jsx"))
  150. query.isJsx = true;
  151. return {
  152. filename,
  153. query
  154. };
  155. }
  156. var FS_PREFIX = "/@fs/";
  157. var IS_WINDOWS = process.platform === "win32";
  158. var queryRE = /\?.*$/s;
  159. var hashRE = /#.*$/s;
  160. function idToFile(id) {
  161. if (id.startsWith(FS_PREFIX))
  162. id = id = id.slice(IS_WINDOWS ? FS_PREFIX.length : FS_PREFIX.length - 1);
  163. return id.replace(hashRE, "").replace(queryRE, "");
  164. }
  165. // src/index.ts
  166. var toggleComboKeysMap = {
  167. control: import_node_process.default.platform === "darwin" ? "Control(^)" : "Ctrl(^)",
  168. meta: "Command(\u2318)",
  169. shift: "Shift(\u21E7)"
  170. };
  171. function getInspectorPath() {
  172. const pluginPath = (0, import_vite2.normalizePath)(import_node_path2.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl)));
  173. return pluginPath.replace(/\/dist$/, "/src");
  174. }
  175. function normalizeComboKeyPrint(toggleComboKey) {
  176. return toggleComboKey.split("-").map((key) => toggleComboKeysMap[key] || key[0].toUpperCase() + key.slice(1)).join((0, import_kolorist.dim)("+"));
  177. }
  178. var DEFAULT_INSPECTOR_OPTIONS = {
  179. vue: 3,
  180. enabled: false,
  181. toggleComboKey: import_node_process.default.platform === "darwin" ? "meta-shift" : "control-shift",
  182. toggleButtonVisibility: "active",
  183. toggleButtonPos: "top-right",
  184. appendTo: "",
  185. lazyLoad: false,
  186. launchEditor: import_node_process.default.env.LAUNCH_EDITOR ?? "code",
  187. reduceMotion: false
  188. };
  189. function VitePluginInspector(options = DEFAULT_INSPECTOR_OPTIONS) {
  190. const inspectorPath = getInspectorPath();
  191. const normalizedOptions = {
  192. ...DEFAULT_INSPECTOR_OPTIONS,
  193. ...options
  194. };
  195. let config;
  196. const {
  197. vue,
  198. appendTo,
  199. cleanHtml = vue === 3
  200. // Only enabled for Vue 3 by default
  201. } = normalizedOptions;
  202. if (normalizedOptions.launchEditor)
  203. import_node_process.default.env.LAUNCH_EDITOR = normalizedOptions.launchEditor;
  204. return [
  205. {
  206. name: "vite-plugin-vue-inspector",
  207. enforce: "pre",
  208. apply(_, { command }) {
  209. return command === "serve" && import_node_process.default.env.NODE_ENV !== "test";
  210. },
  211. async resolveId(importee) {
  212. if (importee.startsWith("virtual:vue-inspector-options")) {
  213. return importee;
  214. } else if (importee.startsWith("virtual:vue-inspector-path:")) {
  215. const resolved = importee.replace("virtual:vue-inspector-path:", `${inspectorPath}/`);
  216. return resolved;
  217. }
  218. },
  219. async load(id) {
  220. if (id === "virtual:vue-inspector-options") {
  221. return `export default ${JSON.stringify({ ...normalizedOptions, base: config.base })}`;
  222. } else if (id.startsWith(inspectorPath)) {
  223. const { query } = parseVueRequest(id);
  224. if (query.type)
  225. return;
  226. const file = idToFile(id);
  227. if (import_node_fs.default.existsSync(file))
  228. return await import_node_fs.default.promises.readFile(file, "utf-8");
  229. else
  230. console.error(`failed to find file for vue-inspector: ${file}, referenced by id ${id}.`);
  231. }
  232. },
  233. transform(code, id) {
  234. const { filename, query } = parseVueRequest(id);
  235. const isJsx = filename.endsWith(".jsx") || filename.endsWith(".tsx") || filename.endsWith(".vue") && query.isJsx;
  236. const isTpl = filename.endsWith(".vue") && query.type !== "style" && !query.raw;
  237. if (isJsx || isTpl)
  238. return compileSFCTemplate({ code, id: filename, type: isJsx ? "jsx" : "template" });
  239. if (!appendTo)
  240. return;
  241. if (typeof appendTo === "string" && filename.endsWith(appendTo) || appendTo instanceof RegExp && appendTo.test(filename))
  242. return { code: `${code}
  243. import 'virtual:vue-inspector-path:load.js'` };
  244. },
  245. configureServer(server) {
  246. const _printUrls = server.printUrls;
  247. const { toggleComboKey } = normalizedOptions;
  248. toggleComboKey && (server.printUrls = () => {
  249. const keys = normalizeComboKeyPrint(toggleComboKey);
  250. _printUrls();
  251. console.log(` ${(0, import_kolorist.green)("\u279C")} ${(0, import_kolorist.bold)("Vue Inspector")}: ${(0, import_kolorist.green)(`Press ${(0, import_kolorist.yellow)(keys)} in App to toggle the Inspector`)}
  252. `);
  253. });
  254. },
  255. transformIndexHtml(html) {
  256. if (appendTo)
  257. return;
  258. return {
  259. html,
  260. tags: [
  261. {
  262. tag: "script",
  263. injectTo: "head",
  264. attrs: {
  265. type: "module",
  266. src: `${config.base || "/"}@id/virtual:vue-inspector-path:load.js`
  267. }
  268. }
  269. ]
  270. };
  271. },
  272. configResolved(resolvedConfig) {
  273. config = resolvedConfig;
  274. }
  275. },
  276. {
  277. name: "vite-plugin-vue-inspector:post",
  278. enforce: "post",
  279. apply(_, { command }) {
  280. return cleanHtml && vue === 3 && command === "serve" && import_node_process.default.env.NODE_ENV !== "test";
  281. },
  282. transform(code) {
  283. if (code.includes("_interopVNode"))
  284. return;
  285. if (!code.includes("data-v-inspector"))
  286. return;
  287. const fn = /* @__PURE__ */ new Set();
  288. const s = new import_magic_string2.default(code);
  289. s.replace(/(createElementVNode|createVNode|createElementBlock|createBlock) as _\1,?/g, (_, name) => {
  290. fn.add(name);
  291. return "";
  292. });
  293. if (!fn.size)
  294. return;
  295. s.appendLeft(0, `/* Injection by vite-plugin-vue-inspector Start */
  296. import { ${Array.from(fn.values()).map((i) => `${i} as __${i}`).join(",")} } from 'vue'
  297. function _interopVNode(vnode) {
  298. if (vnode && vnode.props && 'data-v-inspector' in vnode.props) {
  299. const data = vnode.props['data-v-inspector']
  300. delete vnode.props['data-v-inspector']
  301. Object.defineProperty(vnode.props, '__v_inspector', { value: data, enumerable: false })
  302. }
  303. return vnode
  304. }
  305. ${Array.from(fn.values()).map((i) => `function _${i}(...args) { return _interopVNode(__${i}(...args)) }`).join("\n")}
  306. /* Injection by vite-plugin-vue-inspector End */
  307. `);
  308. return {
  309. code: s.toString(),
  310. map: s.generateMap({ hires: "boundary" })
  311. };
  312. }
  313. }
  314. ];
  315. }
  316. var src_default = VitePluginInspector;
  317. // Annotate the CommonJS export names for ESM import in node:
  318. 0 && (module.exports = {
  319. DEFAULT_INSPECTOR_OPTIONS,
  320. normalizeComboKeyPrint
  321. });