如何将 graphQL 查询从组件中抽象出来?



我有一个带有基本<PostList />组件的NextJS项目,我使用react-apollo模块从GraphQL服务器检索一些测试数据:

import { gql, graphql } from "react-apollo";
import withData from "../../apollo/withData";
const GET_POSTS = gql`
{
posts {
_id
title
}
}
`;
const PostList = ({ data: { loading, posts } }) => {
if (loading) {
return <div>Loading...</div>;
} else {
return (
<ul>
{posts.map(post => <li key={post._id}>{post.title}</li>)}
</ul>
);
}
};
export default withData(graphql(GET_POSTS)(PostList));

这很完美。但是现在我想把这个查询定义拿出来,给它一个单独的.graphql(或.gql(文件。像这样:

// apollo/get-posts-query.graphql
{
posts {
_id
title
}
}

我的问题是,如何将此文件导入我的组件而不必将其转换为 JavaScript 代码?我的意思是,我不想在我的.graphql文件中使用任何非 graphql 代码(所以没有module.exportsexport default等(。

这是我尝试过的所有内容:

使用网络包

/* eslint-disable no-unused-vars */
import withCSS from '@zeit/next-css';
import withSass from '@zeit/next-sass';
import dotenv from 'dotenv';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import glob from 'glob';
import withPurgeCss from 'next-purgecss';
import OptimizeCSSAssetsPlugin from 'optimize-css-assets-webpack-plugin';
import path from 'path';
import webpack from 'webpack';
import 'graphql-tag/loader';
const { parsed: localEnv } = dotenv.config();
module.exports = withCSS(withSass(withPurgeCss({
distDir: '.build',
purgeCssPaths: [
'pages/**/*',
'components/**/*',
],
webpack: (config, { dev, isServer }) => {
if (isServer) {
return config;
}
config.module.rules.push({
test: /.(graphql|gql)$/,
exclude: /node_modules/,
loader: 'graphql-tag/loader',
});
config.plugins.push(
new webpack.DefinePlugin({
'process.env': {
BASE_URL: JSON.stringify(process.env.BASE_URL),
},
}),
new webpack.EnvironmentPlugin(localEnv),
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1,
}),
);
config.optimization.minimizer.push(
new OptimizeCSSAssetsPlugin({}),
);
return config;
},
env: {
REDIS_PORT: process.env.REDIS_PORT,
REDIS_HOST: process.env.REDIS_HOST,
},
})));

此设置会引发以下错误(甚至拒绝识别加载程序!

> ./apollo/test.graphql 2:8
Module parse failed: Unexpected token (2:8)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| {
>   posts {
|     _id
|     title

使用 Babel

我添加了babel-plugin-import-graphqlbabel 插件(yarn add -D babel-plugin-import-graphql到我的开发依赖项中(。然后更新了我的.babelrc如下:

{
"presets": [
"next/babel"
],
"plugins": [["styled-components", { "ssr": true }], "import-graphql"]
}

这将引发以下错误:

> Build error occurred { Invariant Violation: Argument of {   posts {
>     _id
>     title
>     secondaryTitle   } }  passed to parser was not a valid GraphQL DocumentNode. You may need to use 'graphql-tag' or another method to
> convert your operation into a document
>     at invariant (/home/ubuntu/proost/web-no-apollo/node_modules/invariant/invariant.js:40:15)

还有第三种选择吗?

你需要一个像 Webpack 这样的捆绑器来定义如何加载.graphql文件。然后,您只需导入 graphql 文件并像以前一样使用生成的查询字符串/对象。

一种可能性是 webpack-graphql-loader,但 Apollo 建议使用 graphql-tag。

无论如何,您都可以专门为Next.js尝试此方法。

最新更新