vue-jsx-vapor
Version:
Convert Vue JSX to Vapor
220 lines (214 loc) • 11.5 kB
JavaScript
const require_chunk = require('./chunk-CUT6urMc.cjs');
const require_core = require('./core-BEqRwfoK.cjs');
const __babel_core = require_chunk.__toESM(require("@babel/core"));
const __babel_plugin_transform_typescript = require_chunk.__toESM(require("@babel/plugin-transform-typescript"));
const __vue_jsx_vapor_macros_raw = require_chunk.__toESM(require("@vue-jsx-vapor/macros/raw"));
const __vue_macros_jsx_directive_api = require_chunk.__toESM(require("@vue-macros/jsx-directive/api"));
const unplugin_utils = require_chunk.__toESM(require("unplugin-utils"));
const __vue_jsx_vapor_macros_api = require_chunk.__toESM(require("@vue-jsx-vapor/macros/api"));
const hash_sum = require_chunk.__toESM(require("hash-sum"));
const pathe = require_chunk.__toESM(require("pathe"));
const __vue_babel_plugin_jsx = require_chunk.__toESM(require("@vue/babel-plugin-jsx"));
//#region src/core/ssr.ts
const ssrRegisterHelperId = "/__vue-jsx-ssr-register-helper";
const ssrRegisterHelperCode = `import { useSSRContext } from "vue"\nexport const ssrRegisterHelper = ${ssrRegisterHelper.toString()}`;
/**
* This function is serialized with toString() and evaluated as a virtual
* module during SSR
*/
function ssrRegisterHelper(comp, filename) {
const setup = comp.setup;
comp.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add(filename);
if (setup) return setup(props, ctx);
};
}
function injectSSR(id, hotComponents, root = "") {
const normalizedId = (0, unplugin_utils.normalizePath)((0, pathe.relative)(root, id));
let ssrInjectCode = `\nimport { ssrRegisterHelper } from "${ssrRegisterHelperId}"\nconst __moduleId = ${JSON.stringify(normalizedId)}`;
for (const { local } of hotComponents) ssrInjectCode += `\nssrRegisterHelper(${local}, __moduleId)`;
return ssrInjectCode;
}
//#endregion
//#region src/core/hmr.ts
function injectHMRAndSSR(result, id, options) {
const ssr = options?.ssr;
const defineComponentNames = options?.defineComponentNames ?? ["defineComponent", "defineVaporComponent"];
const { ast } = result;
const declaredComponents = [];
const hotComponents = [];
let hasDefaultExport = false;
for (const node of ast.program.body) {
if (node.type === "VariableDeclaration") {
const names = parseComponentDecls(node, defineComponentNames);
if (names.length) declaredComponents.push(...names);
}
if (node.type === "ExportNamedDeclaration") {
if (node.declaration && node.declaration.type === "VariableDeclaration") hotComponents.push(...parseComponentDecls(node.declaration, defineComponentNames).map((name) => ({
local: name,
exported: name,
id: (0, hash_sum.default)(id + name)
})));
else if (node.specifiers.length) {
for (const spec of node.specifiers) if (spec.type === "ExportSpecifier" && spec.exported.type === "Identifier") {
const matched = declaredComponents.find((name) => name === spec.local.name);
if (matched) hotComponents.push({
local: spec.local.name,
exported: spec.exported.name,
id: (0, hash_sum.default)(id + spec.exported.name)
});
}
}
}
if (node.type === "ExportDefaultDeclaration") {
if (node.declaration.type === "Identifier") {
const _name = node.declaration.name;
const matched = declaredComponents.find((name) => name === _name);
if (matched) hotComponents.push({
local: _name,
exported: "default",
id: (0, hash_sum.default)(`${id}default`)
});
} else if (isDefineComponentCall(node.declaration, defineComponentNames) || (0, __vue_jsx_vapor_macros_api.isFunctionalNode)(node.declaration)) {
hasDefaultExport = true;
hotComponents.push({
local: "__default__",
exported: "default",
id: (0, hash_sum.default)(`${id}default`)
});
}
}
}
if (hotComponents.length) {
if (hasDefaultExport || ssr) result.code = `${result.code.replaceAll(`export default `, `const __default__ = `)}\nexport default __default__`;
if (!ssr && !/\?vue&type=script/.test(id)) {
let code = result.code;
let callbackCode = ``;
for (const { local, exported, id: id$1 } of hotComponents) {
code += `\n${local}.__hmrId = "${id$1}"\n__VUE_HMR_RUNTIME__.createRecord("${id$1}", ${local})`;
callbackCode += `
__VUE_HMR_RUNTIME__.rerender(mod['${exported}'].__hmrId, mod['${exported}'].setup || mod['${exported}'])`;
}
code += `
if (import.meta.hot) {
import.meta.hot.accept((mod) => {${callbackCode}\n})
}`;
result.code = code;
}
if (ssr) result.code += injectSSR(id, hotComponents, options?.root);
}
}
function parseComponentDecls(node, fnNames) {
const names = [];
for (const decl of node.declarations) if (decl.id.type === "Identifier" && (isDefineComponentCall(decl.init, fnNames) || (0, __vue_jsx_vapor_macros_api.isFunctionalNode)(decl.init))) names.push(decl.id.name);
return names;
}
function isDefineComponentCall(node, names) {
return !!(node && node.type === "CallExpression" && node.callee.type === "Identifier" && names.includes(node.callee.name));
}
//#endregion
//#region src/core/runtime.ts?raw
var runtime_default = "import {\n EffectScope,\n insert,\n isFragment,\n isVaporComponent,\n proxyRefs,\n remove,\n renderEffect,\n toRefs,\n useAttrs,\n VaporFragment\n} from \"vue\";\nimport * as Vue from \"vue\";\nexport { shallowRef as useRef } from \"vue\";\nexport function getCurrentInstance() {\n return Vue.currentInstance || Vue.getCurrentInstance();\n}\nexport function useProps() {\n const i = getCurrentInstance();\n return i.props;\n}\nexport function useFullProps() {\n return proxyRefs({\n ...toRefs(useProps()),\n ...toRefs(useAttrs())\n });\n}\nfunction createFragment(nodes, anchor = document.createTextNode(\"\")) {\n const frag = new VaporFragment(nodes);\n frag.anchor = anchor;\n return frag;\n}\nfunction normalizeNode(node, anchor) {\n if (node instanceof Node || isFragment(node)) {\n anchor && (anchor.textContent = \"\");\n return node;\n } else if (isVaporComponent(node)) {\n anchor && (anchor.textContent = \"\");\n return createFragment(node, anchor);\n } else if (Array.isArray(node)) {\n anchor && (anchor.textContent = \"\");\n return createFragment(\n node.map((i) => normalizeNode(i)),\n anchor\n );\n } else {\n const result = node == null || typeof node === \"boolean\" ? \"\" : String(node);\n if (anchor) {\n anchor.textContent = result;\n return anchor;\n } else {\n return document.createTextNode(result);\n }\n }\n}\nfunction resolveValue(current, value, _anchor) {\n const node = normalizeNode(value, _anchor);\n if (current) {\n if (isFragment(current)) {\n const { anchor } = current;\n if (anchor && anchor.parentNode) {\n remove(current.nodes, anchor.parentNode);\n insert(node, anchor.parentNode, anchor);\n !_anchor && anchor.parentNode.removeChild(anchor);\n }\n } else if (current instanceof Node) {\n if (isFragment(node) && current.parentNode) {\n insert(node, current.parentNode, current);\n current.parentNode.removeChild(current);\n } else if (node instanceof Node) {\n if (current.nodeType === 3 && node.nodeType === 3) {\n current.textContent = node.textContent;\n return current;\n } else if (current.parentNode) {\n current.parentNode.replaceChild(node, current);\n }\n }\n }\n }\n return node;\n}\nfunction resolveValues(values = [], _anchor) {\n const nodes = [];\n const frag = createFragment(nodes, _anchor);\n const scopes = [];\n for (const [index, value] of values.entries()) {\n const anchor = index === values.length - 1 ? _anchor : void 0;\n if (typeof value === \"function\") {\n renderEffect(() => {\n if (scopes[index]) scopes[index].stop();\n scopes[index] = new EffectScope();\n nodes[index] = scopes[index].run(\n () => resolveValue(nodes[index], value(), anchor)\n );\n });\n } else {\n nodes[index] = resolveValue(nodes[index], value, anchor);\n }\n }\n return frag;\n}\nexport function setNodes(anchor, ...values) {\n const resolvedValues = resolveValues(values, anchor);\n anchor.parentNode && insert(resolvedValues, anchor.parentNode, anchor);\n}\nexport function createNodes(...values) {\n return resolveValues(values);\n}\n";
//#endregion
//#region src/core/vue-jsx.ts
function transformVueJsx(code, id, needSourceMap = false) {
const result = (0, __babel_core.transformSync)(code, {
plugins: [__vue_babel_plugin_jsx.default, ...id.endsWith(".tsx") ? [[__babel_plugin_transform_typescript.default, {
isTSX: true,
allowExtensions: true
}]] : []],
filename: id,
sourceMaps: needSourceMap,
sourceFileName: id,
babelrc: false,
configFile: false
});
if (result?.code) return {
code: result.code,
map: result.map
};
}
//#endregion
//#region src/raw.ts
const plugin = (options = {}) => {
const transformInclude = (0, unplugin_utils.createFilter)(options?.include || /\.[cm]?[jt]sx$/, options?.exclude || /node_modules/);
let root = "";
let needHMR = false;
let needSourceMap = options.sourceMap || false;
return [
{
name: "vue-jsx-vapor",
vite: {
config(config) {
return {
esbuild: { include: /\.ts$/ },
define: {
__VUE_OPTIONS_API__: config.define?.__VUE_OPTIONS_API__ ?? true,
__VUE_PROD_DEVTOOLS__: config.define?.__VUE_PROD_DEVTOOLS__ ?? false,
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: config.define?.__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ ?? false
}
};
},
configResolved(config) {
root = config.root;
needHMR = config.command === "serve";
needSourceMap ||= config.command === "serve" || !!config.build.sourcemap;
}
},
resolveId(id) {
if (id === ssrRegisterHelperId) return id;
if ((0, unplugin_utils.normalizePath)(id) === "vue-jsx-vapor/runtime") return id;
},
loadInclude(id) {
if (id === ssrRegisterHelperId) return true;
return (0, unplugin_utils.normalizePath)(id) === "vue-jsx-vapor/runtime";
},
load(id) {
if (id === ssrRegisterHelperId) return ssrRegisterHelperCode;
if ((0, unplugin_utils.normalizePath)(id) === "vue-jsx-vapor/runtime") return runtime_default;
},
transformInclude,
transform(code, id, opt) {
const result = require_core.transformVueJsxVapor(code, id, options, needSourceMap);
if (result?.code) {
(needHMR || opt?.ssr) && injectHMRAndSSR(result, id, {
ssr: opt?.ssr,
root
});
return {
code: result.code,
map: result.map
};
}
}
},
{
name: "@vue-macros/jsx-directive",
transformInclude,
transform(code, id, opt) {
if (options.interop || opt?.ssr) return (0, __vue_macros_jsx_directive_api.transformJsxDirective)(code, id, {
lib: "vue",
prefix: "v-",
version: 3.6
});
}
},
{
name: "@vitejs/plugin-vue-jsx",
transformInclude,
transform(code, id, opt) {
if (options.interop || opt?.ssr) return transformVueJsx(code, id, needSourceMap);
}
},
...options.macros === false ? [] : options.macros ? [(0, __vue_jsx_vapor_macros_raw.default)(options.macros === true ? void 0 : options.macros)] : []
];
};
var raw_default = plugin;
//#endregion
Object.defineProperty(exports, 'raw_default', {
enumerable: true,
get: function () {
return raw_default;
}
});