beesbuild
Version:
构建工具链
119 lines (118 loc) • 3.12 kB
JavaScript
import * as compiler from "@vue/compiler-dom";
function createBlock(node, source) {
const type = node.tag;
let { start, end } = node.loc;
let content = "";
if (node.children.length) {
start = node.children[0].loc.start;
end = node.children[node.children.length - 1].loc.end;
content = source.slice(start.offset, end.offset);
} else {
const offset = node.loc.source.indexOf(`</`);
if (offset > -1) {
start = {
line: start.line,
column: start.column + offset,
offset: start.offset + offset
};
}
end = Object.assign({}, start);
}
const loc = {
source: content,
start,
end
};
const attrs = {};
const block = {
type,
content,
loc,
attrs
};
node.props.forEach((p) => {
var _a, _b, _c, _d;
if (p.type === compiler.NodeTypes.ATTRIBUTE) {
attrs[p.name] = p.value ? p.value.content || true : true;
if (p.name === "lang") {
block.lang = p.value && p.value.content;
} else if (p.name === "src") {
block.src = p.value && p.value.content;
} else if (type === "style") {
if (p.name === "scoped") {
block.scoped = true;
} else if (p.name === "module") {
block.module = {
name: (_b = (_a = p.value) == null ? void 0 : _a.content) != null ? _b : "$style",
offset: ((_c = p.value) == null ? void 0 : _c.content) ? ((_d = p.value) == null ? void 0 : _d.loc.start.offset) - node.loc.start.offset : void 0
};
}
} else if (type === "script" && p.name === "setup") {
block.setup = attrs.setup;
}
}
});
return block;
}
function parse(source) {
const errors = [];
const ast = compiler.parse(source, {
// SFC 解析级别没有组件
isNativeTag: () => true,
// 保留所有空格
isPreTag: () => true,
parseMode: "sfc",
onError: (e) => {
errors.push(e);
},
comments: true
});
const descriptor = {
filename: "anonymous.vue",
source,
template: null,
script: null,
scriptSetup: null,
styles: [],
customBlocks: [],
cssVars: [],
slotted: false,
shouldForceReload: () => false
};
ast.children.forEach((node) => {
if (node.type !== compiler.NodeTypes.ELEMENT) {
return;
}
switch (node.tag) {
case "template":
descriptor.template = createBlock(node, source);
break;
case "script":
const scriptBlock = createBlock(node, source);
const isSetup = !!scriptBlock.attrs.setup;
if (isSetup && !descriptor.scriptSetup) {
descriptor.scriptSetup = scriptBlock;
break;
}
if (!isSetup && !descriptor.script) {
descriptor.script = scriptBlock;
break;
}
break;
case "style":
const styleBlock = createBlock(node, source);
descriptor.styles.push(styleBlock);
break;
default:
descriptor.customBlocks.push(createBlock(node, source));
break;
}
});
return {
descriptor,
errors
};
}
export {
parse
};