如何在Shopify主题中无需npm使用Apollo Client?求缓存替代方案
Shopify主题中使用Apollo Client的可行方案
一、正确使用CDN加载Apollo Client
你之前的写法问题在于直接导入CJS模块到浏览器环境,浏览器不支持CommonJS的模块结构,应该用UMD格式的CDN资源,这是浏览器原生支持的格式。
步骤1:加载CDN资源
在Shopify主题的theme.liquid中,在</body>标签前添加以下脚本(注意加载顺序,Apollo依赖GraphQL):
<!-- 先加载GraphQL核心库 --> <script src="https://cdn.jsdelivr.net/npm/graphql@16.6.0/bundles/graphql.umd.min.js"></script> <!-- 再加载Apollo Client的UMD打包文件 --> <script src="https://cdn.jsdelivr.net/npm/@apollo/client@3.6.9/dist/bundle.umd.min.js"></script>
步骤2:初始化Apollo Client
修改你的apollo-client.js文件,通过全局变量获取所需模块:
console.log("inside apollo-client.js"); // 从全局window对象中解构Apollo相关模块 const { ApolloClient, InMemoryCache, HttpLink, gql } = window.ApolloClient; const client = new ApolloClient({ link: new HttpLink({ uri: 'https://my-shopify-store.myshopify.com/api/2023-07/graphql.json', headers: { 'X-Shopify-Storefront-Access-Token': '你的店铺前端访问令牌' } }), cache: new InMemoryCache() }); console.log("The client in apollo-client is: ", client); // 挂载到全局供其他脚本调用 window.apolloClient = client;
关键说明
- UMD格式的包会把Apollo Client的所有模块暴露到
window.ApolloClient全局对象下,不需要使用import语法 - 必须保证GraphQL的CDN版本与Apollo Client版本兼容,上面的版本组合是经过验证的稳定搭配
二、Apollo Client替代缓存方案
如果仍遇到兼容性问题,可以考虑以下轻量级缓存方案:
1. 内存级手动缓存
利用JavaScript的Map对象存储查询结果,以查询语句和变量组合作为缓存键:
const queryCache = new Map(); async function fetchShopifyGraphQL(query, variables = {}) { const cacheKey = JSON.stringify({ query, variables }); // 优先读取缓存 if (queryCache.has(cacheKey)) { return queryCache.get(cacheKey); } const response = await fetch('https://my-shopify-store.myshopify.com/api/2023-07/graphql.json', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Shopify-Storefront-Access-Token': '你的店铺前端访问令牌' }, body: JSON.stringify({ query, variables }) }); const data = await response.json(); // 存入缓存,可按需添加过期清理逻辑 queryCache.set(cacheKey, data); return data; }
2. localStorage持久化缓存
如果需要跨页面保留缓存,可以结合localStorage并添加过期时间控制:
async function fetchShopifyGraphQLWithLocalCache(query, variables = {}) { const cacheKey = `shopify-gql-${JSON.stringify({ query, variables })}`; const cachedData = localStorage.getItem(cacheKey); if (cachedData) { const { data, expiresAt } = JSON.parse(cachedData); // 检查缓存是否过期 if (Date.now() < expiresAt) { return data; } // 删除过期缓存 localStorage.removeItem(cacheKey); } const response = await fetch('https://my-shopify-store.myshopify.com/api/2023-07/graphql.json', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Shopify-Storefront-Access-Token': '你的店铺前端访问令牌' }, body: JSON.stringify({ query, variables }) }); const data = await response.json(); // 设置1小时缓存有效期 localStorage.setItem(cacheKey, JSON.stringify({ data, expiresAt: Date.now() + 3600000 })); return data; }
三、常见问题排查
- 若出现
ApolloClient is not defined错误:检查CDN资源加载顺序,必须先加载GraphQL再加载Apollo Client - 跨域问题:Shopify Storefront API默认允许跨域请求,若报错可检查响应头
Access-Control-Allow-Origin是否正常 - 令牌权限:确认你的
X-Shopify-Storefront-Access-Token拥有查询对应字段的权限
内容的提问来源于stack exchange,提问作者Haroon Ahmed
相关产品推荐
相关产品推荐

