समस्या: मैं एक ग्राफक्यूएल क्वेरी का परीक्षण करना चाहता हूं जो इस तरह एक .graphql फ़ाइल में रहती है:

#import '../../fragments/Widget.graphql'

query WidgetFragment($id: ID) {
    readWidgetFragment(id: $id) {
        ...Widget
    }
}

नकली रिज़ॉल्वर और डेटा के साथ एक ग्राफक्यूएल स्कीमा बनाने के लिए, मैं makeExecutableSchema और addMockFunctionsToSchema का उपयोग करता हूं >ग्राफक्ल-टूल्स.

एक जेस्ट टेस्ट के अंदर से क्वेरी को चलाने के लिए, मेरी समझ यह है कि मुझे graphql() फ़ंक्शन का उपयोग करने की आवश्यकता है। "nofollow noreferrer">graphql-js.

इस फ़ंक्शन को स्ट्रिंग के रूप में क्वेरी की आवश्यकता है, इसलिए मैंने दो अलग-अलग तरीकों की कोशिश की, लेकिन उनमें से किसी ने भी काम नहीं किया:

  • .graphql फ़ाइल को एक सामान्य टेक्स्ट फ़ाइल के रूप में पार्स करें, मुझे कच्ची स्ट्रिंग दे रही है (का उपयोग करके जेस्ट-रॉ-लोडर मेरे जेस्ट कॉन्फिगर में)। यह मुझे देता है: Failed: Errors in query: Unknown fragment "Widget". जब मैं क्वेरी चलाता हूं।
  • jest-transform-graphql का उपयोग करके .graphql फ़ाइल को query ऑब्जेक्ट में पार्स करें. मेरा मानना ​​है कि यह सही दृष्टिकोण होना चाहिए, क्योंकि यह किसी भी आयातित टुकड़े को ठीक से हल करना चाहिए। हालांकि, क्वेरी को निष्पादित करने के लिए, मुझे query.loc.source.body को graphql पास करने की आवश्यकता है, जिसके परिणामस्वरूप विकल्प 1 के समान त्रुटि संदेश मिलता है।
5
Thomas Zimmermann 31 मई 2018, 09:02

3 जवाब

सबसे बढ़िया उत्तर

आप इसका उपयोग कर सकते हैं:

import { print } from 'graphql/language/printer'

import query from './query.gql'

...

print(query)
3
tommyboy 19 पद 2018, 20:31

कच्चे पाठ के रूप में इसे पार्स करने के साथ प्रारंभिक दृष्टिकोण का प्रयोग करें, सिवाय इसके:

  1. पथ तर्क के साथ एक पुनरावर्ती फ़ंक्शन का उपयोग करें (मान लीजिए कि आपके पास नेस्टेड टुकड़े हो सकते हैं)
  2. जो regex का उपयोग सभी आयातों को एक सरणी में पहले से निकालने के लिए करता है (शायद एक अच्छे पैटर्न का उपयोग करें :))
  3. बाकी फाइल को एक स्ट्रिंग वेरिएबल में जोड़ें
  4. फिर आयात के माध्यम से लूप करें, #import को हल करें और उन्हें स्वयं पास करें और परिणाम को स्ट्रिंग चर में जोड़ें
  5. अंत में परिणाम को मुख्य फ़ंक्शन पर लौटाएं जहां आप इसे graphql() पर पास करते हैं
0
Milos Grujic 5 सितंबर 2019, 10:42

हाँ, यह काफी अचार है। यहां तक ​​कि आयात के सही ढंग से काम करने के बावजूद (>= v2.1.0 jest-transform-graphql के लिए, वे query.definitions ऑब्जेक्ट में जुड़ जाते हैं, जो graphql को document.loc.source.body के साथ क्वेरी तर्क के रूप में कॉल करते समय पूरी तरह से दरकिनार कर दिया जाता है।

सर्वर के अंत में, graphql (function graphqlImpl ) parse(source) का उपयोग करके document ऑब्जेक्ट का पुनर्निर्माण करेगा - लेकिन उसे आयातित फ़्रैगमेंट परिभाषाओं का शून्य ज्ञान होगा...

जहां तक ​​​​मैं कह सकता हूं, सर्वर पर भेजने से पहले क्वेरी स्रोत पर टुकड़े मुद्रित करना सबसे अच्छा शर्त है। आपको #import से शुरू होने वाली सभी पंक्तियों को स्पष्ट रूप से ढूंढ़ना होगा और इन्हें आयात की जाने वाली graphql फ़ाइल की वास्तविक टेक्स्ट सामग्री से बदलना होगा।

नीचे वह फ़ंक्शन है जिसका मैं उपयोग करता हूं। (पुनरावर्ती अंशों के लिए परीक्षण नहीं किया गया)

// Async wrapper around dynamic `import` function
import { importQuery } from "./queries";

const importAndReplace = async (fileToImport, sourceDocument, line) => {
  const doc = await importQuery(fileToImport);
  const targetDocument = (await sourceDocument).replace(line, doc.loc.source.body);
  return targetDocument;
};

// Inspired by `graphql-tag/loader` 
// Uses promises because of async function `importQuery` used
export default async graphqlOperation => {
  const { body } = graphqlOperation.loc.source;
  const lines = body.split(/\r\n|\r|\n/);
  const bodyWithInlineImports = await lines.reduce(
    async (accumulator, line) => {
      await accumulator;
      const lineSplit = line.slice(1).split(" ");

      return line[0] === "#" && lineSplit[0] === "import"
        ? importAndReplace(lineSplit[1].replace(/"/g, ""), accumulator, line)
        : Promise.resolve(accumulator);
    },
    Promise.resolve(body)
  );
  return bodyWithInlineImports;
};
0
David Remie 6 सितंबर 2019, 10:36