如何批量导入指定目录下多个*.gql文件到TS文件并按需调用
问题解答
你提到的import * as queries from './graphql/queries'写法默认无法直接生效,原因有两点:
- ES 模块的目录导入规则只会自动匹配目录下的
index入口文件,不会主动遍历目录下的所有.gql文件 - 默认的TS和构建工具配置不会将
.gql后缀文件识别为合法的可导入模块
可行实现方案
以下两种是通用的落地方式:
方案1:手写入口文件(无构建工具依赖,最稳定)
- 首先配置
.gql文件的基础加载能力:- 构建工具安装对应gql加载器(Webpack用
graphql-tag/loader,Vite用vite-plugin-graphql-loader) - 全局TS类型声明文件中添加gql文件类型定义:
// 例如env.d.ts declare module '*.gql' { import { DocumentNode } from 'graphql' const content: DocumentNode export default content } - 构建工具安装对应gql加载器(Webpack用
- 在
graphql/queries目录下新建index.ts作为统一导出入口:
// graphql/queries/index.ts import Me from './Me.gql' import Terminals from './Terminals.gql' import Sessions from './Sessions.gql' export default { Me, Terminals, Sessions } as const
- 之后就可以在
fetch.ts中直接批量导入使用:
import queries from './graphql/queries' // 直接按文件名调用 const meQuery = queries.Me // 从数组中取文件名调用也完全支持 const requiredQueryNames = ['Terminals', 'Sessions'] const requiredQueries = requiredQueryNames.map(name => queries[name])
方案2:构建工具自动批量导入(无需手动维护入口文件)
如果不想每次新增gql文件都手动修改index.ts,可以用对应构建工具的动态批量导入语法:
Vite 环境
// fetch.ts // eager: true表示直接加载所有文件,不使用懒加载 const queryModules = import.meta.glob('./graphql/queries/*.gql', { eager: true }) // 处理为「文件名: 查询内容」的对象 const queries = Object.fromEntries( Object.entries(queryModules).map(([filePath, module]) => { const queryName = filePath.split('/').pop().replace('.gql', '') return [queryName, module.default] }) ) as Record<'Me' | 'Terminals' | 'Sessions', DocumentNode>
Webpack 环境
// fetch.ts // 三个参数分别为:扫描目录、是否扫描子目录、匹配文件的正则 const queryContext = require.context('./graphql/queries', false, /\.gql$/) const queries = queryContext.keys().reduce((res, filePath) => { const queryName = filePath.replace('./', '').replace('.gql', '') res[queryName] = queryContext(filePath).default return res }, {} as Record<'Me' | 'Terminals' | 'Sessions', DocumentNode>)
两种自动导入方案生成的queries对象,使用方式和方案1完全一致。
内容的提问来源于stack exchange,提问作者Ari Shojaei
相关产品推荐
相关产品推荐

