New Project
All checks were successful
BeijingMediaOfficialWebsite-ZhaoJian/BeijingMediaOfficialWebsite-ZhaoJian/pipeline/head This commit looks good

This commit is contained in:
2025-12-27 07:57:30 +08:00
parent 3a837da8af
commit 615d671da1
4911 changed files with 1180784 additions and 0 deletions

21
web/node_modules/vite-plugin-vue-inspector/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 webfansplz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

329
web/node_modules/vite-plugin-vue-inspector/README.md generated vendored Normal file
View File

@@ -0,0 +1,329 @@
<p align="center">
<a href="https://github.com/webfansplz/vite-plugin-vue-inspector"><img src="./logo.svg" width="180" alt="vite-plugin-vue-inspector"></a>
</p>
<p align="center">
<a href="https://www.npmjs.com/package/vite-plugin-vue-inspector" target="_blank" rel="noopener noreferrer"><img src="https://badgen.net/npm/v/vite-plugin-vue-inspector" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/package/vite-plugin-vue-inspector" target="_blank" rel="noopener noreferrer"><img src="https://badgen.net/npm/dt/vite-plugin-vue-inspector" alt="NPM Downloads" /></a>
<a href="https://github.com/webfansplz/vite-plugin-vue-inspector/blob/master/LICENSE" target="_blank" rel="noopener noreferrer"><img src="https://badgen.net/github/license/webfansplz/vite-plugin-vue-inspector" alt="License" /></a>
</p>
<p align="center">
<a href="https://stackblitz.com/edit/vitejs-vite-rbr2as?file=src%2FApp.vue"><img src="https://developer.stackblitz.com/img/open_in_stackblitz.svg" alt=""></a>
</p>
## 📖 Introduction
A vite plugin which provides the ability that to jump to the local IDE when you click the element of browser automatically. It supports Vue2 & 3 & SSR.
<p align="center">
<img src="./public/preview.gif" alt="vite-plugin-vue-inspector">
</p>
## 📦 Installation
```bash
# vite-plugin-vue-inspector
pnpm install vite-plugin-vue-inspector -D
# unplugin-vue-inspector
pnpm install unplugin-vue-inspector -D
```
## 🦄 Usage
### Configuration Vite
```ts
// for Vue2
import { defineConfig, } from 'vite'
import { createVuePlugin, } from 'vite-plugin-vue2'
import Inspector from 'unplugin-vue-inspector/vite' // OR vite-plugin-vue-inspector
export default defineConfig({
plugins: [
createVuePlugin(),
Inspector({
vue: 2
}),
],
})
```
```ts
// for Vue3
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import Inspector from 'unplugin-vue-inspector/vite' // OR vite-plugin-vue-inspector
export default defineConfig({
plugins: [Vue(), Inspector()],
})
```
```ts
// for Nuxt3
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt/config'
import Inspector from 'vite-plugin-vue-inspector'
export default defineNuxtConfig({
modules: [
['unplugin-vue-inspector/nuxt', {
enabled: true,
toggleButtonVisibility: 'always',
}],
],
})
```
### Options
```ts
interface VitePluginInspectorOptions {
/**
* Vue version
* @default 3
*/
vue?: 2 | 3
/**
* Default enable state
* @default false
*/
enabled?: boolean
/**
* Define a combo key to toggle inspector
* @default 'control-shift' on windows, 'meta-shift' on other os
*
* any number of modifiers `control` `shift` `alt` `meta` followed by zero or one regular key, separated by -
* examples: control-shift, control-o, control-alt-s meta-x control-meta
* Some keys have native behavior (e.g. alt-s opens history menu on firefox).
* To avoid conflicts or accidentally typing into inputs, modifier only combinations are recommended.
* You can also disable it by setting `false`.
*/
toggleComboKey?: string | false
/**
* Toggle button visibility
* @default 'active'
*/
toggleButtonVisibility?: 'always' | 'active' | 'never'
/**
* Toggle button display position
* @default top-right
*/
toggleButtonPos?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'
/**
* append an import to the module id ending with `appendTo` instead of adding a script into body
* useful for frameworks that do not support transformIndexHtml hook (e.g. Nuxt3)
*
* WARNING: only set this if you know exactly what it does.
*/
appendTo?: string | RegExp
/**
* Customize openInEditor host (e.g. http://localhost:3000)
* @default false
* @deprecated This option is deprecated and removed in 5.0. The plugin now automatically detects the correct host.
*/
openInEditorHost?: string | false
/**
* lazy load inspector times (ms)
* @default false
*/
lazyLoad?: number | false
/**
* disable inspector on editor open
* @default false
*/
disableInspectorOnEditorOpen?: boolean
/**
* Hide information in VNode and produce clean html in DevTools
*
* Currently, it only works for Vue 3
*
* @default true
*/
cleanHtml?: boolean
/**
* Target editor when open in editor (v5.1.0+)
*
* @default code (Visual Studio Code)
*/
launchEditor?: 'appcode' | 'atom' | 'atom-beta' | 'brackets' | 'clion' | 'code' | 'code-insiders' | 'codium' | 'emacs' | 'idea' | 'notepad++' | 'pycharm' | 'phpstorm' | 'rubymine' | 'sublime' | 'vim' | 'visualstudio' | 'webstorm' | 'cursor'
}
```
### Example
- [Vue2](https://github.com/webfansplz/vite-plugin-vue-inspector/tree/main/packages/playground/vue2)
- [Vue3](https://github.com/webfansplz/vite-plugin-vue-inspector/tree/main/packages/playground/vue3)
- [Nuxt3](https://github.com/webfansplz/vite-plugin-vue-inspector/tree/main/packages/playground/nuxt)
## Supported editors
| Value | Editor | Linux | Windows | OSX |
|--------|------|:------:|:------:|:------:|
| `appcode` | [AppCode](https://www.jetbrains.com/objc/) | | |✓|
| `atom` | [Atom](https://atom.io/) |✓|✓|✓|
| `atom-beta` | [Atom Beta](https://atom.io/beta) | | |✓|
| `brackets` | [Brackets](http://brackets.io/) |✓|✓|✓|
| `clion` | [Clion](https://www.jetbrains.com/clion/) | |✓|✓|
| `code` | [Visual Studio Code](https://code.visualstudio.com/) |✓|✓|✓|
| `code-insiders` | [Visual Studio Code Insiders](https://code.visualstudio.com/insiders/) |✓|✓|✓|
| `codium` | [VSCodium](https://github.com/VSCodium/vscodium) |✓|✓|✓|
| `emacs` | [Emacs](https://www.gnu.org/software/emacs/) |✓| | |
| `idea` | [IDEA](https://www.jetbrains.com/idea/) |✓|✓|✓|
| `notepad++` | [Notepad++](https://notepad-plus-plus.org/download/v7.5.4.html) | |✓| |
| `pycharm` | [PyCharm](https://www.jetbrains.com/pycharm/) |✓|✓|✓|
| `phpstorm` | [PhpStorm](https://www.jetbrains.com/phpstorm/) |✓|✓|✓|
| `rubymine` | [RubyMine](https://www.jetbrains.com/ruby/) |✓|✓|✓|
| `sublime` | [Sublime Text](https://www.sublimetext.com/) |✓|✓|✓|
| `vim` | [Vim](http://www.vim.org/) |✓| | |
| `visualstudio` | [Visual Studio](https://www.visualstudio.com/vs/) | | |✓|
| `webstorm` | [WebStorm](https://www.jetbrains.com/webstorm/) |✓|✓|✓|
| `cursor` | [Cursor](https://www.cursor.com/) |✓|✓|✓|
## 🔌 Configuration IDE / Editor
**Starting from v5.1.0, We recommend using the `launchEditor` option configuration to specify the IDE** (Please ensure that the editor's environment variables are correctly configured beforehand.)
It uses an **environment variable** named **`LAUNCH_EDITOR`** to specify an IDE application, but if you do not set this variable, it will try to open a common IDE that you have open or installed once it is certified.
For example, if you want it always open VS Code when inspection clicked, set `export LAUNCH_EDITOR=code` in your shell.
### VS Code
- install VS Code command line tools, [see the official docs](https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line)
![install-vscode-cli](./public/install-vscode-cli.png)
- set env to shell, like `.bashrc` or `.zshrc`
```bash
export LAUNCH_EDITOR=code
```
<br />
### VS Code with WSL (Windows)
- add the configuration in the `settings.json`
- restart the VS Code (All Windows should be closed to take effect)
```json
{
// other config...
"terminal.integrated.env.linux": {
"EDITOR": "code"
}
}
```
### WebStorm
- just set env with an absolute path to shell, like `.bashrc` or `.zshrc` (only MacOS)
```bash
export LAUNCH_EDITOR='/Applications/WebStorm.app/Contents/MacOS/webstorm'
```
**OR**
- install WebStorm command line tools
- then set env to shell, like `.bashrc` or `.zshrc`
```bash
export LAUNCH_EDITOR=webstorm
```
<br />
### PhpStorm
- just set env with an absolute path to shell, like `.bashrc` or `.zshrc` (only MacOS)
```bash
export LAUNCH_EDITOR='/Applications/PhpStorm.app/Contents/MacOS/phpstorm'
```
**OR**
- install PhpStorm command line tools
- then set env to shell, like `.bashrc` or `.zshrc`
```bash
export LAUNCH_EDITOR=phpstorm
```
<br />
### Vim
Yes! you can also use vim if you want, just set env to shell
```bash
export LAUNCH_EDITOR=vim
```
<br />
## 💡 Notice
- **[BREAKING CHANGE] From v1.0, `enabled` option default value changed from `true` to `false` .**
- It only work in develop mode .
- It does not currently support `Template Engine (e.g. pug)` .
## 👨‍💻 Programmatic Usage
You can also use control inspector programmatically, by accessing the `__VUE_INSPECTOR__` global variable.
```ts
import type { VueInspectorClient } from 'vite-plugin-vue-inspector'
const inspector: VueInspectorClient = window.__VUE_INSPECTOR__
if (inspector) {
// enable inspector
inspector.enable()
// or
inspector.disable()
}
```
## 🌸 Credits
This project is inspired by [react-dev-inspector](https://github.com/zthxxx/react-dev-inspector) .
Partially implementation is inspired by [vite-plugin-svelte-inspector](https://github.com/sveltejs/vite-plugin-svelte/tree/main/packages/vite-plugin-svelte/src/ui/inspector) .
## 🤖️ Analysis of Theory
[Chinese] [点击页面元素,这个Vite插件帮我打开了Vue组件](https://juejin.cn/post/7077347158545924127)
## 📄 License
[MIT LICENSE](./LICENSE)

View File

@@ -0,0 +1,327 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
DEFAULT_INSPECTOR_OPTIONS: () => DEFAULT_INSPECTOR_OPTIONS,
default: () => src_default,
normalizeComboKeyPrint: () => normalizeComboKeyPrint
});
module.exports = __toCommonJS(src_exports);
// ../../node_modules/.pnpm/tsup@7.2.0_postcss@8.4.49_typescript@5.2.2/node_modules/tsup/assets/cjs_shims.js
var getImportMetaUrl = () => typeof document === "undefined" ? new URL("file:" + __filename).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
// src/index.ts
var import_node_path2 = __toESM(require("path"));
var import_node_url = require("url");
var import_node_fs = __toESM(require("fs"));
var import_node_process = __toESM(require("process"));
var import_kolorist = require("kolorist");
var import_vite2 = require("vite");
var import_magic_string2 = __toESM(require("magic-string"));
// src/compiler/template.ts
var import_node_path = __toESM(require("path"));
var import_magic_string = __toESM(require("magic-string"));
var import_compiler_dom = require("@vue/compiler-dom");
var import_core = require("@babel/core");
var import_babel_plugin_jsx = __toESM(require("@vue/babel-plugin-jsx"));
var import_plugin_transform_typescript = __toESM(require("@babel/plugin-transform-typescript"));
var import_plugin_syntax_import_meta = __toESM(require("@babel/plugin-syntax-import-meta"));
var import_plugin_proposal_decorators = __toESM(require("@babel/plugin-proposal-decorators"));
var import_plugin_syntax_import_attributes = __toESM(require("@babel/plugin-syntax-import-attributes"));
var import_vite = require("vite");
var EXCLUDE_TAG = ["template", "script", "style"];
var KEY_DATA = "data-v-inspector";
async function compileSFCTemplate({ code, id, type }) {
const s = new import_magic_string.default(code);
const relativePath = (0, import_vite.normalizePath)(import_node_path.default.relative(process.cwd(), id));
const result = await new Promise((resolve) => {
switch (type) {
case "template": {
const ast = (0, import_compiler_dom.parse)(code, { comments: true });
(0, import_compiler_dom.transform)(ast, {
nodeTransforms: [
(node) => {
if (node.type === 1) {
if ((node.tagType === 0 || node.tagType === 1) && !EXCLUDE_TAG.includes(node.tag)) {
if (node.loc.source.includes(KEY_DATA))
return;
const insertPosition = node.props.length ? Math.max(...node.props.map((i) => i.loc.end.offset)) : node.loc.start.offset + node.tag.length + 1;
const { line, column } = node.loc.start;
const content = ` ${KEY_DATA}="${relativePath}:${line}:${column}"`;
s.prependLeft(
insertPosition,
content
);
}
}
}
]
});
break;
}
case "jsx": {
const ast = (0, import_core.parse)(code, {
babelrc: false,
configFile: false,
comments: true,
plugins: [
import_plugin_syntax_import_meta.default,
[import_babel_plugin_jsx.default, {}],
[
import_plugin_transform_typescript.default,
{ isTSX: true, allowExtensions: true }
],
[
import_plugin_proposal_decorators.default,
{ legacy: true }
],
[
import_plugin_syntax_import_attributes.default,
{ deprecatedAssertSyntax: true }
]
]
});
(0, import_core.traverse)(ast, {
enter({ node }) {
if (node.type === "JSXElement" && !EXCLUDE_TAG.includes(s.slice(node.openingElement.name.start, node.openingElement.name.end))) {
if (node.openingElement.attributes.some(
(attr) => attr.type !== "JSXSpreadAttribute" && attr.name.name === KEY_DATA
))
return;
const insertPosition = node.openingElement.end - (node.openingElement.selfClosing ? 2 : 1);
const { line, column } = node.loc.start;
const content = ` ${KEY_DATA}="${relativePath}:${line}:${column}"`;
s.prependLeft(
insertPosition,
content
);
}
}
});
break;
}
default:
break;
}
resolve(s.toString());
});
return result;
}
// src/utils/index.ts
function parseVueRequest(id) {
const [filename] = id.split("?", 2);
const url = new URL(id, "http://domain.inspector");
const query = Object.fromEntries(url.searchParams.entries());
if (query.vue != null)
query.vue = true;
if (query.src != null)
query.src = true;
if (query.index != null)
query.index = Number(query.index);
if (query.raw != null)
query.raw = true;
if (query.hasOwnProperty("lang.tsx") || query.hasOwnProperty("lang.jsx"))
query.isJsx = true;
return {
filename,
query
};
}
var FS_PREFIX = "/@fs/";
var IS_WINDOWS = process.platform === "win32";
var queryRE = /\?.*$/s;
var hashRE = /#.*$/s;
function idToFile(id) {
if (id.startsWith(FS_PREFIX))
id = id = id.slice(IS_WINDOWS ? FS_PREFIX.length : FS_PREFIX.length - 1);
return id.replace(hashRE, "").replace(queryRE, "");
}
// src/index.ts
var toggleComboKeysMap = {
control: import_node_process.default.platform === "darwin" ? "Control(^)" : "Ctrl(^)",
meta: "Command(\u2318)",
shift: "Shift(\u21E7)"
};
function getInspectorPath() {
const pluginPath = (0, import_vite2.normalizePath)(import_node_path2.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl)));
return pluginPath.replace(/\/dist$/, "/src");
}
function normalizeComboKeyPrint(toggleComboKey) {
return toggleComboKey.split("-").map((key) => toggleComboKeysMap[key] || key[0].toUpperCase() + key.slice(1)).join((0, import_kolorist.dim)("+"));
}
var DEFAULT_INSPECTOR_OPTIONS = {
vue: 3,
enabled: false,
toggleComboKey: import_node_process.default.platform === "darwin" ? "meta-shift" : "control-shift",
toggleButtonVisibility: "active",
toggleButtonPos: "top-right",
appendTo: "",
lazyLoad: false,
launchEditor: import_node_process.default.env.LAUNCH_EDITOR ?? "code",
reduceMotion: false
};
function VitePluginInspector(options = DEFAULT_INSPECTOR_OPTIONS) {
const inspectorPath = getInspectorPath();
const normalizedOptions = {
...DEFAULT_INSPECTOR_OPTIONS,
...options
};
let config;
const {
vue,
appendTo,
cleanHtml = vue === 3
// Only enabled for Vue 3 by default
} = normalizedOptions;
if (normalizedOptions.launchEditor)
import_node_process.default.env.LAUNCH_EDITOR = normalizedOptions.launchEditor;
return [
{
name: "vite-plugin-vue-inspector",
enforce: "pre",
apply(_, { command }) {
return command === "serve" && import_node_process.default.env.NODE_ENV !== "test";
},
async resolveId(importee) {
if (importee.startsWith("virtual:vue-inspector-options")) {
return importee;
} else if (importee.startsWith("virtual:vue-inspector-path:")) {
const resolved = importee.replace("virtual:vue-inspector-path:", `${inspectorPath}/`);
return resolved;
}
},
async load(id) {
if (id === "virtual:vue-inspector-options") {
return `export default ${JSON.stringify({ ...normalizedOptions, base: config.base })}`;
} else if (id.startsWith(inspectorPath)) {
const { query } = parseVueRequest(id);
if (query.type)
return;
const file = idToFile(id);
if (import_node_fs.default.existsSync(file))
return await import_node_fs.default.promises.readFile(file, "utf-8");
else
console.error(`failed to find file for vue-inspector: ${file}, referenced by id ${id}.`);
}
},
transform(code, id) {
const { filename, query } = parseVueRequest(id);
const isJsx = filename.endsWith(".jsx") || filename.endsWith(".tsx") || filename.endsWith(".vue") && query.isJsx;
const isTpl = filename.endsWith(".vue") && query.type !== "style" && !query.raw;
if (isJsx || isTpl)
return compileSFCTemplate({ code, id: filename, type: isJsx ? "jsx" : "template" });
if (!appendTo)
return;
if (typeof appendTo === "string" && filename.endsWith(appendTo) || appendTo instanceof RegExp && appendTo.test(filename))
return { code: `${code}
import 'virtual:vue-inspector-path:load.js'` };
},
configureServer(server) {
const _printUrls = server.printUrls;
const { toggleComboKey } = normalizedOptions;
toggleComboKey && (server.printUrls = () => {
const keys = normalizeComboKeyPrint(toggleComboKey);
_printUrls();
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`)}
`);
});
},
transformIndexHtml(html) {
if (appendTo)
return;
return {
html,
tags: [
{
tag: "script",
injectTo: "head",
attrs: {
type: "module",
src: `${config.base || "/"}@id/virtual:vue-inspector-path:load.js`
}
}
]
};
},
configResolved(resolvedConfig) {
config = resolvedConfig;
}
},
{
name: "vite-plugin-vue-inspector:post",
enforce: "post",
apply(_, { command }) {
return cleanHtml && vue === 3 && command === "serve" && import_node_process.default.env.NODE_ENV !== "test";
},
transform(code) {
if (code.includes("_interopVNode"))
return;
if (!code.includes("data-v-inspector"))
return;
const fn = /* @__PURE__ */ new Set();
const s = new import_magic_string2.default(code);
s.replace(/(createElementVNode|createVNode|createElementBlock|createBlock) as _\1,?/g, (_, name) => {
fn.add(name);
return "";
});
if (!fn.size)
return;
s.appendLeft(0, `/* Injection by vite-plugin-vue-inspector Start */
import { ${Array.from(fn.values()).map((i) => `${i} as __${i}`).join(",")} } from 'vue'
function _interopVNode(vnode) {
if (vnode && vnode.props && 'data-v-inspector' in vnode.props) {
const data = vnode.props['data-v-inspector']
delete vnode.props['data-v-inspector']
Object.defineProperty(vnode.props, '__v_inspector', { value: data, enumerable: false })
}
return vnode
}
${Array.from(fn.values()).map((i) => `function _${i}(...args) { return _interopVNode(__${i}(...args)) }`).join("\n")}
/* Injection by vite-plugin-vue-inspector End */
`);
return {
code: s.toString(),
map: s.generateMap({ hires: "boundary" })
};
}
}
];
}
var src_default = VitePluginInspector;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
DEFAULT_INSPECTOR_OPTIONS,
normalizeComboKeyPrint
});

View File

@@ -0,0 +1,101 @@
import { PluginOption } from 'vite';
interface VueInspectorClient {
enabled: boolean;
position: {
x: number;
y: number;
};
linkParams: {
file: string;
line: number;
column: number;
};
enable: () => void;
disable: () => void;
toggleEnabled: () => void;
onEnabled: () => void;
onDisabled: () => void;
openInEditor: (url: URL) => void;
onUpdated: () => void;
}
interface VitePluginInspectorOptions {
/**
* Vue version
* @default 3
*/
vue?: 2 | 3;
/**
* Default enable state
* @default false
*/
enabled?: boolean;
/**
* Define a combo key to toggle inspector
* @default 'control-shift' on windows, 'meta-shift' on other os
*
* any number of modifiers `control` `shift` `alt` `meta` followed by zero or one regular key, separated by -
* examples: control-shift, control-o, control-alt-s meta-x control-meta
* Some keys have native behavior (e.g. alt-s opens history menu on firefox).
* To avoid conflicts or accidentally typing into inputs, modifier only combinations are recommended.
* You can also disable it by setting `false`.
*/
toggleComboKey?: string | false;
/**
* Toggle button visibility
* @default 'active'
*/
toggleButtonVisibility?: 'always' | 'active' | 'never';
/**
* Toggle button display position
* @default top-right
*/
toggleButtonPos?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
/**
* append an import to the module id ending with `appendTo` instead of adding a script into body
* useful for frameworks that do not support transformIndexHtml hook (e.g. Nuxt3)
*
* WARNING: only set this if you know exactly what it does.
*/
appendTo?: string | RegExp;
/**
* Customize openInEditor host (e.g. http://localhost:3000)
* @default false
* @deprecated This option is deprecated and removed in 5.0. The plugin now automatically detects the correct host.
*/
openInEditorHost?: string | false;
/**
* lazy load inspector times (ms)
* @default false
*/
lazyLoad?: number | false;
/**
* disable inspector on editor open
* @default false
*/
disableInspectorOnEditorOpen?: boolean;
/**
* Hide information in VNode and produce clean html in DevTools
*
* Currently, it only works for Vue 3
*
* @default true
*/
cleanHtml?: boolean;
/**
* Target editor when open in editor (v5.1.0+)
*
* @default process.env.LAUNCH_EDITOR ?? code (Visual Studio Code)
*/
launchEditor?: 'appcode' | 'atom' | 'atom-beta' | 'brackets' | 'clion' | 'code' | 'code-insiders' | 'codium' | 'emacs' | 'idea' | 'notepad++' | 'pycharm' | 'phpstorm' | 'rubymine' | 'sublime' | 'vim' | 'visualstudio' | 'webstorm' | 'rider' | 'cursor' | string;
/**
* Disable animation/transition, will auto disable when `prefers-reduced-motion` is set
* @default false
*/
reduceMotion?: boolean;
}
declare function normalizeComboKeyPrint(toggleComboKey: string): string;
declare const DEFAULT_INSPECTOR_OPTIONS: VitePluginInspectorOptions;
declare function VitePluginInspector(options?: VitePluginInspectorOptions): PluginOption;
export { DEFAULT_INSPECTOR_OPTIONS, VitePluginInspectorOptions, VueInspectorClient, VitePluginInspector as default, normalizeComboKeyPrint };

View File

@@ -0,0 +1,101 @@
import { PluginOption } from 'vite';
interface VueInspectorClient {
enabled: boolean;
position: {
x: number;
y: number;
};
linkParams: {
file: string;
line: number;
column: number;
};
enable: () => void;
disable: () => void;
toggleEnabled: () => void;
onEnabled: () => void;
onDisabled: () => void;
openInEditor: (url: URL) => void;
onUpdated: () => void;
}
interface VitePluginInspectorOptions {
/**
* Vue version
* @default 3
*/
vue?: 2 | 3;
/**
* Default enable state
* @default false
*/
enabled?: boolean;
/**
* Define a combo key to toggle inspector
* @default 'control-shift' on windows, 'meta-shift' on other os
*
* any number of modifiers `control` `shift` `alt` `meta` followed by zero or one regular key, separated by -
* examples: control-shift, control-o, control-alt-s meta-x control-meta
* Some keys have native behavior (e.g. alt-s opens history menu on firefox).
* To avoid conflicts or accidentally typing into inputs, modifier only combinations are recommended.
* You can also disable it by setting `false`.
*/
toggleComboKey?: string | false;
/**
* Toggle button visibility
* @default 'active'
*/
toggleButtonVisibility?: 'always' | 'active' | 'never';
/**
* Toggle button display position
* @default top-right
*/
toggleButtonPos?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
/**
* append an import to the module id ending with `appendTo` instead of adding a script into body
* useful for frameworks that do not support transformIndexHtml hook (e.g. Nuxt3)
*
* WARNING: only set this if you know exactly what it does.
*/
appendTo?: string | RegExp;
/**
* Customize openInEditor host (e.g. http://localhost:3000)
* @default false
* @deprecated This option is deprecated and removed in 5.0. The plugin now automatically detects the correct host.
*/
openInEditorHost?: string | false;
/**
* lazy load inspector times (ms)
* @default false
*/
lazyLoad?: number | false;
/**
* disable inspector on editor open
* @default false
*/
disableInspectorOnEditorOpen?: boolean;
/**
* Hide information in VNode and produce clean html in DevTools
*
* Currently, it only works for Vue 3
*
* @default true
*/
cleanHtml?: boolean;
/**
* Target editor when open in editor (v5.1.0+)
*
* @default process.env.LAUNCH_EDITOR ?? code (Visual Studio Code)
*/
launchEditor?: 'appcode' | 'atom' | 'atom-beta' | 'brackets' | 'clion' | 'code' | 'code-insiders' | 'codium' | 'emacs' | 'idea' | 'notepad++' | 'pycharm' | 'phpstorm' | 'rubymine' | 'sublime' | 'vim' | 'visualstudio' | 'webstorm' | 'rider' | 'cursor' | string;
/**
* Disable animation/transition, will auto disable when `prefers-reduced-motion` is set
* @default false
*/
reduceMotion?: boolean;
}
declare function normalizeComboKeyPrint(toggleComboKey: string): string;
declare const DEFAULT_INSPECTOR_OPTIONS: VitePluginInspectorOptions;
declare function VitePluginInspector(options?: VitePluginInspectorOptions): PluginOption;
export { DEFAULT_INSPECTOR_OPTIONS, VitePluginInspectorOptions, VueInspectorClient, VitePluginInspector as default, normalizeComboKeyPrint };

View File

@@ -0,0 +1,286 @@
// src/index.ts
import path2 from "node:path";
import { fileURLToPath } from "node:url";
import fs from "node:fs";
import process2 from "node:process";
import { bold, dim, green, yellow } from "kolorist";
import { normalizePath as normalizePath2 } from "vite";
import MagicString2 from "magic-string";
// src/compiler/template.ts
import path from "node:path";
import MagicString from "magic-string";
import { parse as vueParse, transform as vueTransform } from "@vue/compiler-dom";
import { parse as babelParse, traverse as babelTraverse } from "@babel/core";
import vueJsxPlugin from "@vue/babel-plugin-jsx";
import typescriptPlugin from "@babel/plugin-transform-typescript";
import importMeta from "@babel/plugin-syntax-import-meta";
import decoratorsPlugin from "@babel/plugin-proposal-decorators";
import importAttributesPlugin from "@babel/plugin-syntax-import-attributes";
import { normalizePath } from "vite";
var EXCLUDE_TAG = ["template", "script", "style"];
var KEY_DATA = "data-v-inspector";
async function compileSFCTemplate({ code, id, type }) {
const s = new MagicString(code);
const relativePath = normalizePath(path.relative(process.cwd(), id));
const result = await new Promise((resolve) => {
switch (type) {
case "template": {
const ast = vueParse(code, { comments: true });
vueTransform(ast, {
nodeTransforms: [
(node) => {
if (node.type === 1) {
if ((node.tagType === 0 || node.tagType === 1) && !EXCLUDE_TAG.includes(node.tag)) {
if (node.loc.source.includes(KEY_DATA))
return;
const insertPosition = node.props.length ? Math.max(...node.props.map((i) => i.loc.end.offset)) : node.loc.start.offset + node.tag.length + 1;
const { line, column } = node.loc.start;
const content = ` ${KEY_DATA}="${relativePath}:${line}:${column}"`;
s.prependLeft(
insertPosition,
content
);
}
}
}
]
});
break;
}
case "jsx": {
const ast = babelParse(code, {
babelrc: false,
configFile: false,
comments: true,
plugins: [
importMeta,
[vueJsxPlugin, {}],
[
typescriptPlugin,
{ isTSX: true, allowExtensions: true }
],
[
decoratorsPlugin,
{ legacy: true }
],
[
importAttributesPlugin,
{ deprecatedAssertSyntax: true }
]
]
});
babelTraverse(ast, {
enter({ node }) {
if (node.type === "JSXElement" && !EXCLUDE_TAG.includes(s.slice(node.openingElement.name.start, node.openingElement.name.end))) {
if (node.openingElement.attributes.some(
(attr) => attr.type !== "JSXSpreadAttribute" && attr.name.name === KEY_DATA
))
return;
const insertPosition = node.openingElement.end - (node.openingElement.selfClosing ? 2 : 1);
const { line, column } = node.loc.start;
const content = ` ${KEY_DATA}="${relativePath}:${line}:${column}"`;
s.prependLeft(
insertPosition,
content
);
}
}
});
break;
}
default:
break;
}
resolve(s.toString());
});
return result;
}
// src/utils/index.ts
function parseVueRequest(id) {
const [filename] = id.split("?", 2);
const url = new URL(id, "http://domain.inspector");
const query = Object.fromEntries(url.searchParams.entries());
if (query.vue != null)
query.vue = true;
if (query.src != null)
query.src = true;
if (query.index != null)
query.index = Number(query.index);
if (query.raw != null)
query.raw = true;
if (query.hasOwnProperty("lang.tsx") || query.hasOwnProperty("lang.jsx"))
query.isJsx = true;
return {
filename,
query
};
}
var FS_PREFIX = "/@fs/";
var IS_WINDOWS = process.platform === "win32";
var queryRE = /\?.*$/s;
var hashRE = /#.*$/s;
function idToFile(id) {
if (id.startsWith(FS_PREFIX))
id = id = id.slice(IS_WINDOWS ? FS_PREFIX.length : FS_PREFIX.length - 1);
return id.replace(hashRE, "").replace(queryRE, "");
}
// src/index.ts
var toggleComboKeysMap = {
control: process2.platform === "darwin" ? "Control(^)" : "Ctrl(^)",
meta: "Command(\u2318)",
shift: "Shift(\u21E7)"
};
function getInspectorPath() {
const pluginPath = normalizePath2(path2.dirname(fileURLToPath(import.meta.url)));
return pluginPath.replace(/\/dist$/, "/src");
}
function normalizeComboKeyPrint(toggleComboKey) {
return toggleComboKey.split("-").map((key) => toggleComboKeysMap[key] || key[0].toUpperCase() + key.slice(1)).join(dim("+"));
}
var DEFAULT_INSPECTOR_OPTIONS = {
vue: 3,
enabled: false,
toggleComboKey: process2.platform === "darwin" ? "meta-shift" : "control-shift",
toggleButtonVisibility: "active",
toggleButtonPos: "top-right",
appendTo: "",
lazyLoad: false,
launchEditor: process2.env.LAUNCH_EDITOR ?? "code",
reduceMotion: false
};
function VitePluginInspector(options = DEFAULT_INSPECTOR_OPTIONS) {
const inspectorPath = getInspectorPath();
const normalizedOptions = {
...DEFAULT_INSPECTOR_OPTIONS,
...options
};
let config;
const {
vue,
appendTo,
cleanHtml = vue === 3
// Only enabled for Vue 3 by default
} = normalizedOptions;
if (normalizedOptions.launchEditor)
process2.env.LAUNCH_EDITOR = normalizedOptions.launchEditor;
return [
{
name: "vite-plugin-vue-inspector",
enforce: "pre",
apply(_, { command }) {
return command === "serve" && process2.env.NODE_ENV !== "test";
},
async resolveId(importee) {
if (importee.startsWith("virtual:vue-inspector-options")) {
return importee;
} else if (importee.startsWith("virtual:vue-inspector-path:")) {
const resolved = importee.replace("virtual:vue-inspector-path:", `${inspectorPath}/`);
return resolved;
}
},
async load(id) {
if (id === "virtual:vue-inspector-options") {
return `export default ${JSON.stringify({ ...normalizedOptions, base: config.base })}`;
} else if (id.startsWith(inspectorPath)) {
const { query } = parseVueRequest(id);
if (query.type)
return;
const file = idToFile(id);
if (fs.existsSync(file))
return await fs.promises.readFile(file, "utf-8");
else
console.error(`failed to find file for vue-inspector: ${file}, referenced by id ${id}.`);
}
},
transform(code, id) {
const { filename, query } = parseVueRequest(id);
const isJsx = filename.endsWith(".jsx") || filename.endsWith(".tsx") || filename.endsWith(".vue") && query.isJsx;
const isTpl = filename.endsWith(".vue") && query.type !== "style" && !query.raw;
if (isJsx || isTpl)
return compileSFCTemplate({ code, id: filename, type: isJsx ? "jsx" : "template" });
if (!appendTo)
return;
if (typeof appendTo === "string" && filename.endsWith(appendTo) || appendTo instanceof RegExp && appendTo.test(filename))
return { code: `${code}
import 'virtual:vue-inspector-path:load.js'` };
},
configureServer(server) {
const _printUrls = server.printUrls;
const { toggleComboKey } = normalizedOptions;
toggleComboKey && (server.printUrls = () => {
const keys = normalizeComboKeyPrint(toggleComboKey);
_printUrls();
console.log(` ${green("\u279C")} ${bold("Vue Inspector")}: ${green(`Press ${yellow(keys)} in App to toggle the Inspector`)}
`);
});
},
transformIndexHtml(html) {
if (appendTo)
return;
return {
html,
tags: [
{
tag: "script",
injectTo: "head",
attrs: {
type: "module",
src: `${config.base || "/"}@id/virtual:vue-inspector-path:load.js`
}
}
]
};
},
configResolved(resolvedConfig) {
config = resolvedConfig;
}
},
{
name: "vite-plugin-vue-inspector:post",
enforce: "post",
apply(_, { command }) {
return cleanHtml && vue === 3 && command === "serve" && process2.env.NODE_ENV !== "test";
},
transform(code) {
if (code.includes("_interopVNode"))
return;
if (!code.includes("data-v-inspector"))
return;
const fn = /* @__PURE__ */ new Set();
const s = new MagicString2(code);
s.replace(/(createElementVNode|createVNode|createElementBlock|createBlock) as _\1,?/g, (_, name) => {
fn.add(name);
return "";
});
if (!fn.size)
return;
s.appendLeft(0, `/* Injection by vite-plugin-vue-inspector Start */
import { ${Array.from(fn.values()).map((i) => `${i} as __${i}`).join(",")} } from 'vue'
function _interopVNode(vnode) {
if (vnode && vnode.props && 'data-v-inspector' in vnode.props) {
const data = vnode.props['data-v-inspector']
delete vnode.props['data-v-inspector']
Object.defineProperty(vnode.props, '__v_inspector', { value: data, enumerable: false })
}
return vnode
}
${Array.from(fn.values()).map((i) => `function _${i}(...args) { return _interopVNode(__${i}(...args)) }`).join("\n")}
/* Injection by vite-plugin-vue-inspector End */
`);
return {
code: s.toString(),
map: s.generateMap({ hires: "boundary" })
};
}
}
];
}
var src_default = VitePluginInspector;
export {
DEFAULT_INSPECTOR_OPTIONS,
src_default as default,
normalizeComboKeyPrint
};

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-present vuejs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,5 @@
# @vue/babel-helper-vue-transform-on
A package used internally by vue jsx transformer to transform events.
on: { click: xx } --> onClick: xx

View File

@@ -0,0 +1,4 @@
declare function transformOn(
obj: Record<string, any>
): Record<`on${string}`, any>;
export = transformOn;

View File

@@ -0,0 +1,9 @@
const transformOn = (obj) => {
const result = {};
Object.keys(obj).forEach((evt) => {
result[`on${evt[0].toUpperCase()}${evt.slice(1)}`] = obj[evt];
});
return result;
};
module.exports = transformOn;

View File

@@ -0,0 +1,14 @@
{
"name": "@vue/babel-helper-vue-transform-on",
"version": "1.5.0",
"type": "commonjs",
"description": "to help transform on",
"author": "Amour1688 <lcz_1996@foxmail.com>",
"license": "MIT",
"main": "index.js",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/babel-plugin-jsx.git"
}
}

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-present vuejs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,390 @@
# Babel Plugin JSX for Vue 3
[![npm package](https://img.shields.io/npm/v/@vue/babel-plugin-jsx.svg?style=flat-square)](https://www.npmjs.com/package/@vue/babel-plugin-jsx)
[![issues-helper](https://img.shields.io/badge/Issues%20Manage%20By-issues--helper-blueviolet?style=flat-square)](https://github.com/actions-cool/issues-helper)
To add Vue JSX support.
English | [简体中文](/packages/babel-plugin-jsx/README-zh_CN.md)
## Installation
Install the plugin with:
```bash
npm install @vue/babel-plugin-jsx -D
```
Then add the plugin to your babel config:
```json
{
"plugins": ["@vue/babel-plugin-jsx"]
}
```
## Usage
### options
#### transformOn
Type: `boolean`
Default: `false`
transform `on: { click: xx }` to `onClick: xxx`
#### optimize
Type: `boolean`
Default: `false`
When enabled, this plugin generates optimized runtime code using [`PatchFlags`](https://vuejs.org/guide/extras/rendering-mechanism#patch-flags) and [`SlotFlags`](https://github.com/vuejs/core/blob/v3.5.13/packages/runtime-core/src/componentSlots.ts#L69-L77) to improve rendering performance. However, due to JSX's dynamic nature, the optimizations are not as comprehensive as those in Vue's official template compiler.
Since the optimized code may skip certain re-renders to improve performance, we strongly recommend thorough testing of your application after enabling this option to ensure everything works as expected.
#### isCustomElement
Type: `(tag: string) => boolean`
Default: `undefined`
configuring custom elements
#### mergeProps
Type: `boolean`
Default: `true`
merge static and dynamic class / style attributes / onXXX handlers
#### enableObjectSlots
Type: `boolean`
Default: `true`
Whether to enable `object slots` (mentioned below the document) syntax". It might be useful in JSX, but it will add a lot of `_isSlot` condition expressions which increase your bundle size. And `v-slots` is still available even if `enableObjectSlots` is turned off.
#### pragma
Type: `string`
Default: `createVNode`
Replace the function used when compiling JSX expressions.
#### resolveType
Type: `boolean`
Default: `false`
(**Experimental**) Infer component metadata from types (e.g. `props`, `emits`, `name`). This is an experimental feature and may not work in all cases.
## Syntax
### Content
functional component
```jsx
const App = () => <div>Vue 3.0</div>;
```
with render
```jsx
const App = {
render() {
return <div>Vue 3.0</div>;
},
};
```
```jsx
import { withModifiers, defineComponent } from 'vue';
const App = defineComponent({
setup() {
const count = ref(0);
const inc = () => {
count.value++;
};
return () => (
<div onClick={withModifiers(inc, ['self'])}>{count.value}</div>
);
},
});
```
Fragment
```jsx
const App = () => (
<>
<span>I'm</span>
<span>Fragment</span>
</>
);
```
### Attributes / Props
```jsx
const App = () => <input type="email" />;
```
with a dynamic binding:
```jsx
const placeholderText = 'email';
const App = () => <input type="email" placeholder={placeholderText} />;
```
### Directives
#### v-show
```jsx
const App = {
data() {
return { visible: true };
},
render() {
return <input v-show={this.visible} />;
},
};
```
#### v-model
> Note: You should pass the second param as string for using `arg`.
```jsx
<input v-model={val} />
```
```jsx
<input v-model:argument={val} />
```
```jsx
<input v-model={[val, ['modifier']]} />
// Or
<input v-model_modifier={val} />
```
```jsx
<A v-model={[val, 'argument', ['modifier']]} />
// Or
<input v-model:argument_modifier={val} />
```
Will compile to:
```js
h(A, {
argument: val,
argumentModifiers: {
modifier: true,
},
'onUpdate:argument': ($event) => (val = $event),
});
```
#### v-models (Not recommended since v1.1.0)
> Note: You should pass a Two-dimensional Arrays to v-models.
```jsx
<A v-models={[[foo], [bar, 'bar']]} />
```
```jsx
<A
v-models={[
[foo, 'foo'],
[bar, 'bar'],
]}
/>
```
```jsx
<A
v-models={[
[foo, ['modifier']],
[bar, 'bar', ['modifier']],
]}
/>
```
Will compile to:
```js
h(A, {
modelValue: foo,
modelModifiers: {
modifier: true,
},
'onUpdate:modelValue': ($event) => (foo = $event),
bar: bar,
barModifiers: {
modifier: true,
},
'onUpdate:bar': ($event) => (bar = $event),
});
```
#### custom directive
Recommended when using string arguments
```jsx
const App = {
directives: { custom: customDirective },
setup() {
return () => <a v-custom:arg={val} />;
},
};
```
```jsx
const App = {
directives: { custom: customDirective },
setup() {
return () => <a v-custom={[val, 'arg', ['a', 'b']]} />;
},
};
```
### Slot
> Note: In `jsx`, _`v-slot`_ should be replaced with **`v-slots`**
```jsx
const A = (props, { slots }) => (
<>
<h1>{slots.default ? slots.default() : 'foo'}</h1>
<h2>{slots.bar?.()}</h2>
</>
);
const App = {
setup() {
const slots = {
bar: () => <span>B</span>,
};
return () => (
<A v-slots={slots}>
<div>A</div>
</A>
);
},
};
// or
const App = {
setup() {
const slots = {
default: () => <div>A</div>,
bar: () => <span>B</span>,
};
return () => <A v-slots={slots} />;
},
};
// or you can use object slots when `enableObjectSlots` is not false.
const App = {
setup() {
return () => (
<>
<A>
{{
default: () => <div>A</div>,
bar: () => <span>B</span>,
}}
</A>
<B>{() => 'foo'}</B>
</>
);
},
};
```
### In TypeScript
`tsconfig.json`:
```json
{
"compilerOptions": {
"jsx": "preserve"
}
}
```
## Who is using
<table>
<tbody>
<tr>
<td align="center">
<a target="_blank" href="https://www.antdv.com/">
<img
width="32"
src="https://github.com/vuejs/babel-plugin-jsx/assets/6481596/8d604d42-fe5f-4450-af87-97999537cd21"
/>
<br>
<strong>Ant Design Vue</strong>
</a>
</td>
<td align="center">
<a target="_blank" href="https://youzan.github.io/vant/#/zh-CN/">
<img
width="32"
style="vertical-align: -0.32em; margin-right: 8px;"
src="https://img.yzcdn.cn/vant/logo.png"
/>
<br>
<strong>Vant</strong>
</a>
</td>
<td align="center">
<a target="_blank" href="https://github.com/element-plus/element-plus">
<img
height="32"
style="vertical-align: -0.32em; margin-right: 8px;"
src="https://user-images.githubusercontent.com/10731096/91267529-259f3680-e7a6-11ea-9a60-3286f750de01.png"
/>
<br>
<strong>Element Plus</strong>
</a>
</td>
<td align="center">
<a target="_blank" href="https://github.com/leezng/vue-json-pretty">
<img
height="32"
style="vertical-align: -0.32em; margin-right: 8px;"
src="https://raw.githubusercontent.com/leezng/vue-json-pretty/master/static/logo.svg"
/>
<br>
<strong>Vue Json Pretty</strong>
</a>
</td>
</tr>
</tbody>
</table>
## Compatibility
This repo is only compatible with:
- **Babel 7+**
- **Vue 3+**

View File

@@ -0,0 +1,35 @@
import "@babel/types";
import { Options } from "@vue/babel-plugin-resolve-type";
import * as BabelCore from "@babel/core";
//#region src/interface.d.ts
type State = {
get: (name: string) => any;
set: (name: string, value: any) => any;
opts: VueJSXPluginOptions;
file: BabelCore.BabelFile;
};
interface VueJSXPluginOptions {
/** transform `on: { click: xx }` to `onClick: xxx` */
transformOn?: boolean;
/** enable optimization or not. */
optimize?: boolean;
/** merge static and dynamic class / style attributes / onXXX handlers */
mergeProps?: boolean;
/** configuring custom elements */
isCustomElement?: (tag: string) => boolean;
/** enable object slots syntax */
enableObjectSlots?: boolean;
/** Replace the function used when compiling JSX expressions */
pragma?: string;
/**
* (**Experimental**) Infer component metadata from types (e.g. `props`, `emits`, `name`)
* @default false
*/
resolveType?: Options | boolean;
}
//#endregion
//#region src/index.d.ts
declare const plugin: (api: object, options: VueJSXPluginOptions | null | undefined, dirname: string) => BabelCore.PluginObj<State>;
//#endregion
export { VueJSXPluginOptions, plugin as default };

View File

@@ -0,0 +1,34 @@
import * as BabelCore from "@babel/core";
import { Options } from "@vue/babel-plugin-resolve-type";
//#region src/interface.d.ts
type State = {
get: (name: string) => any;
set: (name: string, value: any) => any;
opts: VueJSXPluginOptions;
file: BabelCore.BabelFile;
};
interface VueJSXPluginOptions {
/** transform `on: { click: xx }` to `onClick: xxx` */
transformOn?: boolean;
/** enable optimization or not. */
optimize?: boolean;
/** merge static and dynamic class / style attributes / onXXX handlers */
mergeProps?: boolean;
/** configuring custom elements */
isCustomElement?: (tag: string) => boolean;
/** enable object slots syntax */
enableObjectSlots?: boolean;
/** Replace the function used when compiling JSX expressions */
pragma?: string;
/**
* (**Experimental**) Infer component metadata from types (e.g. `props`, `emits`, `name`)
* @default false
*/
resolveType?: Options | boolean;
}
//#endregion
//#region src/index.d.ts
declare const plugin: (api: object, options: VueJSXPluginOptions | null | undefined, dirname: string) => BabelCore.PluginObj<State>;
//#endregion
export { VueJSXPluginOptions, plugin as default };

View File

@@ -0,0 +1,818 @@
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
const __babel_types = __toESM(require("@babel/types"));
const __babel_template = __toESM(require("@babel/template"));
const __babel_plugin_syntax_jsx = __toESM(require("@babel/plugin-syntax-jsx"));
const __babel_helper_module_imports = __toESM(require("@babel/helper-module-imports"));
const __vue_babel_plugin_resolve_type = __toESM(require("@vue/babel-plugin-resolve-type"));
const __babel_helper_plugin_utils = __toESM(require("@babel/helper-plugin-utils"));
const __vue_shared = __toESM(require("@vue/shared"));
//#region src/slotFlags.ts
var SlotFlags = /* @__PURE__ */ function(SlotFlags$1) {
/**
* Stable slots that only reference slot props or context state. The slot
* can fully capture its own dependencies so when passed down the parent won't
* need to force the child to update.
*/
SlotFlags$1[SlotFlags$1["STABLE"] = 1] = "STABLE";
/**
* Slots that reference scope variables (v-for or an outer slot prop), or
* has conditional structure (v-if, v-for). The parent will need to force
* the child to update because the slot does not fully capture its dependencies.
*/
SlotFlags$1[SlotFlags$1["DYNAMIC"] = 2] = "DYNAMIC";
/**
* `<slot/>` being forwarded into a child component. Whether the parent needs
* to update the child is dependent on what kind of slots the parent itself
* received. This has to be refined at runtime, when the child's vnode
* is being created (in `normalizeChildren`)
*/
SlotFlags$1[SlotFlags$1["FORWARDED"] = 3] = "FORWARDED";
return SlotFlags$1;
}(SlotFlags || {});
var slotFlags_default = SlotFlags;
//#endregion
//#region src/utils.ts
const FRAGMENT = "Fragment";
const KEEP_ALIVE = "KeepAlive";
/**
* create Identifier
* @param path NodePath
* @param state
* @param name string
* @returns MemberExpression
*/
const createIdentifier = (state, name) => state.get(name)();
/**
* Checks if string is describing a directive
* @param src string
*/
const isDirective = (src) => src.startsWith("v-") || src.startsWith("v") && src.length >= 2 && src[1] >= "A" && src[1] <= "Z";
/**
* Should transformed to slots
* @param tag string
* @returns boolean
*/
const shouldTransformedToSlots = (tag) => !(tag.match(RegExp(`^_?${FRAGMENT}\\d*$`)) || tag === KEEP_ALIVE);
/**
* Check if a Node is a component
*
* @param t
* @param path JSXOpeningElement
* @returns boolean
*/
const checkIsComponent = (path, state) => {
var _state$opts$isCustomE, _state$opts;
const namePath = path.get("name");
if (namePath.isJSXMemberExpression()) return shouldTransformedToSlots(namePath.node.property.name);
const tag = namePath.node.name;
return !((_state$opts$isCustomE = (_state$opts = state.opts).isCustomElement) === null || _state$opts$isCustomE === void 0 ? void 0 : _state$opts$isCustomE.call(_state$opts, tag)) && shouldTransformedToSlots(tag) && !(0, __vue_shared.isHTMLTag)(tag) && !(0, __vue_shared.isSVGTag)(tag);
};
/**
* Transform JSXMemberExpression to MemberExpression
* @param path JSXMemberExpression
* @returns MemberExpression
*/
const transformJSXMemberExpression = (path) => {
const objectPath = path.node.object;
const propertyPath = path.node.property;
const transformedObject = __babel_types.isJSXMemberExpression(objectPath) ? transformJSXMemberExpression(path.get("object")) : __babel_types.isJSXIdentifier(objectPath) ? __babel_types.identifier(objectPath.name) : __babel_types.nullLiteral();
const transformedProperty = __babel_types.identifier(propertyPath.name);
return __babel_types.memberExpression(transformedObject, transformedProperty);
};
/**
* Get tag (first attribute for h) from JSXOpeningElement
* @param path JSXElement
* @param state State
* @returns Identifier | StringLiteral | MemberExpression | CallExpression
*/
const getTag = (path, state) => {
const namePath = path.get("openingElement").get("name");
if (namePath.isJSXIdentifier()) {
const { name } = namePath.node;
if (!(0, __vue_shared.isHTMLTag)(name) && !(0, __vue_shared.isSVGTag)(name)) {
var _state$opts$isCustomE2, _state$opts2;
return name === FRAGMENT ? createIdentifier(state, FRAGMENT) : path.scope.hasBinding(name) ? __babel_types.identifier(name) : ((_state$opts$isCustomE2 = (_state$opts2 = state.opts).isCustomElement) === null || _state$opts$isCustomE2 === void 0 ? void 0 : _state$opts$isCustomE2.call(_state$opts2, name)) ? __babel_types.stringLiteral(name) : __babel_types.callExpression(createIdentifier(state, "resolveComponent"), [__babel_types.stringLiteral(name)]);
}
return __babel_types.stringLiteral(name);
}
if (namePath.isJSXMemberExpression()) return transformJSXMemberExpression(namePath);
throw new Error(`getTag: ${namePath.type} is not supported`);
};
const getJSXAttributeName = (path) => {
const nameNode = path.node.name;
if (__babel_types.isJSXIdentifier(nameNode)) return nameNode.name;
return `${nameNode.namespace.name}:${nameNode.name.name}`;
};
/**
* Transform JSXText to StringLiteral
* @param path JSXText
* @returns StringLiteral | null
*/
const transformJSXText = (path) => {
const str = transformText(path.node.value);
return str !== "" ? __babel_types.stringLiteral(str) : null;
};
const transformText = (text) => {
const lines = text.split(/\r\n|\n|\r/);
let lastNonEmptyLine = 0;
for (let i = 0; i < lines.length; i++) if (lines[i].match(/[^ \t]/)) lastNonEmptyLine = i;
let str = "";
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const isFirstLine = i === 0;
const isLastLine = i === lines.length - 1;
const isLastNonEmptyLine = i === lastNonEmptyLine;
let trimmedLine = line.replace(/\t/g, " ");
if (!isFirstLine) trimmedLine = trimmedLine.replace(/^[ ]+/, "");
if (!isLastLine) trimmedLine = trimmedLine.replace(/[ ]+$/, "");
if (trimmedLine) {
if (!isLastNonEmptyLine) trimmedLine += " ";
str += trimmedLine;
}
}
return str;
};
/**
* Transform JSXExpressionContainer to Expression
* @param path JSXExpressionContainer
* @returns Expression
*/
const transformJSXExpressionContainer = (path) => path.get("expression").node;
/**
* Transform JSXSpreadChild
* @param path JSXSpreadChild
* @returns SpreadElement
*/
const transformJSXSpreadChild = (path) => __babel_types.spreadElement(path.get("expression").node);
const walksScope = (path, name, slotFlag) => {
if (path.scope.hasBinding(name) && path.parentPath) {
if (__babel_types.isJSXElement(path.parentPath.node)) path.parentPath.setData("slotFlag", slotFlag);
walksScope(path.parentPath, name, slotFlag);
}
};
const buildIIFE = (path, children) => {
const { parentPath } = path;
if (parentPath.isAssignmentExpression()) {
const { left } = parentPath.node;
if (__babel_types.isIdentifier(left)) return children.map((child) => {
if (__babel_types.isIdentifier(child) && child.name === left.name) {
const insertName = path.scope.generateUidIdentifier(child.name);
parentPath.insertBefore(__babel_types.variableDeclaration("const", [__babel_types.variableDeclarator(insertName, __babel_types.callExpression(__babel_types.functionExpression(null, [], __babel_types.blockStatement([__babel_types.returnStatement(child)])), []))]));
return insertName;
}
return child;
});
}
return children;
};
const onRE = /^on[^a-z]/;
const isOn = (key) => onRE.test(key);
const mergeAsArray = (existing, incoming) => {
if (__babel_types.isArrayExpression(existing.value)) existing.value.elements.push(incoming.value);
else existing.value = __babel_types.arrayExpression([existing.value, incoming.value]);
};
const dedupeProperties = (properties = [], mergeProps) => {
if (!mergeProps) return properties;
const knownProps = /* @__PURE__ */ new Map();
const deduped = [];
properties.forEach((prop) => {
if (__babel_types.isStringLiteral(prop.key)) {
const { value: name } = prop.key;
const existing = knownProps.get(name);
if (existing) {
if (name === "style" || name === "class" || name.startsWith("on")) mergeAsArray(existing, prop);
} else {
knownProps.set(name, prop);
deduped.push(prop);
}
} else deduped.push(prop);
});
return deduped;
};
/**
* Check if an attribute value is constant
* @param node
* @returns boolean
*/
const isConstant = (node) => {
if (__babel_types.isIdentifier(node)) return node.name === "undefined";
if (__babel_types.isArrayExpression(node)) {
const { elements } = node;
return elements.every((element) => element && isConstant(element));
}
if (__babel_types.isObjectExpression(node)) return node.properties.every((property) => isConstant(property.value));
if (__babel_types.isTemplateLiteral(node) ? !node.expressions.length : __babel_types.isLiteral(node)) return true;
return false;
};
const transformJSXSpreadAttribute = (nodePath, path, mergeProps, args) => {
const argument = path.get("argument");
const properties = __babel_types.isObjectExpression(argument.node) ? argument.node.properties : void 0;
if (!properties) {
if (argument.isIdentifier()) walksScope(nodePath, argument.node.name, slotFlags_default.DYNAMIC);
args.push(mergeProps ? argument.node : __babel_types.spreadElement(argument.node));
} else if (mergeProps) args.push(__babel_types.objectExpression(properties));
else args.push(...properties);
};
//#endregion
//#region src/patchFlags.ts
let PatchFlags = /* @__PURE__ */ function(PatchFlags$1) {
PatchFlags$1[PatchFlags$1["TEXT"] = 1] = "TEXT";
PatchFlags$1[PatchFlags$1["CLASS"] = 2] = "CLASS";
PatchFlags$1[PatchFlags$1["STYLE"] = 4] = "STYLE";
PatchFlags$1[PatchFlags$1["PROPS"] = 8] = "PROPS";
PatchFlags$1[PatchFlags$1["FULL_PROPS"] = 16] = "FULL_PROPS";
PatchFlags$1[PatchFlags$1["HYDRATE_EVENTS"] = 32] = "HYDRATE_EVENTS";
PatchFlags$1[PatchFlags$1["STABLE_FRAGMENT"] = 64] = "STABLE_FRAGMENT";
PatchFlags$1[PatchFlags$1["KEYED_FRAGMENT"] = 128] = "KEYED_FRAGMENT";
PatchFlags$1[PatchFlags$1["UNKEYED_FRAGMENT"] = 256] = "UNKEYED_FRAGMENT";
PatchFlags$1[PatchFlags$1["NEED_PATCH"] = 512] = "NEED_PATCH";
PatchFlags$1[PatchFlags$1["DYNAMIC_SLOTS"] = 1024] = "DYNAMIC_SLOTS";
PatchFlags$1[PatchFlags$1["HOISTED"] = -1] = "HOISTED";
PatchFlags$1[PatchFlags$1["BAIL"] = -2] = "BAIL";
return PatchFlags$1;
}({});
const PatchFlagNames = {
[PatchFlags.TEXT]: "TEXT",
[PatchFlags.CLASS]: "CLASS",
[PatchFlags.STYLE]: "STYLE",
[PatchFlags.PROPS]: "PROPS",
[PatchFlags.FULL_PROPS]: "FULL_PROPS",
[PatchFlags.HYDRATE_EVENTS]: "HYDRATE_EVENTS",
[PatchFlags.STABLE_FRAGMENT]: "STABLE_FRAGMENT",
[PatchFlags.KEYED_FRAGMENT]: "KEYED_FRAGMENT",
[PatchFlags.UNKEYED_FRAGMENT]: "UNKEYED_FRAGMENT",
[PatchFlags.DYNAMIC_SLOTS]: "DYNAMIC_SLOTS",
[PatchFlags.NEED_PATCH]: "NEED_PATCH",
[PatchFlags.HOISTED]: "HOISTED",
[PatchFlags.BAIL]: "BAIL"
};
//#endregion
//#region src/parseDirectives.ts
/**
* Get JSX element type
*
* @param path Path<JSXOpeningElement>
*/
const getType = (path) => {
const typePath = path.get("attributes").find((attribute) => {
if (!attribute.isJSXAttribute()) return false;
return attribute.get("name").isJSXIdentifier() && attribute.get("name").node.name === "type";
});
return typePath ? typePath.get("value").node : null;
};
const parseModifiers = (value) => __babel_types.isArrayExpression(value) ? value.elements.map((el) => __babel_types.isStringLiteral(el) ? el.value : "").filter(Boolean) : [];
const parseDirectives = (params) => {
var _modifiersSet$, _modifiersSet$2;
const { path, value, state, tag, isComponent } = params;
const args = [];
const vals = [];
const modifiersSet = [];
let directiveName;
let directiveArgument;
let directiveModifiers;
if ("namespace" in path.node.name) {
[directiveName, directiveArgument] = params.name.split(":");
directiveName = path.node.name.namespace.name;
directiveArgument = path.node.name.name.name;
directiveModifiers = directiveArgument.split("_").slice(1);
} else {
const underscoreModifiers = params.name.split("_");
directiveName = underscoreModifiers.shift() || "";
directiveModifiers = underscoreModifiers;
}
directiveName = directiveName.replace(/^v/, "").replace(/^-/, "").replace(/^\S/, (s) => s.toLowerCase());
if (directiveArgument) args.push(__babel_types.stringLiteral(directiveArgument.split("_")[0]));
const isVModels = directiveName === "models";
const isVModel = directiveName === "model";
if (isVModel && !path.get("value").isJSXExpressionContainer()) throw new Error("You have to use JSX Expression inside your v-model");
if (isVModels && !isComponent) throw new Error("v-models can only use in custom components");
const shouldResolve = ![
"html",
"text",
"model",
"slots",
"models"
].includes(directiveName) || isVModel && !isComponent;
let modifiers = directiveModifiers;
if (__babel_types.isArrayExpression(value)) {
const elementsList = isVModels ? value.elements : [value];
elementsList.forEach((element) => {
if (isVModels && !__babel_types.isArrayExpression(element)) throw new Error("You should pass a Two-dimensional Arrays to v-models");
const { elements } = element;
const [first, second, third] = elements;
if (second && !__babel_types.isArrayExpression(second) && !__babel_types.isSpreadElement(second)) {
args.push(second);
modifiers = parseModifiers(third);
} else if (__babel_types.isArrayExpression(second)) {
if (!shouldResolve) args.push(__babel_types.nullLiteral());
modifiers = parseModifiers(second);
} else if (!shouldResolve) args.push(__babel_types.nullLiteral());
modifiersSet.push(new Set(modifiers));
vals.push(first);
});
} else if (isVModel && !shouldResolve) {
args.push(__babel_types.nullLiteral());
modifiersSet.push(new Set(directiveModifiers));
} else modifiersSet.push(new Set(directiveModifiers));
return {
directiveName,
modifiers: modifiersSet,
values: vals.length ? vals : [value],
args,
directive: shouldResolve ? [
resolveDirective(path, state, tag, directiveName),
vals[0] || value,
((_modifiersSet$ = modifiersSet[0]) === null || _modifiersSet$ === void 0 ? void 0 : _modifiersSet$.size) ? args[0] || __babel_types.unaryExpression("void", __babel_types.numericLiteral(0), true) : args[0],
!!((_modifiersSet$2 = modifiersSet[0]) === null || _modifiersSet$2 === void 0 ? void 0 : _modifiersSet$2.size) && __babel_types.objectExpression([...modifiersSet[0]].map((modifier) => __babel_types.objectProperty(__babel_types.identifier(modifier), __babel_types.booleanLiteral(true))))
].filter(Boolean) : void 0
};
};
const resolveDirective = (path, state, tag, directiveName) => {
if (directiveName === "show") return createIdentifier(state, "vShow");
if (directiveName === "model") {
let modelToUse;
const type = getType(path.parentPath);
switch (tag.value) {
case "select":
modelToUse = createIdentifier(state, "vModelSelect");
break;
case "textarea":
modelToUse = createIdentifier(state, "vModelText");
break;
default: if (__babel_types.isStringLiteral(type) || !type) switch (type === null || type === void 0 ? void 0 : type.value) {
case "checkbox":
modelToUse = createIdentifier(state, "vModelCheckbox");
break;
case "radio":
modelToUse = createIdentifier(state, "vModelRadio");
break;
default: modelToUse = createIdentifier(state, "vModelText");
}
else modelToUse = createIdentifier(state, "vModelDynamic");
}
return modelToUse;
}
const referenceName = "v" + directiveName[0].toUpperCase() + directiveName.slice(1);
if (path.scope.references[referenceName]) return __babel_types.identifier(referenceName);
return __babel_types.callExpression(createIdentifier(state, "resolveDirective"), [__babel_types.stringLiteral(directiveName)]);
};
var parseDirectives_default = parseDirectives;
//#endregion
//#region src/transform-vue-jsx.ts
const xlinkRE = new RegExp("^xlink([A-Z])", "");
const getJSXAttributeValue = (path, state) => {
const valuePath = path.get("value");
if (valuePath.isJSXElement()) return transformJSXElement(valuePath, state);
if (valuePath.isStringLiteral()) return __babel_types.stringLiteral(transformText(valuePath.node.value));
if (valuePath.isJSXExpressionContainer()) return transformJSXExpressionContainer(valuePath);
return null;
};
const buildProps = (path, state) => {
const tag = getTag(path, state);
const isComponent = checkIsComponent(path.get("openingElement"), state);
const props = path.get("openingElement").get("attributes");
const directives = [];
const dynamicPropNames = /* @__PURE__ */ new Set();
let slots = null;
let patchFlag = 0;
if (props.length === 0) return {
tag,
isComponent,
slots,
props: __babel_types.nullLiteral(),
directives,
patchFlag,
dynamicPropNames
};
let properties = [];
let hasRef = false;
let hasClassBinding = false;
let hasStyleBinding = false;
let hasHydrationEventBinding = false;
let hasDynamicKeys = false;
const mergeArgs = [];
const { mergeProps = true } = state.opts;
props.forEach((prop) => {
if (prop.isJSXAttribute()) {
let name = getJSXAttributeName(prop);
const attributeValue = getJSXAttributeValue(prop, state);
if (!isConstant(attributeValue) || name === "ref") {
if (!isComponent && isOn(name) && name.toLowerCase() !== "onclick" && name !== "onUpdate:modelValue") hasHydrationEventBinding = true;
if (name === "ref") hasRef = true;
else if (name === "class" && !isComponent) hasClassBinding = true;
else if (name === "style" && !isComponent) hasStyleBinding = true;
else if (name !== "key" && !isDirective(name) && name !== "on") dynamicPropNames.add(name);
}
if (state.opts.transformOn && (name === "on" || name === "nativeOn")) {
if (!state.get("transformOn")) state.set("transformOn", (0, __babel_helper_module_imports.addDefault)(path, "@vue/babel-helper-vue-transform-on", { nameHint: "_transformOn" }));
mergeArgs.push(__babel_types.callExpression(state.get("transformOn"), [attributeValue || __babel_types.booleanLiteral(true)]));
return;
}
if (isDirective(name)) {
const { directive, modifiers, values, args, directiveName } = parseDirectives_default({
tag,
isComponent,
name,
path: prop,
state,
value: attributeValue
});
if (directiveName === "slots") {
slots = attributeValue;
return;
}
if (directive) directives.push(__babel_types.arrayExpression(directive));
else if (directiveName === "html") {
properties.push(__babel_types.objectProperty(__babel_types.stringLiteral("innerHTML"), values[0]));
dynamicPropNames.add("innerHTML");
} else if (directiveName === "text") {
properties.push(__babel_types.objectProperty(__babel_types.stringLiteral("textContent"), values[0]));
dynamicPropNames.add("textContent");
}
if (["models", "model"].includes(directiveName)) values.forEach((value, index) => {
const propName = args[index];
const isDynamic = propName && !__babel_types.isStringLiteral(propName) && !__babel_types.isNullLiteral(propName);
if (!directive) {
var _modifiers$index;
properties.push(__babel_types.objectProperty(__babel_types.isNullLiteral(propName) ? __babel_types.stringLiteral("modelValue") : propName, value, isDynamic));
if (!isDynamic) dynamicPropNames.add((propName === null || propName === void 0 ? void 0 : propName.value) || "modelValue");
if ((_modifiers$index = modifiers[index]) === null || _modifiers$index === void 0 ? void 0 : _modifiers$index.size) properties.push(__babel_types.objectProperty(isDynamic ? __babel_types.binaryExpression("+", propName, __babel_types.stringLiteral("Modifiers")) : __babel_types.stringLiteral(`${(propName === null || propName === void 0 ? void 0 : propName.value) || "model"}Modifiers`), __babel_types.objectExpression([...modifiers[index]].map((modifier) => __babel_types.objectProperty(__babel_types.stringLiteral(modifier), __babel_types.booleanLiteral(true)))), isDynamic));
}
const updateName = isDynamic ? __babel_types.binaryExpression("+", __babel_types.stringLiteral("onUpdate:"), propName) : __babel_types.stringLiteral(`onUpdate:${(propName === null || propName === void 0 ? void 0 : propName.value) || "modelValue"}`);
properties.push(__babel_types.objectProperty(updateName, __babel_types.arrowFunctionExpression([__babel_types.identifier("$event")], __babel_types.assignmentExpression("=", value, __babel_types.identifier("$event"))), isDynamic));
if (!isDynamic) dynamicPropNames.add(updateName.value);
else hasDynamicKeys = true;
});
} else {
if (name.match(xlinkRE)) name = name.replace(xlinkRE, (_, firstCharacter) => `xlink:${firstCharacter.toLowerCase()}`);
properties.push(__babel_types.objectProperty(__babel_types.stringLiteral(name), attributeValue || __babel_types.booleanLiteral(true)));
}
} else {
if (properties.length && mergeProps) {
mergeArgs.push(__babel_types.objectExpression(dedupeProperties(properties, mergeProps)));
properties = [];
}
hasDynamicKeys = true;
transformJSXSpreadAttribute(path, prop, mergeProps, mergeProps ? mergeArgs : properties);
}
});
if (hasDynamicKeys) patchFlag |= PatchFlags.FULL_PROPS;
else {
if (hasClassBinding) patchFlag |= PatchFlags.CLASS;
if (hasStyleBinding) patchFlag |= PatchFlags.STYLE;
if (dynamicPropNames.size) patchFlag |= PatchFlags.PROPS;
if (hasHydrationEventBinding) patchFlag |= PatchFlags.HYDRATE_EVENTS;
}
if ((patchFlag === 0 || patchFlag === PatchFlags.HYDRATE_EVENTS) && (hasRef || directives.length > 0)) patchFlag |= PatchFlags.NEED_PATCH;
let propsExpression = __babel_types.nullLiteral();
if (mergeArgs.length) {
if (properties.length) mergeArgs.push(__babel_types.objectExpression(dedupeProperties(properties, mergeProps)));
if (mergeArgs.length > 1) propsExpression = __babel_types.callExpression(createIdentifier(state, "mergeProps"), mergeArgs);
else propsExpression = mergeArgs[0];
} else if (properties.length) if (properties.length === 1 && __babel_types.isSpreadElement(properties[0])) propsExpression = properties[0].argument;
else propsExpression = __babel_types.objectExpression(dedupeProperties(properties, mergeProps));
return {
tag,
props: propsExpression,
isComponent,
slots,
directives,
patchFlag,
dynamicPropNames
};
};
/**
* Get children from Array of JSX children
* @param paths Array<JSXText | JSXExpressionContainer | JSXElement | JSXFragment>
* @returns Array<Expression | SpreadElement>
*/
const getChildren = (paths, state) => paths.map((path) => {
if (path.isJSXText()) {
const transformedText = transformJSXText(path);
if (transformedText) return __babel_types.callExpression(createIdentifier(state, "createTextVNode"), [transformedText]);
return transformedText;
}
if (path.isJSXExpressionContainer()) {
const expression = transformJSXExpressionContainer(path);
if (__babel_types.isIdentifier(expression)) {
const { name } = expression;
const { referencePaths = [] } = path.scope.getBinding(name) || {};
referencePaths.forEach((referencePath) => {
walksScope(referencePath, name, slotFlags_default.DYNAMIC);
});
}
return expression;
}
if (path.isJSXSpreadChild()) return transformJSXSpreadChild(path);
if (path.isCallExpression()) return path.node;
if (path.isJSXElement()) return transformJSXElement(path, state);
throw new Error(`getChildren: ${path.type} is not supported`);
}).filter(((value) => value != null && !__babel_types.isJSXEmptyExpression(value)));
const transformJSXElement = (path, state) => {
var _path$getData;
const children = getChildren(path.get("children"), state);
const { tag, props, isComponent, directives, patchFlag, dynamicPropNames, slots } = buildProps(path, state);
const { optimize = false } = state.opts;
if (directives.length && directives.some((d) => {
var _d$elements;
return ((_d$elements = d.elements) === null || _d$elements === void 0 || (_d$elements = _d$elements[0]) === null || _d$elements === void 0 ? void 0 : _d$elements.type) === "CallExpression" && d.elements[0].callee.type === "Identifier" && d.elements[0].callee.name === "_resolveDirective";
})) {
var _currentPath$parentPa;
let currentPath = path;
while ((_currentPath$parentPa = currentPath.parentPath) === null || _currentPath$parentPa === void 0 ? void 0 : _currentPath$parentPa.isJSXElement()) {
currentPath = currentPath.parentPath;
currentPath.setData("slotFlag", 0);
}
}
const slotFlag = (_path$getData = path.getData("slotFlag")) !== null && _path$getData !== void 0 ? _path$getData : slotFlags_default.STABLE;
const optimizeSlots = optimize && slotFlag !== 0;
let VNodeChild;
if (children.length > 1 || slots) VNodeChild = isComponent ? children.length ? __babel_types.objectExpression([
!!children.length && __babel_types.objectProperty(__babel_types.identifier("default"), __babel_types.arrowFunctionExpression([], __babel_types.arrayExpression(buildIIFE(path, children)))),
...slots ? __babel_types.isObjectExpression(slots) ? slots.properties : [__babel_types.spreadElement(slots)] : [],
optimizeSlots && __babel_types.objectProperty(__babel_types.identifier("_"), __babel_types.numericLiteral(slotFlag))
].filter(Boolean)) : slots : __babel_types.arrayExpression(children);
else if (children.length === 1) {
const { enableObjectSlots = true } = state.opts;
const child = children[0];
const objectExpression = __babel_types.objectExpression([__babel_types.objectProperty(__babel_types.identifier("default"), __babel_types.arrowFunctionExpression([], __babel_types.arrayExpression(buildIIFE(path, [child])))), optimizeSlots && __babel_types.objectProperty(__babel_types.identifier("_"), __babel_types.numericLiteral(slotFlag))].filter(Boolean));
if (__babel_types.isIdentifier(child) && isComponent) VNodeChild = enableObjectSlots ? __babel_types.conditionalExpression(__babel_types.callExpression(state.get("@vue/babel-plugin-jsx/runtimeIsSlot")(), [child]), child, objectExpression) : objectExpression;
else if (__babel_types.isCallExpression(child) && child.loc && isComponent) if (enableObjectSlots) {
const { scope } = path;
const slotId = scope.generateUidIdentifier("slot");
if (scope) scope.push({
id: slotId,
kind: "let"
});
const alternate = __babel_types.objectExpression([__babel_types.objectProperty(__babel_types.identifier("default"), __babel_types.arrowFunctionExpression([], __babel_types.arrayExpression(buildIIFE(path, [slotId])))), optimizeSlots && __babel_types.objectProperty(__babel_types.identifier("_"), __babel_types.numericLiteral(slotFlag))].filter(Boolean));
const assignment = __babel_types.assignmentExpression("=", slotId, child);
const condition = __babel_types.callExpression(state.get("@vue/babel-plugin-jsx/runtimeIsSlot")(), [assignment]);
VNodeChild = __babel_types.conditionalExpression(condition, slotId, alternate);
} else VNodeChild = objectExpression;
else if (__babel_types.isFunctionExpression(child) || __babel_types.isArrowFunctionExpression(child)) VNodeChild = __babel_types.objectExpression([__babel_types.objectProperty(__babel_types.identifier("default"), child)]);
else if (__babel_types.isObjectExpression(child)) VNodeChild = __babel_types.objectExpression([...child.properties, optimizeSlots && __babel_types.objectProperty(__babel_types.identifier("_"), __babel_types.numericLiteral(slotFlag))].filter(Boolean));
else VNodeChild = isComponent ? __babel_types.objectExpression([__babel_types.objectProperty(__babel_types.identifier("default"), __babel_types.arrowFunctionExpression([], __babel_types.arrayExpression([child])))]) : __babel_types.arrayExpression([child]);
}
const createVNode = __babel_types.callExpression(createIdentifier(state, "createVNode"), [
tag,
props,
VNodeChild || __babel_types.nullLiteral(),
!!patchFlag && optimize && __babel_types.numericLiteral(patchFlag),
!!dynamicPropNames.size && optimize && __babel_types.arrayExpression([...dynamicPropNames.keys()].map((name) => __babel_types.stringLiteral(name)))
].filter(Boolean));
if (!directives.length) return createVNode;
return __babel_types.callExpression(createIdentifier(state, "withDirectives"), [createVNode, __babel_types.arrayExpression(directives)]);
};
const visitor$1 = { JSXElement: { exit(path, state) {
path.replaceWith(transformJSXElement(path, state));
} } };
var transform_vue_jsx_default = visitor$1;
//#endregion
//#region src/sugar-fragment.ts
const transformFragment = (path, Fragment) => {
const children = path.get("children") || [];
return __babel_types.jsxElement(__babel_types.jsxOpeningElement(Fragment, []), __babel_types.jsxClosingElement(Fragment), children.map(({ node }) => node), false);
};
const visitor = { JSXFragment: { enter(path, state) {
const fragmentCallee = createIdentifier(state, FRAGMENT);
path.replaceWith(transformFragment(path, __babel_types.isIdentifier(fragmentCallee) ? __babel_types.jsxIdentifier(fragmentCallee.name) : __babel_types.jsxMemberExpression(__babel_types.jsxIdentifier(fragmentCallee.object.name), __babel_types.jsxIdentifier(fragmentCallee.property.name))));
} } };
var sugar_fragment_default = visitor;
//#endregion
//#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/typeof.js
var require_typeof = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/typeof.js": ((exports, module) => {
function _typeof$2(o) {
"@babel/helpers - typeof";
return module.exports = _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
return typeof o$1;
} : function(o$1) {
return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
}, module.exports.__esModule = true, module.exports["default"] = module.exports, _typeof$2(o);
}
module.exports = _typeof$2, module.exports.__esModule = true, module.exports["default"] = module.exports;
}) });
//#endregion
//#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js
var require_toPrimitive = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js": ((exports, module) => {
var _typeof$1 = require_typeof()["default"];
function toPrimitive$1(t, r) {
if ("object" != _typeof$1(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof$1(i)) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
module.exports = toPrimitive$1, module.exports.__esModule = true, module.exports["default"] = module.exports;
}) });
//#endregion
//#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/toPropertyKey.js
var require_toPropertyKey = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/toPropertyKey.js": ((exports, module) => {
var _typeof = require_typeof()["default"];
var toPrimitive = require_toPrimitive();
function toPropertyKey$1(t) {
var i = toPrimitive(t, "string");
return "symbol" == _typeof(i) ? i : i + "";
}
module.exports = toPropertyKey$1, module.exports.__esModule = true, module.exports["default"] = module.exports;
}) });
//#endregion
//#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/defineProperty.js
var require_defineProperty = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/defineProperty.js": ((exports, module) => {
var toPropertyKey = require_toPropertyKey();
function _defineProperty(e, r, t) {
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: !0,
configurable: !0,
writable: !0
}) : e[r] = t, e;
}
module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports;
}) });
//#endregion
//#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/objectSpread2.js
var require_objectSpread2 = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/objectSpread2.js": ((exports, module) => {
var defineProperty = require_defineProperty();
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function(r$1) {
return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), !0).forEach(function(r$1) {
defineProperty(e, r$1, t[r$1]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r$1) {
Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t, r$1));
});
}
return e;
}
module.exports = _objectSpread2, module.exports.__esModule = true, module.exports["default"] = module.exports;
}) });
//#endregion
//#region src/index.ts
var import_objectSpread2 = /* @__PURE__ */ __toESM(require_objectSpread2());
const hasJSX = (parentPath) => {
let fileHasJSX = false;
parentPath.traverse({
JSXElement(path) {
fileHasJSX = true;
path.stop();
},
JSXFragment(path) {
fileHasJSX = true;
path.stop();
}
});
return fileHasJSX;
};
const JSX_ANNOTATION_REGEX = new RegExp("\\*?\\s*@jsx\\s+([^\\s]+)", "");
/* @__NO_SIDE_EFFECTS__ */
function interopDefault(m) {
return m.default || m;
}
const syntaxJsx = /* @__PURE__ */ interopDefault(__babel_plugin_syntax_jsx.default);
const template = /* @__PURE__ */ interopDefault(__babel_template.default);
const plugin = (0, __babel_helper_plugin_utils.declare)((api, opt, dirname) => {
const { types } = api;
let resolveType;
if (opt.resolveType) {
if (typeof opt.resolveType === "boolean") opt.resolveType = {};
resolveType = (0, __vue_babel_plugin_resolve_type.default)(api, opt.resolveType, dirname);
}
return (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolveType || {}), {}, {
name: "babel-plugin-jsx",
inherits: /* @__PURE__ */ interopDefault(syntaxJsx),
visitor: (0, import_objectSpread2.default)((0, import_objectSpread2.default)((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolveType === null || resolveType === void 0 ? void 0 : resolveType.visitor), transform_vue_jsx_default), sugar_fragment_default), {}, { Program: { enter(path, state) {
if (hasJSX(path)) {
const importNames = [
"createVNode",
"Fragment",
"resolveComponent",
"withDirectives",
"vShow",
"vModelSelect",
"vModelText",
"vModelCheckbox",
"vModelRadio",
"vModelText",
"vModelDynamic",
"resolveDirective",
"mergeProps",
"createTextVNode",
"isVNode"
];
if ((0, __babel_helper_module_imports.isModule)(path)) {
const importMap = {};
importNames.forEach((name) => {
state.set(name, () => {
if (importMap[name]) return types.cloneNode(importMap[name]);
const identifier = (0, __babel_helper_module_imports.addNamed)(path, name, "vue", { ensureLiveReference: true });
importMap[name] = identifier;
return identifier;
});
});
const { enableObjectSlots = true } = state.opts;
if (enableObjectSlots) state.set("@vue/babel-plugin-jsx/runtimeIsSlot", () => {
if (importMap.runtimeIsSlot) return importMap.runtimeIsSlot;
const { name: isVNodeName } = state.get("isVNode")();
const isSlot = path.scope.generateUidIdentifier("isSlot");
const ast = template.ast`
function ${isSlot.name}(s) {
return typeof s === 'function' || (Object.prototype.toString.call(s) === '[object Object]' && !${isVNodeName}(s));
}
`;
const lastImport = path.get("body").filter((p) => p.isImportDeclaration()).pop();
if (lastImport) lastImport.insertAfter(ast);
importMap.runtimeIsSlot = isSlot;
return isSlot;
});
} else {
let sourceName;
importNames.forEach((name) => {
state.set(name, () => {
if (!sourceName) sourceName = (0, __babel_helper_module_imports.addNamespace)(path, "vue", { ensureLiveReference: true });
return __babel_types.memberExpression(sourceName, __babel_types.identifier(name));
});
});
const helpers = {};
const { enableObjectSlots = true } = state.opts;
if (enableObjectSlots) state.set("@vue/babel-plugin-jsx/runtimeIsSlot", () => {
if (helpers.runtimeIsSlot) return helpers.runtimeIsSlot;
const isSlot = path.scope.generateUidIdentifier("isSlot");
const { object: objectName } = state.get("isVNode")();
const ast = template.ast`
function ${isSlot.name}(s) {
return typeof s === 'function' || (Object.prototype.toString.call(s) === '[object Object]' && !${objectName.name}.isVNode(s));
}
`;
const nodePaths = path.get("body");
const lastImport = nodePaths.filter((p) => p.isVariableDeclaration() && p.node.declarations.some((d) => {
var _d$id;
return ((_d$id = d.id) === null || _d$id === void 0 ? void 0 : _d$id.name) === sourceName.name;
})).pop();
if (lastImport) lastImport.insertAfter(ast);
return isSlot;
});
}
const { opts: { pragma = "" }, file } = state;
if (pragma) state.set("createVNode", () => __babel_types.identifier(pragma));
if (file.ast.comments) for (const comment of file.ast.comments) {
const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
if (jsxMatches) state.set("createVNode", () => __babel_types.identifier(jsxMatches[1]));
}
}
} } })
});
});
var src_default = plugin;
//#endregion
module.exports = src_default;

View File

@@ -0,0 +1,771 @@
import * as t from "@babel/types";
import _template from "@babel/template";
import _syntaxJsx from "@babel/plugin-syntax-jsx";
import { addDefault, addNamed, addNamespace, isModule } from "@babel/helper-module-imports";
import ResolveType from "@vue/babel-plugin-resolve-type";
import { declare } from "@babel/helper-plugin-utils";
import { isHTMLTag, isSVGTag } from "@vue/shared";
//#region src/slotFlags.ts
var SlotFlags = /* @__PURE__ */ function(SlotFlags$1) {
/**
* Stable slots that only reference slot props or context state. The slot
* can fully capture its own dependencies so when passed down the parent won't
* need to force the child to update.
*/
SlotFlags$1[SlotFlags$1["STABLE"] = 1] = "STABLE";
/**
* Slots that reference scope variables (v-for or an outer slot prop), or
* has conditional structure (v-if, v-for). The parent will need to force
* the child to update because the slot does not fully capture its dependencies.
*/
SlotFlags$1[SlotFlags$1["DYNAMIC"] = 2] = "DYNAMIC";
/**
* `<slot/>` being forwarded into a child component. Whether the parent needs
* to update the child is dependent on what kind of slots the parent itself
* received. This has to be refined at runtime, when the child's vnode
* is being created (in `normalizeChildren`)
*/
SlotFlags$1[SlotFlags$1["FORWARDED"] = 3] = "FORWARDED";
return SlotFlags$1;
}(SlotFlags || {});
var slotFlags_default = SlotFlags;
//#endregion
//#region src/utils.ts
const FRAGMENT = "Fragment";
const KEEP_ALIVE = "KeepAlive";
/**
* create Identifier
* @param path NodePath
* @param state
* @param name string
* @returns MemberExpression
*/
const createIdentifier = (state, name) => state.get(name)();
/**
* Checks if string is describing a directive
* @param src string
*/
const isDirective = (src) => src.startsWith("v-") || src.startsWith("v") && src.length >= 2 && src[1] >= "A" && src[1] <= "Z";
/**
* Should transformed to slots
* @param tag string
* @returns boolean
*/
const shouldTransformedToSlots = (tag) => !(tag.match(RegExp(`^_?${FRAGMENT}\\d*$`)) || tag === KEEP_ALIVE);
/**
* Check if a Node is a component
*
* @param t
* @param path JSXOpeningElement
* @returns boolean
*/
const checkIsComponent = (path, state) => {
var _state$opts$isCustomE, _state$opts;
const namePath = path.get("name");
if (namePath.isJSXMemberExpression()) return shouldTransformedToSlots(namePath.node.property.name);
const tag = namePath.node.name;
return !((_state$opts$isCustomE = (_state$opts = state.opts).isCustomElement) === null || _state$opts$isCustomE === void 0 ? void 0 : _state$opts$isCustomE.call(_state$opts, tag)) && shouldTransformedToSlots(tag) && !isHTMLTag(tag) && !isSVGTag(tag);
};
/**
* Transform JSXMemberExpression to MemberExpression
* @param path JSXMemberExpression
* @returns MemberExpression
*/
const transformJSXMemberExpression = (path) => {
const objectPath = path.node.object;
const propertyPath = path.node.property;
const transformedObject = t.isJSXMemberExpression(objectPath) ? transformJSXMemberExpression(path.get("object")) : t.isJSXIdentifier(objectPath) ? t.identifier(objectPath.name) : t.nullLiteral();
const transformedProperty = t.identifier(propertyPath.name);
return t.memberExpression(transformedObject, transformedProperty);
};
/**
* Get tag (first attribute for h) from JSXOpeningElement
* @param path JSXElement
* @param state State
* @returns Identifier | StringLiteral | MemberExpression | CallExpression
*/
const getTag = (path, state) => {
const namePath = path.get("openingElement").get("name");
if (namePath.isJSXIdentifier()) {
const { name } = namePath.node;
if (!isHTMLTag(name) && !isSVGTag(name)) {
var _state$opts$isCustomE2, _state$opts2;
return name === FRAGMENT ? createIdentifier(state, FRAGMENT) : path.scope.hasBinding(name) ? t.identifier(name) : ((_state$opts$isCustomE2 = (_state$opts2 = state.opts).isCustomElement) === null || _state$opts$isCustomE2 === void 0 ? void 0 : _state$opts$isCustomE2.call(_state$opts2, name)) ? t.stringLiteral(name) : t.callExpression(createIdentifier(state, "resolveComponent"), [t.stringLiteral(name)]);
}
return t.stringLiteral(name);
}
if (namePath.isJSXMemberExpression()) return transformJSXMemberExpression(namePath);
throw new Error(`getTag: ${namePath.type} is not supported`);
};
const getJSXAttributeName = (path) => {
const nameNode = path.node.name;
if (t.isJSXIdentifier(nameNode)) return nameNode.name;
return `${nameNode.namespace.name}:${nameNode.name.name}`;
};
/**
* Transform JSXText to StringLiteral
* @param path JSXText
* @returns StringLiteral | null
*/
const transformJSXText = (path) => {
const str = transformText(path.node.value);
return str !== "" ? t.stringLiteral(str) : null;
};
const transformText = (text) => {
const lines = text.split(/\r\n|\n|\r/);
let lastNonEmptyLine = 0;
for (let i = 0; i < lines.length; i++) if (lines[i].match(/[^ \t]/)) lastNonEmptyLine = i;
let str = "";
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const isFirstLine = i === 0;
const isLastLine = i === lines.length - 1;
const isLastNonEmptyLine = i === lastNonEmptyLine;
let trimmedLine = line.replace(/\t/g, " ");
if (!isFirstLine) trimmedLine = trimmedLine.replace(/^[ ]+/, "");
if (!isLastLine) trimmedLine = trimmedLine.replace(/[ ]+$/, "");
if (trimmedLine) {
if (!isLastNonEmptyLine) trimmedLine += " ";
str += trimmedLine;
}
}
return str;
};
/**
* Transform JSXExpressionContainer to Expression
* @param path JSXExpressionContainer
* @returns Expression
*/
const transformJSXExpressionContainer = (path) => path.get("expression").node;
/**
* Transform JSXSpreadChild
* @param path JSXSpreadChild
* @returns SpreadElement
*/
const transformJSXSpreadChild = (path) => t.spreadElement(path.get("expression").node);
const walksScope = (path, name, slotFlag) => {
if (path.scope.hasBinding(name) && path.parentPath) {
if (t.isJSXElement(path.parentPath.node)) path.parentPath.setData("slotFlag", slotFlag);
walksScope(path.parentPath, name, slotFlag);
}
};
const buildIIFE = (path, children) => {
const { parentPath } = path;
if (parentPath.isAssignmentExpression()) {
const { left } = parentPath.node;
if (t.isIdentifier(left)) return children.map((child) => {
if (t.isIdentifier(child) && child.name === left.name) {
const insertName = path.scope.generateUidIdentifier(child.name);
parentPath.insertBefore(t.variableDeclaration("const", [t.variableDeclarator(insertName, t.callExpression(t.functionExpression(null, [], t.blockStatement([t.returnStatement(child)])), []))]));
return insertName;
}
return child;
});
}
return children;
};
const onRE = /^on[^a-z]/;
const isOn = (key) => onRE.test(key);
const mergeAsArray = (existing, incoming) => {
if (t.isArrayExpression(existing.value)) existing.value.elements.push(incoming.value);
else existing.value = t.arrayExpression([existing.value, incoming.value]);
};
const dedupeProperties = (properties = [], mergeProps) => {
if (!mergeProps) return properties;
const knownProps = /* @__PURE__ */ new Map();
const deduped = [];
properties.forEach((prop) => {
if (t.isStringLiteral(prop.key)) {
const { value: name } = prop.key;
const existing = knownProps.get(name);
if (existing) {
if (name === "style" || name === "class" || name.startsWith("on")) mergeAsArray(existing, prop);
} else {
knownProps.set(name, prop);
deduped.push(prop);
}
} else deduped.push(prop);
});
return deduped;
};
/**
* Check if an attribute value is constant
* @param node
* @returns boolean
*/
const isConstant = (node) => {
if (t.isIdentifier(node)) return node.name === "undefined";
if (t.isArrayExpression(node)) {
const { elements } = node;
return elements.every((element) => element && isConstant(element));
}
if (t.isObjectExpression(node)) return node.properties.every((property) => isConstant(property.value));
if (t.isTemplateLiteral(node) ? !node.expressions.length : t.isLiteral(node)) return true;
return false;
};
const transformJSXSpreadAttribute = (nodePath, path, mergeProps, args) => {
const argument = path.get("argument");
const properties = t.isObjectExpression(argument.node) ? argument.node.properties : void 0;
if (!properties) {
if (argument.isIdentifier()) walksScope(nodePath, argument.node.name, slotFlags_default.DYNAMIC);
args.push(mergeProps ? argument.node : t.spreadElement(argument.node));
} else if (mergeProps) args.push(t.objectExpression(properties));
else args.push(...properties);
};
//#endregion
//#region src/patchFlags.ts
let PatchFlags = /* @__PURE__ */ function(PatchFlags$1) {
PatchFlags$1[PatchFlags$1["TEXT"] = 1] = "TEXT";
PatchFlags$1[PatchFlags$1["CLASS"] = 2] = "CLASS";
PatchFlags$1[PatchFlags$1["STYLE"] = 4] = "STYLE";
PatchFlags$1[PatchFlags$1["PROPS"] = 8] = "PROPS";
PatchFlags$1[PatchFlags$1["FULL_PROPS"] = 16] = "FULL_PROPS";
PatchFlags$1[PatchFlags$1["HYDRATE_EVENTS"] = 32] = "HYDRATE_EVENTS";
PatchFlags$1[PatchFlags$1["STABLE_FRAGMENT"] = 64] = "STABLE_FRAGMENT";
PatchFlags$1[PatchFlags$1["KEYED_FRAGMENT"] = 128] = "KEYED_FRAGMENT";
PatchFlags$1[PatchFlags$1["UNKEYED_FRAGMENT"] = 256] = "UNKEYED_FRAGMENT";
PatchFlags$1[PatchFlags$1["NEED_PATCH"] = 512] = "NEED_PATCH";
PatchFlags$1[PatchFlags$1["DYNAMIC_SLOTS"] = 1024] = "DYNAMIC_SLOTS";
PatchFlags$1[PatchFlags$1["HOISTED"] = -1] = "HOISTED";
PatchFlags$1[PatchFlags$1["BAIL"] = -2] = "BAIL";
return PatchFlags$1;
}({});
const PatchFlagNames = {
[PatchFlags.TEXT]: "TEXT",
[PatchFlags.CLASS]: "CLASS",
[PatchFlags.STYLE]: "STYLE",
[PatchFlags.PROPS]: "PROPS",
[PatchFlags.FULL_PROPS]: "FULL_PROPS",
[PatchFlags.HYDRATE_EVENTS]: "HYDRATE_EVENTS",
[PatchFlags.STABLE_FRAGMENT]: "STABLE_FRAGMENT",
[PatchFlags.KEYED_FRAGMENT]: "KEYED_FRAGMENT",
[PatchFlags.UNKEYED_FRAGMENT]: "UNKEYED_FRAGMENT",
[PatchFlags.DYNAMIC_SLOTS]: "DYNAMIC_SLOTS",
[PatchFlags.NEED_PATCH]: "NEED_PATCH",
[PatchFlags.HOISTED]: "HOISTED",
[PatchFlags.BAIL]: "BAIL"
};
//#endregion
//#region src/parseDirectives.ts
/**
* Get JSX element type
*
* @param path Path<JSXOpeningElement>
*/
const getType = (path) => {
const typePath = path.get("attributes").find((attribute) => {
if (!attribute.isJSXAttribute()) return false;
return attribute.get("name").isJSXIdentifier() && attribute.get("name").node.name === "type";
});
return typePath ? typePath.get("value").node : null;
};
const parseModifiers = (value) => t.isArrayExpression(value) ? value.elements.map((el) => t.isStringLiteral(el) ? el.value : "").filter(Boolean) : [];
const parseDirectives = (params) => {
var _modifiersSet$, _modifiersSet$2;
const { path, value, state, tag, isComponent } = params;
const args = [];
const vals = [];
const modifiersSet = [];
let directiveName;
let directiveArgument;
let directiveModifiers;
if ("namespace" in path.node.name) {
[directiveName, directiveArgument] = params.name.split(":");
directiveName = path.node.name.namespace.name;
directiveArgument = path.node.name.name.name;
directiveModifiers = directiveArgument.split("_").slice(1);
} else {
const underscoreModifiers = params.name.split("_");
directiveName = underscoreModifiers.shift() || "";
directiveModifiers = underscoreModifiers;
}
directiveName = directiveName.replace(/^v/, "").replace(/^-/, "").replace(/^\S/, (s) => s.toLowerCase());
if (directiveArgument) args.push(t.stringLiteral(directiveArgument.split("_")[0]));
const isVModels = directiveName === "models";
const isVModel = directiveName === "model";
if (isVModel && !path.get("value").isJSXExpressionContainer()) throw new Error("You have to use JSX Expression inside your v-model");
if (isVModels && !isComponent) throw new Error("v-models can only use in custom components");
const shouldResolve = ![
"html",
"text",
"model",
"slots",
"models"
].includes(directiveName) || isVModel && !isComponent;
let modifiers = directiveModifiers;
if (t.isArrayExpression(value)) {
const elementsList = isVModels ? value.elements : [value];
elementsList.forEach((element) => {
if (isVModels && !t.isArrayExpression(element)) throw new Error("You should pass a Two-dimensional Arrays to v-models");
const { elements } = element;
const [first, second, third] = elements;
if (second && !t.isArrayExpression(second) && !t.isSpreadElement(second)) {
args.push(second);
modifiers = parseModifiers(third);
} else if (t.isArrayExpression(second)) {
if (!shouldResolve) args.push(t.nullLiteral());
modifiers = parseModifiers(second);
} else if (!shouldResolve) args.push(t.nullLiteral());
modifiersSet.push(new Set(modifiers));
vals.push(first);
});
} else if (isVModel && !shouldResolve) {
args.push(t.nullLiteral());
modifiersSet.push(new Set(directiveModifiers));
} else modifiersSet.push(new Set(directiveModifiers));
return {
directiveName,
modifiers: modifiersSet,
values: vals.length ? vals : [value],
args,
directive: shouldResolve ? [
resolveDirective(path, state, tag, directiveName),
vals[0] || value,
((_modifiersSet$ = modifiersSet[0]) === null || _modifiersSet$ === void 0 ? void 0 : _modifiersSet$.size) ? args[0] || t.unaryExpression("void", t.numericLiteral(0), true) : args[0],
!!((_modifiersSet$2 = modifiersSet[0]) === null || _modifiersSet$2 === void 0 ? void 0 : _modifiersSet$2.size) && t.objectExpression([...modifiersSet[0]].map((modifier) => t.objectProperty(t.identifier(modifier), t.booleanLiteral(true))))
].filter(Boolean) : void 0
};
};
const resolveDirective = (path, state, tag, directiveName) => {
if (directiveName === "show") return createIdentifier(state, "vShow");
if (directiveName === "model") {
let modelToUse;
const type = getType(path.parentPath);
switch (tag.value) {
case "select":
modelToUse = createIdentifier(state, "vModelSelect");
break;
case "textarea":
modelToUse = createIdentifier(state, "vModelText");
break;
default: if (t.isStringLiteral(type) || !type) switch (type === null || type === void 0 ? void 0 : type.value) {
case "checkbox":
modelToUse = createIdentifier(state, "vModelCheckbox");
break;
case "radio":
modelToUse = createIdentifier(state, "vModelRadio");
break;
default: modelToUse = createIdentifier(state, "vModelText");
}
else modelToUse = createIdentifier(state, "vModelDynamic");
}
return modelToUse;
}
const referenceName = "v" + directiveName[0].toUpperCase() + directiveName.slice(1);
if (path.scope.references[referenceName]) return t.identifier(referenceName);
return t.callExpression(createIdentifier(state, "resolveDirective"), [t.stringLiteral(directiveName)]);
};
var parseDirectives_default = parseDirectives;
//#endregion
//#region src/transform-vue-jsx.ts
const xlinkRE = new RegExp("^xlink([A-Z])", "");
const getJSXAttributeValue = (path, state) => {
const valuePath = path.get("value");
if (valuePath.isJSXElement()) return transformJSXElement(valuePath, state);
if (valuePath.isStringLiteral()) return t.stringLiteral(transformText(valuePath.node.value));
if (valuePath.isJSXExpressionContainer()) return transformJSXExpressionContainer(valuePath);
return null;
};
const buildProps = (path, state) => {
const tag = getTag(path, state);
const isComponent = checkIsComponent(path.get("openingElement"), state);
const props = path.get("openingElement").get("attributes");
const directives = [];
const dynamicPropNames = /* @__PURE__ */ new Set();
let slots = null;
let patchFlag = 0;
if (props.length === 0) return {
tag,
isComponent,
slots,
props: t.nullLiteral(),
directives,
patchFlag,
dynamicPropNames
};
let properties = [];
let hasRef = false;
let hasClassBinding = false;
let hasStyleBinding = false;
let hasHydrationEventBinding = false;
let hasDynamicKeys = false;
const mergeArgs = [];
const { mergeProps = true } = state.opts;
props.forEach((prop) => {
if (prop.isJSXAttribute()) {
let name = getJSXAttributeName(prop);
const attributeValue = getJSXAttributeValue(prop, state);
if (!isConstant(attributeValue) || name === "ref") {
if (!isComponent && isOn(name) && name.toLowerCase() !== "onclick" && name !== "onUpdate:modelValue") hasHydrationEventBinding = true;
if (name === "ref") hasRef = true;
else if (name === "class" && !isComponent) hasClassBinding = true;
else if (name === "style" && !isComponent) hasStyleBinding = true;
else if (name !== "key" && !isDirective(name) && name !== "on") dynamicPropNames.add(name);
}
if (state.opts.transformOn && (name === "on" || name === "nativeOn")) {
if (!state.get("transformOn")) state.set("transformOn", addDefault(path, "@vue/babel-helper-vue-transform-on", { nameHint: "_transformOn" }));
mergeArgs.push(t.callExpression(state.get("transformOn"), [attributeValue || t.booleanLiteral(true)]));
return;
}
if (isDirective(name)) {
const { directive, modifiers, values, args, directiveName } = parseDirectives_default({
tag,
isComponent,
name,
path: prop,
state,
value: attributeValue
});
if (directiveName === "slots") {
slots = attributeValue;
return;
}
if (directive) directives.push(t.arrayExpression(directive));
else if (directiveName === "html") {
properties.push(t.objectProperty(t.stringLiteral("innerHTML"), values[0]));
dynamicPropNames.add("innerHTML");
} else if (directiveName === "text") {
properties.push(t.objectProperty(t.stringLiteral("textContent"), values[0]));
dynamicPropNames.add("textContent");
}
if (["models", "model"].includes(directiveName)) values.forEach((value, index) => {
const propName = args[index];
const isDynamic = propName && !t.isStringLiteral(propName) && !t.isNullLiteral(propName);
if (!directive) {
var _modifiers$index;
properties.push(t.objectProperty(t.isNullLiteral(propName) ? t.stringLiteral("modelValue") : propName, value, isDynamic));
if (!isDynamic) dynamicPropNames.add((propName === null || propName === void 0 ? void 0 : propName.value) || "modelValue");
if ((_modifiers$index = modifiers[index]) === null || _modifiers$index === void 0 ? void 0 : _modifiers$index.size) properties.push(t.objectProperty(isDynamic ? t.binaryExpression("+", propName, t.stringLiteral("Modifiers")) : t.stringLiteral(`${(propName === null || propName === void 0 ? void 0 : propName.value) || "model"}Modifiers`), t.objectExpression([...modifiers[index]].map((modifier) => t.objectProperty(t.stringLiteral(modifier), t.booleanLiteral(true)))), isDynamic));
}
const updateName = isDynamic ? t.binaryExpression("+", t.stringLiteral("onUpdate:"), propName) : t.stringLiteral(`onUpdate:${(propName === null || propName === void 0 ? void 0 : propName.value) || "modelValue"}`);
properties.push(t.objectProperty(updateName, t.arrowFunctionExpression([t.identifier("$event")], t.assignmentExpression("=", value, t.identifier("$event"))), isDynamic));
if (!isDynamic) dynamicPropNames.add(updateName.value);
else hasDynamicKeys = true;
});
} else {
if (name.match(xlinkRE)) name = name.replace(xlinkRE, (_, firstCharacter) => `xlink:${firstCharacter.toLowerCase()}`);
properties.push(t.objectProperty(t.stringLiteral(name), attributeValue || t.booleanLiteral(true)));
}
} else {
if (properties.length && mergeProps) {
mergeArgs.push(t.objectExpression(dedupeProperties(properties, mergeProps)));
properties = [];
}
hasDynamicKeys = true;
transformJSXSpreadAttribute(path, prop, mergeProps, mergeProps ? mergeArgs : properties);
}
});
if (hasDynamicKeys) patchFlag |= PatchFlags.FULL_PROPS;
else {
if (hasClassBinding) patchFlag |= PatchFlags.CLASS;
if (hasStyleBinding) patchFlag |= PatchFlags.STYLE;
if (dynamicPropNames.size) patchFlag |= PatchFlags.PROPS;
if (hasHydrationEventBinding) patchFlag |= PatchFlags.HYDRATE_EVENTS;
}
if ((patchFlag === 0 || patchFlag === PatchFlags.HYDRATE_EVENTS) && (hasRef || directives.length > 0)) patchFlag |= PatchFlags.NEED_PATCH;
let propsExpression = t.nullLiteral();
if (mergeArgs.length) {
if (properties.length) mergeArgs.push(t.objectExpression(dedupeProperties(properties, mergeProps)));
if (mergeArgs.length > 1) propsExpression = t.callExpression(createIdentifier(state, "mergeProps"), mergeArgs);
else propsExpression = mergeArgs[0];
} else if (properties.length) if (properties.length === 1 && t.isSpreadElement(properties[0])) propsExpression = properties[0].argument;
else propsExpression = t.objectExpression(dedupeProperties(properties, mergeProps));
return {
tag,
props: propsExpression,
isComponent,
slots,
directives,
patchFlag,
dynamicPropNames
};
};
/**
* Get children from Array of JSX children
* @param paths Array<JSXText | JSXExpressionContainer | JSXElement | JSXFragment>
* @returns Array<Expression | SpreadElement>
*/
const getChildren = (paths, state) => paths.map((path) => {
if (path.isJSXText()) {
const transformedText = transformJSXText(path);
if (transformedText) return t.callExpression(createIdentifier(state, "createTextVNode"), [transformedText]);
return transformedText;
}
if (path.isJSXExpressionContainer()) {
const expression = transformJSXExpressionContainer(path);
if (t.isIdentifier(expression)) {
const { name } = expression;
const { referencePaths = [] } = path.scope.getBinding(name) || {};
referencePaths.forEach((referencePath) => {
walksScope(referencePath, name, slotFlags_default.DYNAMIC);
});
}
return expression;
}
if (path.isJSXSpreadChild()) return transformJSXSpreadChild(path);
if (path.isCallExpression()) return path.node;
if (path.isJSXElement()) return transformJSXElement(path, state);
throw new Error(`getChildren: ${path.type} is not supported`);
}).filter(((value) => value != null && !t.isJSXEmptyExpression(value)));
const transformJSXElement = (path, state) => {
var _path$getData;
const children = getChildren(path.get("children"), state);
const { tag, props, isComponent, directives, patchFlag, dynamicPropNames, slots } = buildProps(path, state);
const { optimize = false } = state.opts;
if (directives.length && directives.some((d) => {
var _d$elements;
return ((_d$elements = d.elements) === null || _d$elements === void 0 || (_d$elements = _d$elements[0]) === null || _d$elements === void 0 ? void 0 : _d$elements.type) === "CallExpression" && d.elements[0].callee.type === "Identifier" && d.elements[0].callee.name === "_resolveDirective";
})) {
var _currentPath$parentPa;
let currentPath = path;
while ((_currentPath$parentPa = currentPath.parentPath) === null || _currentPath$parentPa === void 0 ? void 0 : _currentPath$parentPa.isJSXElement()) {
currentPath = currentPath.parentPath;
currentPath.setData("slotFlag", 0);
}
}
const slotFlag = (_path$getData = path.getData("slotFlag")) !== null && _path$getData !== void 0 ? _path$getData : slotFlags_default.STABLE;
const optimizeSlots = optimize && slotFlag !== 0;
let VNodeChild;
if (children.length > 1 || slots) VNodeChild = isComponent ? children.length ? t.objectExpression([
!!children.length && t.objectProperty(t.identifier("default"), t.arrowFunctionExpression([], t.arrayExpression(buildIIFE(path, children)))),
...slots ? t.isObjectExpression(slots) ? slots.properties : [t.spreadElement(slots)] : [],
optimizeSlots && t.objectProperty(t.identifier("_"), t.numericLiteral(slotFlag))
].filter(Boolean)) : slots : t.arrayExpression(children);
else if (children.length === 1) {
const { enableObjectSlots = true } = state.opts;
const child = children[0];
const objectExpression = t.objectExpression([t.objectProperty(t.identifier("default"), t.arrowFunctionExpression([], t.arrayExpression(buildIIFE(path, [child])))), optimizeSlots && t.objectProperty(t.identifier("_"), t.numericLiteral(slotFlag))].filter(Boolean));
if (t.isIdentifier(child) && isComponent) VNodeChild = enableObjectSlots ? t.conditionalExpression(t.callExpression(state.get("@vue/babel-plugin-jsx/runtimeIsSlot")(), [child]), child, objectExpression) : objectExpression;
else if (t.isCallExpression(child) && child.loc && isComponent) if (enableObjectSlots) {
const { scope } = path;
const slotId = scope.generateUidIdentifier("slot");
if (scope) scope.push({
id: slotId,
kind: "let"
});
const alternate = t.objectExpression([t.objectProperty(t.identifier("default"), t.arrowFunctionExpression([], t.arrayExpression(buildIIFE(path, [slotId])))), optimizeSlots && t.objectProperty(t.identifier("_"), t.numericLiteral(slotFlag))].filter(Boolean));
const assignment = t.assignmentExpression("=", slotId, child);
const condition = t.callExpression(state.get("@vue/babel-plugin-jsx/runtimeIsSlot")(), [assignment]);
VNodeChild = t.conditionalExpression(condition, slotId, alternate);
} else VNodeChild = objectExpression;
else if (t.isFunctionExpression(child) || t.isArrowFunctionExpression(child)) VNodeChild = t.objectExpression([t.objectProperty(t.identifier("default"), child)]);
else if (t.isObjectExpression(child)) VNodeChild = t.objectExpression([...child.properties, optimizeSlots && t.objectProperty(t.identifier("_"), t.numericLiteral(slotFlag))].filter(Boolean));
else VNodeChild = isComponent ? t.objectExpression([t.objectProperty(t.identifier("default"), t.arrowFunctionExpression([], t.arrayExpression([child])))]) : t.arrayExpression([child]);
}
const createVNode = t.callExpression(createIdentifier(state, "createVNode"), [
tag,
props,
VNodeChild || t.nullLiteral(),
!!patchFlag && optimize && t.numericLiteral(patchFlag),
!!dynamicPropNames.size && optimize && t.arrayExpression([...dynamicPropNames.keys()].map((name) => t.stringLiteral(name)))
].filter(Boolean));
if (!directives.length) return createVNode;
return t.callExpression(createIdentifier(state, "withDirectives"), [createVNode, t.arrayExpression(directives)]);
};
const visitor$1 = { JSXElement: { exit(path, state) {
path.replaceWith(transformJSXElement(path, state));
} } };
var transform_vue_jsx_default = visitor$1;
//#endregion
//#region src/sugar-fragment.ts
const transformFragment = (path, Fragment) => {
const children = path.get("children") || [];
return t.jsxElement(t.jsxOpeningElement(Fragment, []), t.jsxClosingElement(Fragment), children.map(({ node }) => node), false);
};
const visitor = { JSXFragment: { enter(path, state) {
const fragmentCallee = createIdentifier(state, FRAGMENT);
path.replaceWith(transformFragment(path, t.isIdentifier(fragmentCallee) ? t.jsxIdentifier(fragmentCallee.name) : t.jsxMemberExpression(t.jsxIdentifier(fragmentCallee.object.name), t.jsxIdentifier(fragmentCallee.property.name))));
} } };
var sugar_fragment_default = visitor;
//#endregion
//#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/typeof.js
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
return typeof o$1;
} : function(o$1) {
return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
}, _typeof(o);
}
//#endregion
//#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/toPrimitive.js
function toPrimitive(t$1, r) {
if ("object" != _typeof(t$1) || !t$1) return t$1;
var e = t$1[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t$1, r || "default");
if ("object" != _typeof(i)) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t$1);
}
//#endregion
//#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/toPropertyKey.js
function toPropertyKey(t$1) {
var i = toPrimitive(t$1, "string");
return "symbol" == _typeof(i) ? i : i + "";
}
//#endregion
//#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/defineProperty.js
function _defineProperty(e, r, t$1) {
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t$1,
enumerable: !0,
configurable: !0,
writable: !0
}) : e[r] = t$1, e;
}
//#endregion
//#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/objectSpread2.js
function ownKeys(e, r) {
var t$1 = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function(r$1) {
return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
})), t$1.push.apply(t$1, o);
}
return t$1;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t$1 = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t$1), !0).forEach(function(r$1) {
_defineProperty(e, r$1, t$1[r$1]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t$1)) : ownKeys(Object(t$1)).forEach(function(r$1) {
Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t$1, r$1));
});
}
return e;
}
//#endregion
//#region src/index.ts
const hasJSX = (parentPath) => {
let fileHasJSX = false;
parentPath.traverse({
JSXElement(path) {
fileHasJSX = true;
path.stop();
},
JSXFragment(path) {
fileHasJSX = true;
path.stop();
}
});
return fileHasJSX;
};
const JSX_ANNOTATION_REGEX = new RegExp("\\*?\\s*@jsx\\s+([^\\s]+)", "");
/* @__NO_SIDE_EFFECTS__ */
function interopDefault(m) {
return m.default || m;
}
const syntaxJsx = /* @__PURE__ */ interopDefault(_syntaxJsx);
const template = /* @__PURE__ */ interopDefault(_template);
const plugin = declare((api, opt, dirname) => {
const { types } = api;
let resolveType;
if (opt.resolveType) {
if (typeof opt.resolveType === "boolean") opt.resolveType = {};
resolveType = ResolveType(api, opt.resolveType, dirname);
}
return _objectSpread2(_objectSpread2({}, resolveType || {}), {}, {
name: "babel-plugin-jsx",
inherits: /* @__PURE__ */ interopDefault(syntaxJsx),
visitor: _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, resolveType === null || resolveType === void 0 ? void 0 : resolveType.visitor), transform_vue_jsx_default), sugar_fragment_default), {}, { Program: { enter(path, state) {
if (hasJSX(path)) {
const importNames = [
"createVNode",
"Fragment",
"resolveComponent",
"withDirectives",
"vShow",
"vModelSelect",
"vModelText",
"vModelCheckbox",
"vModelRadio",
"vModelText",
"vModelDynamic",
"resolveDirective",
"mergeProps",
"createTextVNode",
"isVNode"
];
if (isModule(path)) {
const importMap = {};
importNames.forEach((name) => {
state.set(name, () => {
if (importMap[name]) return types.cloneNode(importMap[name]);
const identifier = addNamed(path, name, "vue", { ensureLiveReference: true });
importMap[name] = identifier;
return identifier;
});
});
const { enableObjectSlots = true } = state.opts;
if (enableObjectSlots) state.set("@vue/babel-plugin-jsx/runtimeIsSlot", () => {
if (importMap.runtimeIsSlot) return importMap.runtimeIsSlot;
const { name: isVNodeName } = state.get("isVNode")();
const isSlot = path.scope.generateUidIdentifier("isSlot");
const ast = template.ast`
function ${isSlot.name}(s) {
return typeof s === 'function' || (Object.prototype.toString.call(s) === '[object Object]' && !${isVNodeName}(s));
}
`;
const lastImport = path.get("body").filter((p) => p.isImportDeclaration()).pop();
if (lastImport) lastImport.insertAfter(ast);
importMap.runtimeIsSlot = isSlot;
return isSlot;
});
} else {
let sourceName;
importNames.forEach((name) => {
state.set(name, () => {
if (!sourceName) sourceName = addNamespace(path, "vue", { ensureLiveReference: true });
return t.memberExpression(sourceName, t.identifier(name));
});
});
const helpers = {};
const { enableObjectSlots = true } = state.opts;
if (enableObjectSlots) state.set("@vue/babel-plugin-jsx/runtimeIsSlot", () => {
if (helpers.runtimeIsSlot) return helpers.runtimeIsSlot;
const isSlot = path.scope.generateUidIdentifier("isSlot");
const { object: objectName } = state.get("isVNode")();
const ast = template.ast`
function ${isSlot.name}(s) {
return typeof s === 'function' || (Object.prototype.toString.call(s) === '[object Object]' && !${objectName.name}.isVNode(s));
}
`;
const nodePaths = path.get("body");
const lastImport = nodePaths.filter((p) => p.isVariableDeclaration() && p.node.declarations.some((d) => {
var _d$id;
return ((_d$id = d.id) === null || _d$id === void 0 ? void 0 : _d$id.name) === sourceName.name;
})).pop();
if (lastImport) lastImport.insertAfter(ast);
return isSlot;
});
}
const { opts: { pragma = "" }, file } = state;
if (pragma) state.set("createVNode", () => t.identifier(pragma));
if (file.ast.comments) for (const comment of file.ast.comments) {
const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
if (jsxMatches) state.set("createVNode", () => t.identifier(jsxMatches[1]));
}
}
} } })
});
});
var src_default = plugin;
//#endregion
export { src_default as default };

View File

@@ -0,0 +1,57 @@
{
"name": "@vue/babel-plugin-jsx",
"version": "1.5.0",
"description": "Babel plugin for Vue 3 JSX",
"author": "Amour1688 <lcz_1996@foxmail.com>",
"homepage": "https://github.com/vuejs/babel-plugin-jsx/tree/dev/packages/babel-plugin-jsx#readme",
"license": "MIT",
"type": "commonjs",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./*": "./*"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/babel-plugin-jsx.git"
},
"bugs": {
"url": "https://github.com/vuejs/babel-plugin-jsx/issues"
},
"files": [
"dist"
],
"dependencies": {
"@babel/helper-module-imports": "^7.27.1",
"@babel/helper-plugin-utils": "^7.27.1",
"@babel/plugin-syntax-jsx": "^7.27.1",
"@babel/template": "^7.27.2",
"@babel/traverse": "^7.28.0",
"@babel/types": "^7.28.2",
"@vue/shared": "^3.5.18",
"@vue/babel-helper-vue-transform-on": "1.5.0",
"@vue/babel-plugin-resolve-type": "1.5.0"
},
"devDependencies": {
"@babel/core": "^7.28.0",
"@babel/preset-env": "^7.28.0",
"@types/babel__template": "^7.4.4",
"@types/babel__traverse": "^7.28.0",
"@vue/test-utils": "^2.4.6",
"regenerator-runtime": "^0.14.1",
"vue": "^3.5.18"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
},
"peerDependenciesMeta": {
"@babel/core": {
"optional": true
}
}
}

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-present vuejs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1 @@
# babel-plugin-resolve-type

View File

@@ -0,0 +1,7 @@
import { SimpleTypeResolveOptions } from "@vue/compiler-sfc";
import * as BabelCore from "@babel/core";
//#region src/index.d.ts
declare const plugin: (api: object, options: SimpleTypeResolveOptions | null | undefined, dirname: string) => BabelCore.PluginObj<BabelCore.PluginPass>;
//#endregion
export { SimpleTypeResolveOptions as Options, plugin as default };

View File

@@ -0,0 +1,7 @@
import * as BabelCore from "@babel/core";
import { SimpleTypeResolveOptions } from "@vue/compiler-sfc";
//#region src/index.d.ts
declare const plugin: (api: object, options: SimpleTypeResolveOptions | null | undefined, dirname: string) => BabelCore.PluginObj<BabelCore.PluginPass>;
//#endregion
export { SimpleTypeResolveOptions as Options, plugin as default };

View File

@@ -0,0 +1,196 @@
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
const __babel_parser = __toESM(require("@babel/parser"));
const __vue_compiler_sfc = __toESM(require("@vue/compiler-sfc"));
const __babel_code_frame = __toESM(require("@babel/code-frame"));
const __babel_helper_module_imports = __toESM(require("@babel/helper-module-imports"));
const __babel_helper_plugin_utils = __toESM(require("@babel/helper-plugin-utils"));
//#region src/index.ts
const plugin = (0, __babel_helper_plugin_utils.declare)(({ types: t }, options) => {
let ctx;
let helpers;
return {
name: "babel-plugin-resolve-type",
pre(file) {
const filename = file.opts.filename || "unknown.js";
helpers = /* @__PURE__ */ new Set();
ctx = {
filename,
source: file.code,
options,
ast: file.ast.program.body,
isCE: false,
error(msg, node) {
throw new Error(`[@vue/babel-plugin-resolve-type] ${msg}\n\n${filename}\n${(0, __babel_code_frame.codeFrameColumns)(file.code, {
start: {
line: node.loc.start.line,
column: node.loc.start.column + 1
},
end: {
line: node.loc.end.line,
column: node.loc.end.column + 1
}
})}`);
},
helper(key) {
helpers.add(key);
return `_${key}`;
},
getString(node) {
return file.code.slice(node.start, node.end);
},
propsTypeDecl: void 0,
propsRuntimeDefaults: void 0,
propsDestructuredBindings: {},
emitsTypeDecl: void 0
};
},
visitor: {
CallExpression(path) {
if (!ctx) throw new Error("[@vue/babel-plugin-resolve-type] context is not loaded.");
const { node } = path;
if (!t.isIdentifier(node.callee, { name: "defineComponent" })) return;
if (!checkDefineComponent(path)) return;
const comp = node.arguments[0];
if (!comp || !t.isFunction(comp)) return;
let options$1 = node.arguments[1];
if (!options$1) {
options$1 = t.objectExpression([]);
node.arguments.push(options$1);
}
let propsGenerics;
let emitsGenerics;
if (node.typeParameters && node.typeParameters.params.length > 0) {
propsGenerics = node.typeParameters.params[0];
emitsGenerics = node.typeParameters.params[1];
}
node.arguments[1] = processProps(comp, propsGenerics, options$1) || options$1;
node.arguments[1] = processEmits(comp, emitsGenerics, node.arguments[1]) || options$1;
},
VariableDeclarator(path) {
inferComponentName(path);
}
},
post(file) {
for (const helper of helpers) (0, __babel_helper_module_imports.addNamed)(file.path, `_${helper}`, "vue");
}
};
function inferComponentName(path) {
var _init$get;
const id = path.get("id");
const init = path.get("init");
if (!id || !id.isIdentifier() || !init || !init.isCallExpression()) return;
if (!((_init$get = init.get("callee")) === null || _init$get === void 0 ? void 0 : _init$get.isIdentifier({ name: "defineComponent" }))) return;
if (!checkDefineComponent(init)) return;
const nameProperty = t.objectProperty(t.identifier("name"), t.stringLiteral(id.node.name));
const { arguments: args } = init.node;
if (args.length === 0) return;
if (args.length === 1) init.node.arguments.push(t.objectExpression([]));
args[1] = addProperty(t, args[1], nameProperty);
}
function processProps(comp, generics, options$1) {
const props = comp.params[0];
if (!props) return;
if (props.type === "AssignmentPattern") {
if (generics) ctx.propsTypeDecl = resolveTypeReference(generics);
else ctx.propsTypeDecl = getTypeAnnotation(props.left);
ctx.propsRuntimeDefaults = props.right;
} else if (generics) ctx.propsTypeDecl = resolveTypeReference(generics);
else ctx.propsTypeDecl = getTypeAnnotation(props);
if (!ctx.propsTypeDecl) return;
const runtimeProps = (0, __vue_compiler_sfc.extractRuntimeProps)(ctx);
if (!runtimeProps) return;
const ast = (0, __babel_parser.parseExpression)(runtimeProps);
return addProperty(t, options$1, t.objectProperty(t.identifier("props"), ast));
}
function processEmits(comp, generics, options$1) {
let emitType;
if (generics) emitType = resolveTypeReference(generics);
const setupCtx = comp.params[1] && getTypeAnnotation(comp.params[1]);
if (!emitType && setupCtx && t.isTSTypeReference(setupCtx) && t.isIdentifier(setupCtx.typeName, { name: "SetupContext" })) {
var _setupCtx$typeParamet;
emitType = (_setupCtx$typeParamet = setupCtx.typeParameters) === null || _setupCtx$typeParamet === void 0 ? void 0 : _setupCtx$typeParamet.params[0];
}
if (!emitType) return;
ctx.emitsTypeDecl = emitType;
const runtimeEmits = (0, __vue_compiler_sfc.extractRuntimeEmits)(ctx);
const ast = t.arrayExpression(Array.from(runtimeEmits).map((e) => t.stringLiteral(e)));
return addProperty(t, options$1, t.objectProperty(t.identifier("emits"), ast));
}
function resolveTypeReference(typeNode) {
if (!ctx) return;
if (t.isTSTypeReference(typeNode)) {
const typeName = getTypeReferenceName(typeNode);
if (typeName) {
const typeDeclaration = findTypeDeclaration(typeName);
if (typeDeclaration) return typeDeclaration;
}
}
}
function getTypeReferenceName(typeRef) {
if (t.isIdentifier(typeRef.typeName)) return typeRef.typeName.name;
else if (t.isTSQualifiedName(typeRef.typeName)) {
const parts = [];
let current = typeRef.typeName;
while (t.isTSQualifiedName(current)) {
if (t.isIdentifier(current.right)) parts.unshift(current.right.name);
current = current.left;
}
if (t.isIdentifier(current)) parts.unshift(current.name);
return parts.join(".");
}
return null;
}
function findTypeDeclaration(typeName) {
if (!ctx) return null;
for (const statement of ctx.ast) {
if (t.isTSInterfaceDeclaration(statement) && statement.id.name === typeName) return t.tsTypeLiteral(statement.body.body);
if (t.isTSTypeAliasDeclaration(statement) && statement.id.name === typeName) return statement.typeAnnotation;
if (t.isExportNamedDeclaration(statement) && statement.declaration) {
if (t.isTSInterfaceDeclaration(statement.declaration) && statement.declaration.id.name === typeName) return t.tsTypeLiteral(statement.declaration.body.body);
if (t.isTSTypeAliasDeclaration(statement.declaration) && statement.declaration.id.name === typeName) return statement.declaration.typeAnnotation;
}
}
return null;
}
});
var src_default = plugin;
function getTypeAnnotation(node) {
if ("typeAnnotation" in node && node.typeAnnotation && node.typeAnnotation.type === "TSTypeAnnotation") return node.typeAnnotation.typeAnnotation;
}
function checkDefineComponent(path) {
var _path$scope$getBindin;
const defineCompImport = (_path$scope$getBindin = path.scope.getBinding("defineComponent")) === null || _path$scope$getBindin === void 0 ? void 0 : _path$scope$getBindin.path.parent;
if (!defineCompImport) return true;
return defineCompImport.type === "ImportDeclaration" && new RegExp("^@?vue(\\/|$)", "").test(defineCompImport.source.value);
}
function addProperty(t, object, property) {
if (t.isObjectExpression(object)) object.properties.unshift(property);
else if (t.isExpression(object)) return t.objectExpression([property, t.spreadElement(object)]);
return object;
}
//#endregion
module.exports = src_default;

View File

@@ -0,0 +1,173 @@
import { parseExpression } from "@babel/parser";
import { extractRuntimeEmits, extractRuntimeProps } from "@vue/compiler-sfc";
import { codeFrameColumns } from "@babel/code-frame";
import { addNamed } from "@babel/helper-module-imports";
import { declare } from "@babel/helper-plugin-utils";
//#region src/index.ts
const plugin = declare(({ types: t }, options) => {
let ctx;
let helpers;
return {
name: "babel-plugin-resolve-type",
pre(file) {
const filename = file.opts.filename || "unknown.js";
helpers = /* @__PURE__ */ new Set();
ctx = {
filename,
source: file.code,
options,
ast: file.ast.program.body,
isCE: false,
error(msg, node) {
throw new Error(`[@vue/babel-plugin-resolve-type] ${msg}\n\n${filename}\n${codeFrameColumns(file.code, {
start: {
line: node.loc.start.line,
column: node.loc.start.column + 1
},
end: {
line: node.loc.end.line,
column: node.loc.end.column + 1
}
})}`);
},
helper(key) {
helpers.add(key);
return `_${key}`;
},
getString(node) {
return file.code.slice(node.start, node.end);
},
propsTypeDecl: void 0,
propsRuntimeDefaults: void 0,
propsDestructuredBindings: {},
emitsTypeDecl: void 0
};
},
visitor: {
CallExpression(path) {
if (!ctx) throw new Error("[@vue/babel-plugin-resolve-type] context is not loaded.");
const { node } = path;
if (!t.isIdentifier(node.callee, { name: "defineComponent" })) return;
if (!checkDefineComponent(path)) return;
const comp = node.arguments[0];
if (!comp || !t.isFunction(comp)) return;
let options$1 = node.arguments[1];
if (!options$1) {
options$1 = t.objectExpression([]);
node.arguments.push(options$1);
}
let propsGenerics;
let emitsGenerics;
if (node.typeParameters && node.typeParameters.params.length > 0) {
propsGenerics = node.typeParameters.params[0];
emitsGenerics = node.typeParameters.params[1];
}
node.arguments[1] = processProps(comp, propsGenerics, options$1) || options$1;
node.arguments[1] = processEmits(comp, emitsGenerics, node.arguments[1]) || options$1;
},
VariableDeclarator(path) {
inferComponentName(path);
}
},
post(file) {
for (const helper of helpers) addNamed(file.path, `_${helper}`, "vue");
}
};
function inferComponentName(path) {
var _init$get;
const id = path.get("id");
const init = path.get("init");
if (!id || !id.isIdentifier() || !init || !init.isCallExpression()) return;
if (!((_init$get = init.get("callee")) === null || _init$get === void 0 ? void 0 : _init$get.isIdentifier({ name: "defineComponent" }))) return;
if (!checkDefineComponent(init)) return;
const nameProperty = t.objectProperty(t.identifier("name"), t.stringLiteral(id.node.name));
const { arguments: args } = init.node;
if (args.length === 0) return;
if (args.length === 1) init.node.arguments.push(t.objectExpression([]));
args[1] = addProperty(t, args[1], nameProperty);
}
function processProps(comp, generics, options$1) {
const props = comp.params[0];
if (!props) return;
if (props.type === "AssignmentPattern") {
if (generics) ctx.propsTypeDecl = resolveTypeReference(generics);
else ctx.propsTypeDecl = getTypeAnnotation(props.left);
ctx.propsRuntimeDefaults = props.right;
} else if (generics) ctx.propsTypeDecl = resolveTypeReference(generics);
else ctx.propsTypeDecl = getTypeAnnotation(props);
if (!ctx.propsTypeDecl) return;
const runtimeProps = extractRuntimeProps(ctx);
if (!runtimeProps) return;
const ast = parseExpression(runtimeProps);
return addProperty(t, options$1, t.objectProperty(t.identifier("props"), ast));
}
function processEmits(comp, generics, options$1) {
let emitType;
if (generics) emitType = resolveTypeReference(generics);
const setupCtx = comp.params[1] && getTypeAnnotation(comp.params[1]);
if (!emitType && setupCtx && t.isTSTypeReference(setupCtx) && t.isIdentifier(setupCtx.typeName, { name: "SetupContext" })) {
var _setupCtx$typeParamet;
emitType = (_setupCtx$typeParamet = setupCtx.typeParameters) === null || _setupCtx$typeParamet === void 0 ? void 0 : _setupCtx$typeParamet.params[0];
}
if (!emitType) return;
ctx.emitsTypeDecl = emitType;
const runtimeEmits = extractRuntimeEmits(ctx);
const ast = t.arrayExpression(Array.from(runtimeEmits).map((e) => t.stringLiteral(e)));
return addProperty(t, options$1, t.objectProperty(t.identifier("emits"), ast));
}
function resolveTypeReference(typeNode) {
if (!ctx) return;
if (t.isTSTypeReference(typeNode)) {
const typeName = getTypeReferenceName(typeNode);
if (typeName) {
const typeDeclaration = findTypeDeclaration(typeName);
if (typeDeclaration) return typeDeclaration;
}
}
}
function getTypeReferenceName(typeRef) {
if (t.isIdentifier(typeRef.typeName)) return typeRef.typeName.name;
else if (t.isTSQualifiedName(typeRef.typeName)) {
const parts = [];
let current = typeRef.typeName;
while (t.isTSQualifiedName(current)) {
if (t.isIdentifier(current.right)) parts.unshift(current.right.name);
current = current.left;
}
if (t.isIdentifier(current)) parts.unshift(current.name);
return parts.join(".");
}
return null;
}
function findTypeDeclaration(typeName) {
if (!ctx) return null;
for (const statement of ctx.ast) {
if (t.isTSInterfaceDeclaration(statement) && statement.id.name === typeName) return t.tsTypeLiteral(statement.body.body);
if (t.isTSTypeAliasDeclaration(statement) && statement.id.name === typeName) return statement.typeAnnotation;
if (t.isExportNamedDeclaration(statement) && statement.declaration) {
if (t.isTSInterfaceDeclaration(statement.declaration) && statement.declaration.id.name === typeName) return t.tsTypeLiteral(statement.declaration.body.body);
if (t.isTSTypeAliasDeclaration(statement.declaration) && statement.declaration.id.name === typeName) return statement.declaration.typeAnnotation;
}
}
return null;
}
});
var src_default = plugin;
function getTypeAnnotation(node) {
if ("typeAnnotation" in node && node.typeAnnotation && node.typeAnnotation.type === "TSTypeAnnotation") return node.typeAnnotation.typeAnnotation;
}
function checkDefineComponent(path) {
var _path$scope$getBindin;
const defineCompImport = (_path$scope$getBindin = path.scope.getBinding("defineComponent")) === null || _path$scope$getBindin === void 0 ? void 0 : _path$scope$getBindin.path.parent;
if (!defineCompImport) return true;
return defineCompImport.type === "ImportDeclaration" && new RegExp("^@?vue(\\/|$)", "").test(defineCompImport.source.value);
}
function addProperty(t, object, property) {
if (t.isObjectExpression(object)) object.properties.unshift(property);
else if (t.isExpression(object)) return t.objectExpression([property, t.spreadElement(object)]);
return object;
}
//#endregion
export { src_default as default };

View File

@@ -0,0 +1,45 @@
{
"name": "@vue/babel-plugin-resolve-type",
"version": "1.5.0",
"description": "Babel plugin for resolving Vue types.",
"author": "三咲智子 Kevin Deng <sxzz@sxzz.moe>",
"funding": "https://github.com/sponsors/sxzz",
"homepage": "https://github.com/vuejs/babel-plugin-jsx/tree/dev/packages/babel-plugin-resolve-type#readme",
"license": "MIT",
"type": "commonjs",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./package.json": "./package.json"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/babel-plugin-jsx.git"
},
"bugs": {
"url": "https://github.com/vuejs/babel-plugin-jsx/issues"
},
"files": [
"dist"
],
"peerDependencies": {
"@babel/core": "^7.0.0-0"
},
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/helper-module-imports": "^7.27.1",
"@babel/helper-plugin-utils": "^7.27.1",
"@babel/parser": "^7.28.0",
"@vue/compiler-sfc": "^3.5.18"
},
"devDependencies": {
"@babel/core": "^7.28.0",
"@types/babel__code-frame": "^7.0.6",
"vue": "^3.5.18"
}
}

View File

@@ -0,0 +1,62 @@
{
"name": "vite-plugin-vue-inspector",
"version": "5.3.2",
"description": "jump to local IDE source code while click the element of browser automatically.",
"author": "webfansplz",
"license": "MIT",
"homepage": "https://github.com/webfansplz/vite-plugin-vue-inspector#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/webfansplz/vite-plugin-vue-inspector.git"
},
"bugs": {
"url": "https://github.com/webfansplz/vite-plugin-vue-inspector/issues"
},
"keywords": [
"vue",
"vite",
"vscode",
"vite-plugin",
"inspector",
"debug"
],
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.cjs",
"import": "./dist/index.mjs"
},
"./src/*": "./src/*"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist",
"src/load.js",
"src/Overlay.vue"
],
"peerDependencies": {
"vite": "^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0"
},
"dependencies": {
"@babel/core": "^7.23.0",
"@babel/plugin-proposal-decorators": "^7.23.0",
"@babel/plugin-syntax-import-attributes": "^7.22.5",
"@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/plugin-transform-typescript": "^7.22.15",
"@vue/babel-plugin-jsx": "^1.1.5",
"@vue/compiler-dom": "^3.3.4",
"kolorist": "^1.8.0",
"magic-string": "^0.30.4"
},
"devDependencies": {
"@types/babel__core": "^7.20.2",
"unplugin": "^1.5.0"
},
"scripts": {
"lint": "eslint --fix --ext .js,.ts,.vue .",
"dev": "tsup --watch",
"build": "tsup"
}
}

File diff suppressed because one or more lines are too long

44
web/node_modules/vite-plugin-vue-inspector/src/load.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
/* eslint-disable new-cap */
import * as Vue from 'vue'
import App from 'virtual:vue-inspector-path:Overlay.vue'
import inspectorOptions from 'virtual:vue-inspector-options'
const CONTAINER_ID = 'vue-inspector-container'
function createInspectorContainer() {
if (document.getElementById(CONTAINER_ID) != null)
throw new Error('vueInspectorContainer element already exists')
const el = document.createElement('div')
el.setAttribute('id', CONTAINER_ID)
document.getElementsByTagName('body')[0].appendChild(el)
return el
}
function load() {
const isClient = typeof window !== 'undefined'
if (!isClient)
return
createInspectorContainer()
const { vue } = inspectorOptions
// vue 2/3 compatibility
vue === 3
? Vue.createApp({
render: () => Vue.h(App),
devtools: {
hide: true,
},
}).mount(`#${CONTAINER_ID}`)
: new Vue.default({
render: h => h(App),
devtools: {
hide: true,
},
}).$mount(`#${CONTAINER_ID}`)
}
if (inspectorOptions.lazyLoad)
setTimeout(load, inspectorOptions.lazyLoad)
else
load()