rollup打包vue虚拟组件
为了实现在线版的vitepress将md文件内容转为html,并且提供vue支持,可以在md中编写或引入vue并展示。所以需要实现rollup打包vue虚拟组件的功能。
具体步骤:md文件=》html字符串 =》 vue文件 =》 rollup打包 =》 js代码 实现
将md文件渲染为html字符串
使用markdown-it实现转换 例如:
<script lang="ts" setup>
import MyButton from '@/compoent/Button.vue'
const content = 'pageContent ...'
</script>
# title
## subTitle
{{content}}
<MyButton>submit</MyButton>
<script lang="ts" setup>
import MyButton from '@/compoent/Button.vue'
const content = 'pageContent ...'
</script>
<h1>title</h1>
<h2>subTitle</h2>
<p>{{content}}</p>
<MyButton>submit</MyButton>
将虚拟vue文件变为js代码
<script lang="ts" setup>
import MyButton from '@/compoent/Button.vue'
const content = 'pageContent ...'
</script>
<template>
<div>
<h1>title</h1>
<h2>subTitle</h2>
<p>{{content}}</p>
<MyButton>submit</MyButton>
</div>
</template>
<h1>title</h1>
<h2>subTitle</h2>
<p>pageContent ...</p>
<button class="mybutton">submit</button>
rollup打包配置
目标是一个支持severless,一件部署的文档工具。 由于要支持severless所以,不支持写文件,要使用memfs库实现在内存中读写文件。
const vol = Volume.fromJSON({
"virtual.vue": str,// 虚拟vue组件代码
});
const fsVol = createFsFromVolume(vol);
const myfs = {
promises: {
readFile: (filePath: string, options?: any) => {
if (filePath === "virtual.vue")
return fsVol.promises.readFile(filePath, options);
else return fs.promises.readFile(filePath, options);
}
},
};
const bundle = await rollup({
input: ["virtual.vue"],
//@ts-ignore
fs: myfs.promises,
external: ["vue"],
plugins: [
vue({
preprocessStyles: true,
}),
postcss({
inject: true,
}),
nodeResolve({
extensions:['.js','.ts','.vue']
}),
commonjs(),
esbuild({
target: "es2022",
optimizeDeps: {
esbuildOptions: {},
include: [],
},
sourceMap: false,
loaders: {
".vue": "ts",
},
}),
],
});
const { output } = await bundle.generate({format:'esm'})
console.log("output[0].code: ",output[0].code);
打包后效果
import { defineComponent, createElementBlock, openBlock, createElementVNode, createVNode } from 'vue';
var script = /* @__PURE__ */ defineComponent({
__name: "virtual",
setup(__props) {
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", null, [
_cache[0] || (_cache[0] = createElementVNode(
"h1",
null,
"test1",
-1
/* CACHED */
)),
createVNode(script$1, { name: "more" })
]);
};
}
});
script.__file = "virtual.vue";
export { script as default };
这样就支持在浏览器端import并且使用了