如何实现目录下所有文件内容自动导出,无需手动更新index.js
解决方案
方案1:构建/开发阶段预生成静态导出文件(最推荐)
这是兼容性最好、不影响打包优化的方案,核心逻辑是用脚本提前扫描目标目录,生成符合ESM静态语法的index文件,你可以配置成目录变动时自动更新,完全不需要手动修改导出规则。
- 先写一个生成index文件的脚本,命名为
gen-export-index.js:
import fs from 'fs' import path from 'path' // 可根据自己需求修改要生成导出的目录 const targetDir = path.resolve(process.cwd(), process.argv[2] || './src') // 过滤规则,只识别你需要的文件后缀,排除index自身 const matchFiles = fs.readdirSync(targetDir).filter(file => { return /\.(js|ts|jsx|tsx)$/.test(file) && !file.startsWith('index.') }) // 生成静态export语句 const exportContent = matchFiles.map(file => { // 去掉后缀避免导入报错 const fileNameWithoutExt = path.parse(file).name return `export * from './${fileNameWithoutExt}'` }).join('\n') // 写入index文件,TS项目可以改成index.ts fs.writeFileSync(path.join(targetDir, 'index.js'), exportContent)
- 在
package.json中配置执行脚本,可搭配监听工具实现自动更新:
{ "scripts": { "gen-index": "node gen-export-index.js", // 示例:开发时监听src目录下的js/ts文件变动,自动重生成index,后面接你原来的开发启动命令 "dev": "nodemon --watch src --ext js,ts,jsx,tsx --exec npm run gen-index & vite" } }
这个方案生成的index文件和你手动写的完全一致,打包工具的tree shaking、类型推导都能正常工作,没有任何运行时副作用。
方案2:运行时动态导入(仅适合不需要静态优化的场景)
如果你必须在运行时动态加载所有导出,可以用ESM原生的异步import()方法实现:
// index.js import { readdir } from 'fs/promises' export async function loadAllExports() { const files = (await readdir('./')).filter(file => { return /\.(js|ts)$/.test(file) && !file.startsWith('index.') }) const exportsMap = {} for (const file of files) { const module = await import(`./${file}`) Object.assign(exportsMap, module) } return exportsMap }
使用时需要异步调用:
import { loadAllExports } from './your-dir/index.js' const allExports = await loadAllExports()
该方案的缺点是必须异步调用,且打包工具无法识别动态导入的内容,无法做tree shaking,会把所有文件的内容都打包进去。
补充说明你之前写法的问题:ESM的
export是静态语法,ES规范要求必须写在模块顶层,不能放在循环、条件判断等代码块内;require是CommonJS专属API,默认在ESM环境下不支持,不建议强制开启兼容。
内容的提问来源于stack exchange,提问作者Arman
相关产品推荐
相关产品推荐

