这是一个“动态引入插件”的开发教程
最主要使用的插件api是resolveId和load
1. 首先vite插件接收的是一个对象
假如我们的插件命名为vite-dynamic-import
{
name: "vite-dynamic-import";
}
这样我们的插件就创建完成了~
2.一般我们可以给插件定义一个函数
export default function dynamicImport() {
return {
name: "vite-dynamic-import",
};
}
3.resolveId 我们可以使用resolveId来处理需要被插件处理的文件
resolveId你可以理解为一个过滤器,当发现一些特殊的import规则/路径时,需要给找出来
export default function dynamicImport() {
return {
name: "vite-dynamic-import",
resolveId(source, importer) {
if (source.endsWith("?dynamic_import")) {
// 这里是为了让我们在代码里可以相当路径
const resolvedPath = path.resolve(
path.dirname(importer),
source.replace("?dynamic_import", "")
);
return resolvedPath + "?dynamic_import";
}
},
};
}
4.用load来处理编译前的引入阶段
load就是说在import的这些文件被编译之前的阶段,我们相当于可以对源代码进行修改,当然这个修改不是真的修改代码,而是你理解为被vite载入到内存里的代码
export default function dynamicImport() {
return {
name: "vite-dynamic-import",
resolveId(source, importer) {
if (source.endsWith("?dynamic_import")) {
// 这里是为了让我们在代码里可以相当路径
const resolvedPath = path.resolve(
path.dirname(importer),
source.replace("?dynamic_import", "")
);
return resolvedPath + "?dynamic_import";
}
},
load(id, options) {
if (id.endsWith("?dynamic_import")) {
const dirPath = path.resolve(id.replace('?dynamic_import', ''))
const files = fs.readdirSync(dirPath)
const imports = files.map(file => {
// 利用path.extname取出文件扩展名
const fileExt = path.extname(file);
// 利用path.basename取出文件名
const name = path.basename(file, fileExt)
return `import ${name} from "${path.join(dirPath, file)}"`
}).join('\n')
var exportObjectKeysString = files.map(file => {
const name = path.basename(file, fileExt)
return " " + name
}).join(',\n')
const exportObject = 'const markdownPaths = {\n' + exportObjectKeysString + '\n}'
return `${imports}\n\n${exportObject}\n\nexport default markdownPaths`
}
},
};
}
5.vite-config配置
plugins: [
react(),
dynamicImport(),
...
]
最后呈现的效果就是
// 这里我们只需要引入一句
import markdownPaths from "./docs?dynamic_import";
// 就可以达到如下的这个效果
// import a from "./docs/a.md";
// import b from "./docs/b.md";
// import c from "./docs/c.md";
// const markdownPaths = {
// a,
// b,
// c
// };