MMP 被Rollup文档的 id 参数命名误导 记轮子项目中写了一个Vite的插件,实现了处理自定义命名标签的功能
大纲链接 §
[toc]
插件需求
- 自定义块转换来转换
SFC
中的<demo>常规用法</demo>
- vite 在遇到 vue 文件的时候如何处理自定义块
- 封装插件方法,使用时传入需要转换的标签名
addSrcFromCustomBlock('demo')
创建 plugins/addSrcFromCustomBlock.ts
⇧
import {baseParse, ElementNode} from '@vue/compiler-core';
import fs from 'fs';
// 自定义块转换
// 可以告诉 vite 在遇到 vue 文件的时候如何处理自定义块 <example>
// 获取组件源码 Component.__sourceCode
// 获取组件标题 Component.__sourceCodeTitle 等价于 code
export function addSrcFromCustomBlock(customBlockName: string) {
const regexp = new RegExp(`vue&type=${customBlockName}`);
return {
name: 'vueCustomBlockTransforms',
transform: (code: string, id: string) => {
if (!regexp.test(id)) {
return;
}
const path = id
.replace(`?vue&type=${customBlockName}&index=0&lang.${customBlockName}`,
'');
const fileString = fs.readFileSync(path).toString();
const parsed = baseParse(fileString).children.find((n) => (n as ElementNode).tag === 'demo');
const scriptTag = baseParse(fileString).children.find(n => (n as ElementNode).tag === 'script');
// demo 标题
const title = code; // @ts-ignore // const title = parsed.children[0].content;
// 去掉demo标签和纯script后需要显示的代码主体
const main = fileString.split(parsed.loc.source).join('').split(scriptTag.loc.source).join('').trim();
return `export default function (Component) {
Component.__sourceCode = ${JSON.stringify(main)}
Component.__sourceCodeTitle = ${JSON.stringify(title)}
}`.trim();
},
};
}
- 核心方法是
transform(code: string, id: string) {}
引入到 vite.config.ts
// vueCustomBlockTransforms
import {addSrcFromCustomBlock} from './plugins/addSrcFromCustomBlock';
export const basicConfig = defineConfig({
plugins: [
addSrcFromCustomBlock('demo')
],
});
vite
插件 rollup
文档的 参数命名误导 id
- 处理自定义标签
<demo></demo>
- vite 1.x 迁移 自定义块转换
transform(code, id)
中的id
其实所解析到的文件的 url- 使用正则匹配
/vue&type=demo/.test(id)
- 去除多余的查询参数得到该文件路径
const path = id.replace(`?vue&type=demo&index=0&lang.demo`,'');
- 按路径读取文件内容
const fileString = fs.readFileSync(path).toString();
- 找出
<demo></demo>
标签节点,并且得到文本const parsed = baseParse(fileString).children.find(n => n.tag === 'demo');
const title = parsed.children[0].content;
- 得到代码主体
const main = fileString.split(parsed.loc.source).join('').trim();
- 给组件附加属性
Component.__sourceCode = ${JSON.stringify(main)}
Component.__sourceCodeTitle = ${JSON.stringify(title)}
- 在模板字符串中返回 方法
return `export default function (Component) { Component.__sourceCode = ${JSON.stringify(main)} Component.__sourceCodeTitle = ${JSON.stringify(title)} }`.trim();
如何解决
- TLDR 如果不想通读文档的话,只能在开发过程中使用
console.log
来调试
·未完待续·
参考文章
- rollupjs transform
- rollupjs transformers
- Plugin Development
- New hook for transforming ids
- Vite2 插件 API
- Vite3 插件 API
相关文章
- 作者: Joel
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名
转载自:https://juejin.cn/post/7145621729178550285