這是一個(gè)“動(dòng)態(tài)引入插件”的開發(fā)教程
最主要使用的插件api是resolveId和load
1. 首先vite插件接收的是一個(gè)對象
假如我們的插件命名為vite-dynamic-import
{
name: "vite-dynamic-import";
}
這樣我們的插件就創(chuàng)建完成了~
2.一般我們可以給插件定義一個(gè)函數(shù)
export default function dynamicImport() {
return {
name: "vite-dynamic-import",
};
}
3.resolveId 我們可以使用resolveId來處理需要被插件處理的文件
resolveId你可以理解為一個(gè)過濾器,當(dāng)發(fā)現(xiàn)一些特殊的import規(guī)則/路徑時(shí),需要給找出來
export default function dynamicImport() {
return {
name: "vite-dynamic-import",
resolveId(source, importer) {
if (source.endsWith("?dynamic_import")) {
// 這里是為了讓我們在代碼里可以相當(dāng)路徑
const resolvedPath = path.resolve(
path.dirname(importer),
source.replace("?dynamic_import", "")
);
return resolvedPath + "?dynamic_import";
}
},
};
}
4.用load來處理編譯前的引入階段
load就是說在import的這些文件被編譯之前的階段,我們相當(dāng)于可以對源代碼進(jìn)行修改,當(dāng)然這個(gè)修改不是真的修改代碼,而是你理解為被vite載入到內(nèi)存里的代碼
export default function dynamicImport() {
return {
name: "vite-dynamic-import",
resolveId(source, importer) {
if (source.endsWith("?dynamic_import")) {
// 這里是為了讓我們在代碼里可以相當(dāng)路徑
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取出文件擴(kuò)展名
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(),
...
]
最后呈現(xiàn)的效果就是
// 這里我們只需要引入一句
import markdownPaths from "./docs?dynamic_import";
// 就可以達(dá)到如下的這個(gè)效果
// import a from "./docs/a.md";
// import b from "./docs/b.md";
// import c from "./docs/c.md";
// const markdownPaths = {
// a,
// b,
// c
// };