版本信息
JSON
"vite": "^4.3.0"
要解决一个什么问题
公司的一个 React 多页项目,所有页面都放在项目 src/pages 目录下,像这样:
然后 vite.config.js 里头入口是这么配置的:
ts
rollupOptions: {
input: {
exam: resolve(__dirname, 'src/pages/hhh/exam.html'),
test: resolve(__dirname, 'src/pages/test.html'),
}
}
这似乎非常合理,但是后面每当开发一个新页面的时候,你就得往 input 里面加一条,不管是看起来还是写起来都多少有点睿智。那既然所有页面都放在 pages 目录下,能不能改一下自动读取 pages 目录下的文件,然后打包,做到自动的多输入多输出?
解决的办法
Vite 本身基于 node 环境,完全可以利用 node 去访问指定目录,通过递归获取 Rollup 的 input 对象。
ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { join } from 'path';
import fs from 'fs'
const calcInputObject = () => {
const inputObject = {};
// 递归遍历文件夹
const recursiveFunc = (dir: string) => {
fs.readdirSync(dir)
.forEach((fileName: string) => {
const fullpath = join(dir, fileName);
const stats = fs.statSync(fullpath);
if (stats.isDirectory()) {
// 是文件夹接着归
recursiveFunc(fullpath);
} else {
inputObject[fileName.split('.')[0]] = fullpath
}
})
}
const sourcePath = join(__dirname, 'pages');
recursiveFunc(sourcePath);
return inputObject
}
export default defineConfig(() => {
return {
plugins: [react()],
build: {
rollupOptions: {
input: calcInputObject();
},
},
}
})
打包出来的结果:
后续还可以基于此增加 exclude 功能,排除目录中不需要的内容。
弯弯绕绕
在翻阅 Rollup 资料的时候,有好心人提到可以用 Rollup 的 multi-entry 插件来实现。但是正如人家 Readme 中写的一样
A Rollup plugin which allows use of multiple entry points for a bundle.
他的确可以读取指定目录下的文件,但是只输出一个 JS bundle ,我们总不能让用户访问一个页面的时候就让他把整个项目都给 down 下来吧。溜达了一圈,似乎也没有什么清晰的方式可以做到多输出,遂作罢。