需求
最近有一个基建类库,是需要这个库可以按需引用或全量引用。原因在于这个库里面会同时使用在PC、小程序的环境,因此需要依赖由宿主包提供,同时避免包体积过大
Vite 库模式的缺陷
Vite 本身有 build.lib 配置项,其支持配置一个入口,入口项 entry 为 string 类型。从文档看,Vite 默认打包是全量打包,只有一个入口文件,里面需要引用类库的所有源码。Vite 会解析入口文件并压缩
根据官方文档,Vite 使用 Rollup 打包你的代码,并且它是预配置的。可以通过 rollupOptions 进行配置,其支持多入口文件配置
// 以下示例仅供参考
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
const path = require('path')
// 解决node-fs读取文件夹效率低问题
const fg = require('fast-glob')
const outDir = path.resolve(__dirname, 'lib')
const rollupOptions = {
input: {},
output: {
globals: {
react: 'React',
},
},
// 确保外部化处理那些你不想打包进库的依赖
external: [],
}
const genEntries = async () => {
const entries = fg.sync(`src/**/*.*`, {
onlyFiles: false,
deep: Infinity,
})
entries.forEach((entry: string) => {
const FILE_TYPE_SUFFIX_REG = /\.[t|j]s?$/g
const TEST_FILE_REG = /__tests__/g
if (FILE_TYPE_SUFFIX_REG.test(entry) && !TEST_FILE_REG.test(entry)) {
const fileOutDir = entry.replace(FILE_TYPE_SUFFIX_REG, '')
rollupOptions.input = {
...rollupOptions.input,
[fileOutDir]: entry,
}
}
})
}
genEntries()
Vite 构建配置开启库模式,同时将引入之前的 rollupOptions,实现多入口构建
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
json: {
// 是否支持从 .json 文件中进行按名导入
namedExports: true,
// 若设置为 true, 导入的 JSON 会被转换为 export default JSON.parse("...") 会比转译成对象字面量性能更好
// 尤其是当 JSON 文件较大时
// 开启此项, 则会禁用按名导入
stringify: false,
},
build: {
outDir,
lib: {
// 使用 rollup 多入口构建,lib 模式 entry 字段为空即可
entry: '',
fileName: format => `${format}/[name].js`,
formats: ['cjs', 'es'],
},
manifest: false,
rollupOptions,
commonjsOptions: {},
emptyOutDir: true,
// chunk 大小警告的限制
chunkSizeWarningLimit: 500,
},
})
node-fs 多层级读取文件的弊端
自带的 node-fs 循环或递归读取文件带来以下问题。node-fs 文件夹层级太深读取文件效率低,虽然类库的目录结构比较简单,但是有可能会出现嵌套文件夹
使用 fast-glob 替代 node-fs 读取文件
fast-glob It's a very fast and efficient glob library for Node.js.