|
- // src/core/utils.ts
- function getChildrenLocation(node) {
- if (node.children.length > 0) {
- const lastChild = node.children[node.children.length - 1];
- return [node.children[0].loc.start.offset, lastChild.loc.end.offset];
- } else {
- return void 0;
- }
- }
- function parseVueRequest(id) {
- const [filename, rawQuery] = id.split(`?`, 2);
- const query = Object.fromEntries(new URLSearchParams(rawQuery));
- if (query.vue != null) {
- query.vue = true;
- }
- if (query.index != null) {
- query.index = Number(query.index);
- }
- if (query.raw != null) {
- query.raw = true;
- }
- if (query.url != null) {
- query.url = true;
- }
- if (query.scoped != null) {
- query.scoped = true;
- }
- return {
- filename,
- query
- };
- }
-
- // src/core/constants.ts
- var QUERY_NAMED_TEMPLATE = "?vue&type=named-template";
- var QUERY_TEMPLATE = "type=template&namedTemplate";
- var QUERY_TEMPLATE_MAIN = `${QUERY_TEMPLATE}&mainTemplate`;
- var MAIN_TEMPLATE = Symbol();
-
- // src/core/index.ts
- import {
- HELPER_PREFIX,
- MagicString,
- babelParse,
- getLang,
- getTransformResult,
- importHelperFn,
- isCallOf,
- walkAST
- } from "@vue-macros/common";
- import { createTransformContext, parse, traverseNode } from "@vue/compiler-dom";
- function transformTemplateIs(s) {
- return (node) => {
- if (!(node.type === 1 && node.tag === "template"))
- return;
- const propIs = node.props.find(
- (prop) => prop.type === 6 && prop.name === "is"
- );
- if (!(propIs == null ? void 0 : propIs.value))
- return;
- const refName = propIs.value.content;
- s.overwrite(
- node.loc.start.offset,
- node.loc.end.offset,
- `<component is="named-template-${refName}" />`
- );
- };
- }
- function preTransform(code, id, templateContent) {
- const root = parse(code);
- const templates = root.children.filter(
- (node) => node.type === 1 && node.tag === "template"
- );
- if (templates.length <= 1)
- return;
- const s = new MagicString(code);
- for (const node of templates) {
- const propName = node.props.find(
- (prop) => prop.type === 6 && prop.name === "name"
- );
- if (!propName) {
- preTransformMainTemplate({ s, root, node, id, templateContent });
- continue;
- } else if (!propName.value) {
- continue;
- }
- const name = propName.value.content;
- let template = "";
- const templateLoc = getChildrenLocation(node);
- if (templateLoc) {
- template = s.slice(...templateLoc);
- }
- if (!templateContent[id])
- templateContent[id] = {};
- templateContent[id][name] = template;
- s.appendLeft(node.loc.start.offset, `<named-template name="${name}">`);
- s.appendLeft(node.loc.end.offset, "</named-template>");
- }
- return getTransformResult(s, id);
- }
- function preTransformMainTemplate({
- s,
- root,
- node,
- id,
- templateContent
- }) {
- const ctx = createTransformContext(root, {
- filename: id,
- nodeTransforms: [transformTemplateIs(s)]
- });
- traverseNode(node, ctx);
- const loc = getChildrenLocation(node);
- if (!loc)
- return;
- if (!templateContent[id])
- templateContent[id] = {};
- templateContent[id][MAIN_TEMPLATE] = s.slice(...loc);
- s.remove(...loc);
- const offset = node.loc.start.offset + 1 + node.tag.length;
- s.appendLeft(offset, ` src="${`${id}?vue&${QUERY_TEMPLATE_MAIN}`}"`);
- }
- function postTransform(code, id, customBlocks) {
- var _a, _b, _c;
- const lang = getLang(id);
- const program = babelParse(code, lang);
- const { filename } = parseVueRequest(id);
- if (!id.includes(QUERY_TEMPLATE_MAIN)) {
- postTransformMainEntry(program, filename, customBlocks);
- return;
- }
- const s = new MagicString(code);
- const subTemplates = [];
- for (const node of program.body) {
- if (node.type === "ExportNamedDeclaration" && ((_a = node.declaration) == null ? void 0 : _a.type) === "FunctionDeclaration" && ((_b = node.declaration.id) == null ? void 0 : _b.name) === "render") {
- const params = node.declaration.params;
- if (params.length > 0) {
- const lastParams = params[node.declaration.params.length - 1];
- const loc = [params[0].start, lastParams.end];
- const paramsText = s.slice(...loc);
- s.overwrite(...loc, "...args");
- s.appendLeft(
- node.declaration.body.start + 1,
- `
- let [${paramsText}] = args`
- );
- }
- }
- }
- walkAST(program, {
- enter(node) {
- if (isCallOf(node, ["_createVNode", "_createBlock"]) && isCallOf(node.arguments[0], "_resolveDynamicComponent") && node.arguments[0].arguments[0].type === "StringLiteral" && node.arguments[0].arguments[0].value.startsWith("named-template-")) {
- subTemplates.push({
- vnode: node,
- component: node.arguments[0],
- name: node.arguments[0].arguments[0].value.replace(
- "named-template-",
- ""
- ),
- fnName: node.callee.name
- });
- }
- }
- });
- if (subTemplates.length === 0)
- return;
- for (const { vnode, component, name, fnName } of subTemplates) {
- const block = (_c = customBlocks[filename]) == null ? void 0 : _c[name];
- if (!block)
- throw new SyntaxError(`Unknown named template: ${name}`);
- const render = `${HELPER_PREFIX}block_${escapeTemplateName(
- name
- )}.render(...args)`;
- if (fnName === "_createVNode") {
- s.overwriteNode(vnode, render);
- } else if (fnName === "_createBlock") {
- importHelperFn(s, 0, "Fragment", "vue");
- s.overwriteNode(component, `${HELPER_PREFIX}Fragment`);
- const text = `${vnode.arguments[1] ? "" : ", null"}, [${render}]`;
- s.appendLeft((vnode.arguments[1] || vnode.arguments[0]).end, text);
- }
- }
- for (const [name, source] of Object.entries(customBlocks[filename])) {
- s.prepend(
- `import { default as ${HELPER_PREFIX}block_${escapeTemplateName(
- name
- )} } from ${JSON.stringify(source)}
- `
- );
- }
- return getTransformResult(s, id);
- }
- function postTransformMainEntry(program, id, customBlocks) {
- for (const node of program.body) {
- if (node.type === "ImportDeclaration" && node.source.value.includes(QUERY_NAMED_TEMPLATE)) {
- const { name } = parseVueRequest(node.source.value).query;
- if (!customBlocks[id])
- customBlocks[id] = {};
- customBlocks[id][name] = node.source.value;
- }
- }
- }
- function escapeTemplateName(name) {
- return name.replace(/-/g, "$DASH");
- }
-
- export {
- getChildrenLocation,
- parseVueRequest,
- QUERY_NAMED_TEMPLATE,
- QUERY_TEMPLATE,
- QUERY_TEMPLATE_MAIN,
- MAIN_TEMPLATE,
- transformTemplateIs,
- preTransform,
- preTransformMainTemplate,
- postTransform,
- postTransformMainEntry
- };
|