Gatsby: [bug] ️ masalah payung untuk masalah penyesuaian skema

Dibuat pada 4 Mar 2019  ·  131Komentar  ·  Sumber: gatsbyjs/gatsby

Ini adalah masalah meta untuk semua masalah dengan 2.2.0, yang diperkenalkan oleh skema refactoring.

Apa?

Lihat posting blog untuk detail tentang mengapa kami melakukan refactoring dan tentang apa itu semua.

Lihat posting blog rilis untuk catatan rilis dan pembaruan terakhir.

Bagaimana?

Instal versi terbaru Gatsby dan coba jalankan situs Anda. Mudah-mudahan itu semua hanya akan bekerja. Jika mau, Anda juga dapat mencoba dua API baru ( createTypes dan createResolvers ).

yarn add gatsby

Changelog

[email protected]

  • Diterbitkan

[email protected]

  • Dipindahkan ke arahan eksplisit alih-alih addResolver

[email protected]

  • Kuasai penggabungan kembali, tingkatkan graphql-compose

[email protected]

  • Lihat #13028

[email protected]

  • :sampanye:

[email protected]

  • Memperbaiki regresi ketika string kosong dicampur dengan tanggal menyebabkan hal-hal tidak ditafsirkan sebagai tanggal

[email protected]

  • gabungkan master terbaru
  • pembaruan dokumen

[email protected]

  • gabungkan master terbaru
  • pesan kesalahan penguraian SDL yang lebih baik

[email protected]

  • perbaiki regresi dalam penamaan koneksi dalam jenis huruf kecil bernama

[email protected]

  • Memperbaiki skalar khusus yang tidak memiliki filter
  • Menambahkan kesalahan saat mencoba mengganti antarmuka Node atau jenis filter/sort yang dihasilkan.

[email protected]

  • Menambahkan API kenyamanan baru yang dimodelkan setelah graphql-compose. Lihat contoh penggunaan-jenis-definisi.
exports.sourceNodes = ({ actions, schema }) => {
  const { createTypes } = actions
  createTypes([
    schema.buildObjectType({
      name: `CommentJson`,
      fields: {
        text: `String!`,
        blog: {
          type: `BlogJson`,
          resolve(parent, args, context) {
            return context.nodeModel.getNodeById({
              id: parent.author,
              type: `BlogJson`,
            })
          },
        },
        author: {
          type: `AuthorJson`,
          resolve(parent, args, context) {
            return context.nodeModel.getNodeById({
              id: parent.author,
              type: `AuthorJson`,
            })
          },
        },
      },
      interfaces: [`Node`],
    }),
  ])
}

[email protected]

  • Regresi tetap dengan bidang Node id bukan String, seperti di master saat ini.
  • Ditingkatkan ke [email protected]
  • Tipe FilterInput sekarang tidak diawali dengan tipe keluaran, mengurangi proliferasi tipe

[email protected]

  • Memperbaiki masalah dengan pagination pada hasil kueri nol
  • @dontInfer(noDefaultResolvers: false) benar-benar berfungsi
  • di createResolvers resolver info.originalResolver tersedia meskipun tidak ada resolver di bidang asli

[email protected]

  • Ulangi versi alfa dengan versi rilis yang tepat
  • Perbaiki jenis Node tanpa node yang sebenarnya tidak ditambahkan

[email protected]

  • Alfa awal
GraphQL

Komentar yang paling membantu

Diterbitkan [email protected] . Terima kasih semuanya!

Semua 131 komentar

Filter untuk bidang ID sekarang mengharapkan ID sebagai input yang sebelumnya menginginkan string. Ini memecah kueri tertentu, misalnya:

export const query = graphql`
  query BlogPostTemplateQuery($id: String!) {
    post: sanityPost(id: { eq: $id }) {
      id
      title
    }
  }
`

Akan melaporkan:

error GraphQL Error Variable "$id" of type "String!" used in position expecting type "ID".

Meskipun mungkin lebih tepat untuk memperbarui kueri untuk mencerminkan hal ini, ini adalah perubahan yang melanggar, jadi saya pikir saya akan melaporkannya.

@rexxars Temuan yang bagus! Saya berasumsi kami biasa mengonversi filter ID ke String. Saya akan mengembalikan perilaku lama.

Dirilis versi baru.

Mencoba menanyakan skema di resolver:

exports.createResolvers = ({ createResolvers, schema }) => {
  createResolvers({
    MenuJson: {
      someResolver: {
        type: `String!`,
        async resolve(source, args, context, info) {
          const foo = await graphql(schema, `
            {
              allPageJson {
                nodes {
                  id
                }
              }
            }
          `, {})

          console.log(foo)

          return 'WIP'
        },
      },
    },
  })
}
TypeError: Cannot read property 'nodeModel' of undefined
         at /private/tmp/test-gatsby/node_modules/gatsby/dist/schema/resolvers.js:22:15
         at /private/tmp/test-gatsby/node_modules/gatsby/dist/schema/resolvers.js:49:44
         at Generator.next (<anonymous>)
[...]

@NicoleEtLui Untuk kueri di bidang resolver, gunakan metode yang disediakan pada context.nodeModel , yaitu Anda dapat menggunakan context.nodeModel.getAllNodes({ type: 'PageJson' }) atau untuk kueri yang lebih canggih Anda dapat menggunakan context.nodeModel.runQuery . Ada beberapa contoh dasar di sini .

Jika Anda perlu mengakses skema, perhatikan bahwa argumen schema hanyalah representasi perantara - di resolver Anda memiliki akses ke skema akhir yang dibuat pada info.schema .

Diterbitkan [email protected]

@stefanprobst Terima kasih atas jawaban cepat dan semua pekerjaan hebat yang Anda lakukan!

Hai!
Adakah saran untuk menangani hubungan antar node?

Misalnya, file disimpan di JSON (tanpa bidang id, anggap nama file sebagai id):
data/comments/some-uuid.json = { "message": "Hello", "postId": "some-post" }
data/posts/some-post.json = { "content": "post" }

Menggunakan plugin source-filesystem dan transformer-json , yang membuat node memiliki ID tidak dapat diprediksi karena transformator menggunakan createNodeId() . Itu membuat sulit untuk menemukan post dari comment .

Hai !
Mencoba memulai proyek gatsby dengan semua ini di gatsby-config.js :

  • gatsby-transformer-sharp
  • gatsby-plugin-sharp
  • gatsby-plugin-manifest

akan melempar:

error Plugin gatsby-transformer-sharp returned an error


  Error: Cannot find module 'gatsby/dist/utils/cpu-core-count'

  - loader.js:581 Function.Module._resolveFilename
    internal/modules/cjs/loader.js:581:15

  - loader.js:507 Function.Module._load
    internal/modules/cjs/loader.js:507:25

  - loader.js:637 Module.require
    internal/modules/cjs/loader.js:637:17

  - v8-compile-cache.js:159 require
    [keemotion-corporate]/[v8-compile-cache]/v8-compile-cache.js:159:20
[...]

@NicoleEtLui Harap perbarui gatsby-plugin-manifest dan gatsby-plugin-sharp , ini diperbaiki dalam paket tersebut dengan https://github.com/gatsbyjs/gatsby/pull/12332

Diterbitkan [email protected]

@LoicMahieu Anda dapat secara manual memberikan id untuk node, kemudian Anda dapat melakukan hubungan dengan menentukan bidang fieldName___NODE .

Diterbitkan [email protected]

T: Apakah kasus penggunaan ini cocok untuk createResolvers ?

Saya menggunakan CMS jarak jauh melalui gatsby-source-graphql yang menyertakan referensi ke beberapa file jarak jauh. Saat ini saya menarik file-file itu dengan createRemoteFileNode . Namun, kueri halaman menjadi canggung dengan cepat karena mudah untuk masuk ke situasi di mana saya memerlukan hasil kueri cms (pada sumber data gatsby-source-graphql ) untuk mencari tahu file mana yang saya perlukan dari gatsby-source-filesystem .

Idealnya, saya ingin menambahkan/menautkan/bergabung (?) node file jarak jauh ini ke dalam node cms dari gatsby-source-graphql . Apakah ini situasi yang createResolvers dapat membantu?

@skinandbones Jika saya mengerti dengan benar, jawaban singkatnya adalah "mungkin tapi mungkin belum".

Kami melakukan dukungan memperluas konfigurasi lapangan pada jenis ditambahkan skema pihak ketiga, sehingga memungkinkan untuk menambahkan penyelesai lapangan untuk tipe dari skema CMS Anda dengan createResolvers , dan menggunakan createRemoteFileNode di pemecah masalah. Sebagai contoh:
https://github.com/stefanprobst/gatsby/blob/5bbfee29b5ec38f13a3070b13de4877aaddd6483/examples/using-gatsby-source-graphql/gatsby-node.js#L56 -L71

Masalahnya adalah createRemoteFileNode akan memicu panggilan API onCreateNode , dan di bidang resolver kami saat ini tidak memiliki cara untuk mengetahui kapan panggilan API berikutnya telah selesai dan aman bagi resolver untuk kembali. (Salah satu pendekatan untuk menyelesaikan ini adalah #12202.) Jadi, tergantung pada apa sebenarnya yang ingin Anda lakukan dengan file jarak jauh, ini mungkin atau mungkin belum berhasil.

@LoicMahieu Apakah Anda memiliki contoh proyek yang dapat Anda tautkan?

@stefanprobst Ya, Anda mengerti dengan benar dan masalah async masuk akal. Contoh yang Anda tautkan sangat mirip dengan apa yang saya harapkan sehingga saya dapat mencobanya dan melihat apa yang terjadi. Rencana saya adalah menjalankan node file ini melalui gatsby-transformer-sharp dalam kueri halaman.

Apakah pendekatan lain yang layak untuk menggunakan createRemoteFileNode melalui sourceNodes API (seperti biasa) dan kemudian menautkan node tersebut ke skema pihak ketiga menggunakan API baru? Sampai saat ini, saya belum bisa masuk ke skema pihak ke-3 untuk melakukan ini.

@skinandbones maaf, saya harus diklarifikasi: bagian dalam contoh saya terkait dengan saat ini belum bekerja, persis karena masalah bahwa ketika pengembalian bidang resolver, yang File simpul akan telah dibuat, tetapi ImageSharp node (yang dibuat dalam panggilan API onCreateNode dipicu) belum.

Adapun pendekatan kedua, saya akan tertarik dengan temuan Anda -- seharusnya dimungkinkan untuk menanyakan node File jarak jauh yang ditambahkan di resolver dengan context.nodeModel.getAllNodes({ type: 'File' }) atau dengan sesuatu seperti context.nodeModel.runQuery({ type: 'File', query: { filter: { name: { regex: "/^remote/" } } } })

@stefanprobst
Berikut ini contohnya:

  1. https://github.com/LoicMahieu/test-gatsby-refactor-schema
    Di sini kita dapat menautkan comments ke post dengan pencarian kompleks pada induk File .
  1. https://github.com/LoicMahieu/test-gatsby-refactor-schema/tree/custom-transformer-json
    Di sini kita dapat menautkannya dengan menggunakan trafo JSON khusus tempat kita dapat mengubah objek dan juga mengubah id.
    Metode ini berfungsi tetapi: jika posting dihapus dan referensi masih ada di komentar, gatsby akan gagal.
    Itu bisa diperbaiki dengan tidak menggunakan cara ___NODE tetapi createResolvers : demo

Hei, saya baru saja membaca posting blog ini tentang kustomisasi skema dan contoh ulang tahun agak aneh bagi saya. Dalam contoh Anda membuat penyelesai kustom, yang mencoba untuk menyelesaikan bidang tanggal menjadi Tanggal, dan jatuh kembali ke nilai palsu (01-01-1970) jika tanggal input bukan Tanggal yang tepat. Jika Anda pernah benar-benar memiliki tanggal dalam sistem nyata, Anda tidak akan pernah ingin mengganti input yang salah dengan data palsu. Anda ingin menandainya sebagai tidak dikenal/salah dengan sesuatu seperti nilai nol. Fakta bahwa null tidak digunakan dalam contoh membuat saya bertanya-tanya: apakah ada semacam batasan dalam Gatsby/GraphQL wrt. nilai nol?

@baobabKoodaa

apakah ada semacam batasan di Gatsby/GraphQL wrt. nilai nol?

Tidak. Di GraphQL, Anda dapat secara eksplisit mengatur apakah suatu bidang harus dapat dibatalkan atau tidak. Info lebih lanjut di sini .

@stefanprobst Saya membuat ini berfungsi dan berfungsi dengan ImageSharp . Sangat sangat keren dan pengubah permainan untuk bekerja dengan skema pihak ke-3

Adapun pendekatan kedua, saya akan tertarik dengan temuan Anda -- seharusnya dimungkinkan untuk menanyakan node File jarak jauh yang ditambahkan di resolver dengan context.nodeModel.getAllNodes({ type: 'File' }) atau dengan sesuatu seperti context.nodeModel.runQuery({ type: 'File', query: { filter: { name: { regex: "/^remote/" } } } })

Inilah yang saya lakukan ...

exports.sourceNodes = async ({ actions, store, cache, createNodeId }) => {
  ... do createRemoteFileNode stuff ...
}

exports.createResolvers = ({ createResolvers, schema }) => {
  createResolvers({
    CMS_Thing: {
      thumbFile: {
        type: 'File!',
        async resolve(source, args, context, info) {
          const data = await context.nodeModel.runQuery({
            type: 'File',
            query: { filter: { fields: { ThingThumb: { eq: 'true' }, thingId: { eq: source.id } } } }
          })
          return data[0];
        }
      }
    }
  });
}

(Ini tergantung pada saya membuat node file dengan beberapa bidang, tentu saja.)

Jalur optimal (untuk kasus penggunaan saya) adalah untuk dapat menggunakan createRemoteFileNode di createResolvers jadi semoga kita dapat mengetahuinya.

@skinandbones Sangat keren! Btw, Anda dapat menggunakan firstOnly: true di runQuery hanya untuk mendapatkan hasil pertama.

Dirilis [email protected] .

Tujuan sementara adalah menggabungkan ini untuk dikuasai dan dirilis minggu depan. Silahkan berkomentar dan mencobanya :)

Tampaknya filter untuk bidang tipe yang diselesaikan dalam createResolvers() tidak dibuat.

Contoh:

  • post.json : { "id": "some-post", "author": "Loic", message: "Hello" }
  • comment.json : { "postId": "some-post", message: "World" }
createResolvers({
  CommentsJson: {
    post: {
      type: `PostsJson`,
      resolve (source, args, context, info) {
        const allNodes = context.nodeModel.getNodeById({ id: source.postId, type: 'PostsJson' })
      }
    }
  }
})

CommentsJsonFilterInput tidak berisi bidang post . Jadi kueri seperti ini tidak dapat berfungsi:

{
  allCommentsJson(filter: {post: {author: {eq: "foo"}}}) {
    nodes {
      id
    }
  }
}

Terima kasih

@LoicMahieu Ini adalah perilaku yang dimaksudkan (setidaknya untuk saat ini): bidang baru yang ditambahkan di createResolvers tidak akan ada di filter input, karena createResolvers dijalankan terakhir dalam pembuatan skema. Pendekatan yang disarankan di sini adalah untuk mendefinisikan jenis bidang dengan tindakan createTypes dan kemudian memperluasnya dalam createResolvers - atau gunakan bantuan buildObjectType baru ditambahkan (lihat di atas).

Maaf ini belum didokumentasikan dengan lebih baik - untuk saat ini Anda dapat melihat dokumen API langsung di cabang: createResolvers dan createTypes .

@LoicMahieu ini disengaja, tambahkan resolver terjadi setelah semua pemrosesan dan dimaksudkan sebagai alat untuk melakukan penyesuaian akhir pada skema. Anda harus menambahkan bidang di createTypes jika Anda ingin bidang tersebut ditampilkan di filter. Ada sintaks steno baru yang dapat Anda gunakan, lihat posting teratas.

EDIT: Ups, belum melihat @stefanprobst membalas :D

Terima kasih keduanya untuk klarifikasi. createResolvers dan createTypes tampaknya mencapai tujuan yang sama.


Satu hal yang bisa sangat berguna adalah menyimpan skema yang dihasilkan. Itu akan memungkinkan untuk "snapshot" jenis dan memastikan bahwa skema akan tetap seperti yang kita harapkan.
Saya menulis POC yang tampaknya berfungsi dengan baik:

const { printType } = require("graphql")
const fs = require("fs-extra")
const path = require("path")

const schemaFilePath = path.join(__dirname, "./src/schema.gql")

exports.sourceNodes = async ({ actions }) => {
  const { createTypes } = actions

  if (await fs.exists(schemaFilePath)) {
    const typeDefs = (await fs.readFile(schemaFilePath)).toString()
    createTypes(typeDefs)
  }
}

exports.onPostBootstrap = async ({ store }) => {
  const { schema } = store.getState()
  const types = ["CommentsJson", "PostsJson"]
  const typeDefs = types
    .map(type => printType(schema.getType(type)))
    .join("\n\n")
  await fs.writeFile(schemaFilePath, typeDefs + "\n")
}

Dengan ini kita bahkan dapat menghapus semua data dan skema masih seperti yang kita harapkan.
Demo: https://github.com/LoicMahieu/test-gatsby-refactor-schema/commit/9696c8e386fd066262164f8e38f5689a14f111e1

@LoicMahieu :+1: Sesuatu seperti ini adalah bagian dari peta jalan kami.

Ini tidak menyentuh threading bangunan skema, kan?

Mengacu komentar: https://github.com/gatsbyjs/gatsby/issues/7373#issuecomment -413.570.634

Hanya satu proses Node yang berfungsi (screencap ini _not_ dari rilis beta, cukup tambahkan di sini untuk mengilustrasikan poin saya):

Screenshot 2019-01-10 10 14 07

@hilja API penyesuaian skema baru bukan tentang menjalankan kueri , tetapi tentang pembuatan skema, jadi ini belum berubah. Ada pekerjaan eksperimental yang memungkinkan pemecah masalah lapangan untuk memindahkan pekerjaan ke proses lain, tetapi itu belum siap.

Dirilis 2.2.0-rc.1 . Segera.

Penyortiran kueri pada bidang yang baru dibuat tampaknya bermasalah.

Saya dapat membuat bidang baru dengan melakukan:

exports.sourceNodes = ({ actions }) => {
  const { createTypes } = actions
  const typeDefs = `
    type MyNode implements Node {
      copyOfId: ID!
    }
  `
  createTypes(typeDefs)
}

exports.createResolvers = ({ createResolvers }) => {
  createResolvers({
    MyNode: {
      copyOfId: {
        resolve(source, args, context, info) {
          return info.originalResolver(
            {
              ...source,
              copyOfId: source.id,
            },
            args,
            context,
            info,
          )
        },
      },
    },
  })
}

Tetapi kemudian jika saya bertanya:

query {
    allMyNode (sort: {fields: [copyOfId]}) {
      nodes {
        copyOfId
    }
  }
}

hasil tidak diurutkan dan muncul dalam urutan aslinya.

Jika saya mengurutkan id semuanya baik-baik saja tentu saja.

Saya kira ini adalah masalah yang sama dengan @LoicMahieu yang disebutkan sebelumnya, tetapi ini benar-benar menyesatkan. Jika kita tidak dapat melakukannya maka itu harus didokumentasikan dengan sangat baik karena tampaknya wajar bagi saya untuk memudahkan pemfilteran dan penyortiran saya dengan membuat bidang yang sesuai dengan metode API baru ini.

PS: lupa menyebutkan... API baru ini luar biasa!! :D Jangan biarkan komentar saya menyesatkan Anda dengan berpikir saya dalam suasana hati yang pesimis. Saya hanya berusaha menjadi berguna. ;) Terima kasih atas kerja bagusnya!

@MarcCoet Terima kasih telah menguji! Ini adalah masalah yang diketahui - kami tidak memanggil pemecah bidang untuk bidang pengurutan saat ini, lihat #11368. Ini adalah hal berikutnya yang akan kita tangani setelah ini digabungkan!

Oh maaf. Saya tidak berpikir untuk mencari masalah setFieldsOnGraphQLNodeType . Salahku.
Saya senang mengetahui itu sedang dikerjakan.

jadi benar-benar tidak ada cara untuk menyiasatinya dengan API baru? Kita harus tetap menggunakan cara lama createNodeField ?

Saya mencoba dengan buildObjectType tetapi hasil yang sama.

exports.sourceNodes = ({ actions, schema }) => {
  const { createTypes } = actions

  createTypes([
    schema.buildObjectType({
      name: `MyNode`,
      fields: {
        copyOfId: {
          type: `ID!`,
          resolve(parent) {
            return parent.id
          },
        },
      },
      interfaces: [`Node`],
    }),
  ])
}

Adakah cara lain yang tidak terdokumentasi untuk mencapai penyortiran pada bidang simpul baru secara kebetulan?

Selain itu saya baru saja mengalami kesalahan sintaks dengan direktif @infer() . Tapi saya rasa itulah yang dimaksud dengan 'Izinkan opsi inferensi pada tipe non-SDL' dalam masalah yang diketahui di atas?!

@MarcCoet

kesalahan sintaks dengan direktif @infer()

Apakah ini Bekerja untukmu?

createTypes('type MyNode implements Node <strong i="11">@infer</strong> { foo: Boolean }')

Adapun masalah penyortiran: masalah ini agak ortogonal dengan refactor kustomisasi skema. Masalahnya adalah: ketika kita ingin memfilter atau mengurutkan bidang yang tidak ada pada objek node itu sendiri tetapi ditambahkan oleh resolver bidang, kita perlu memanggil resolver tersebut sebelumnya sehingga kita memiliki node lengkap yang tersedia untuk memfilter dan menyortir. Misalnya dalam contoh Anda, objek node tidak memiliki bidang copyOfId -- agar tersedia, kita perlu memanggil resolver sebelum memfilter dan menyortir. Saat ini, kami hanya melakukan ini untuk bidang filter, tetapi tidak untuk bidang pengurutan. Sebagai solusinya, Anda dapat mencoba menambahkan filter tiruan untuk copyOfId ke kueri Anda:

query {
  allMyNode (sort: { fields: [copyOfId] }, filter: { copyOfId: { ne: null } }) {
    nodes {
      copyOfId
    }
  }
}

Lihat juga komentar ini .

Saya mencoba mengatur skema untuk node frontmatter yang dihasilkan oleh gatsby-transformer-remark dan selalu mengalami kesalahan ini: Error: Schema must contain unique named types but contains multiple types named "MarkdownRemarkFrontmatter".

Skema saya terlihat seperti ini:

type MarkdownRemarkFrontmatter implements Node {
  title: String
}

@kennedyrose Terima kasih telah menguji! Apakah yang berikut ini cocok untuk Anda?

exports.sourceNodes = ({ actions }) => {
  const { createTypes } = actions
  createTypes(`
    type MarkdownRemarkFrontmatter {
      title: String
    }
    type MarkdownRemark implements Node {
      frontmatter: MarkdownRemarkFrontmatter
    }
  `)
}

Hanya tipe tingkat atas, yaitu tipe node yang dihasilkan oleh plugin sumber dan transformator (seperti MarkdownRemark atau ImageSharp ) yang harus mengimplementasikan antarmuka Node, bukan tipe bersarang seperti tipe frontmatter.
(Meskipun kita tampaknya memiliki bug bila menargetkan jenis infered bersarang langsung)

Itu bekerja. Terima kasih!

Diterbitkan [email protected] .

Diterbitkan [email protected] . Terima kasih semuanya!

@stefanprobst

Apakah ini Bekerja untukmu?
createTypes('type MyNode implements Node <strong i="9">@infer</strong> { foo: Boolean }')

Itu benar! Hanya artikel asli yang menyesatkan.

Saya kira kabut akan meningkat dengan datangnya dokumentasi yang tepat. ;)

Tentang masalah penyortiran, terima kasih banyak atas klarifikasinya. Itu sangat membantu.
Solusinya tampaknya berhasil jadi ini sempurna untuk saat ini.

Saya sangat senang dengan kemungkinan baru Gatsby. Terima kasih banyak untuk pekerjaan yang kalian lakukan di Gatsby.

Mau x-post gatsbyjs/gatsby #12696, khusus post ini

Sepertinya inferensi/deteksi file mungkin sedikit diubah di sini? Pembaruan ke 2.2.2 rusak, sedangkan ~2.1.0 tampaknya menyimpulkan node file dengan benar.

Baru saja menemukan ini saat bereksperimen dengan membuat antarmuka khusus menggunakan API. Menggunakan fungsi resolveType pada antarmuka berfungsi, tetapi menggunakan fungsi isTypeOf sebagai gantinya pada objek yang berbagi antarmuka tidak. Saya pikir ini tergantung pada kode di bawah ini di schema.js, yang mengasumsikan resolveType harus berupa simpul, ketika tidak ada fungsi yang dideklarasikan. Asumsi ini sekarang salah dengan jenis antarmuka kustom.

if (!typeComposer.getResolveType()) {
      typeComposer.setResolveType(node => node.internal.type);
    }

Omong-omong, pekerjaan yang bagus, tepat pada waktunya untuk proyek saya!

Hai @Wolfsun Ya, karena menyediakan resolveType melalui SDL tidak mungkin, kami menyediakan default yang seharusnya berfungsi dalam banyak kasus, dan memungkinkan menyediakan yang khusus melalui tipe graphql-js . Memang benar ini tidak cocok dengan isTypeOf . Karena penasaran: apakah ada alasan untuk menggunakan isTypeOf lebih dari resolveType ?

Hai @stefanprobst , terima kasih atas penjelasannya. Menggunakan resolveType sangat bisa diterapkan untuk saya pada tahap ini, namun menggunakan dengan isTypeOf akan sedikit lebih bersih karena saya memiliki satu antarmuka dengan banyak objek implementasi. Saya menggunakan struktur data untuk mewakili tata letak berbasis grid yang cukup kompleks, saya memiliki antarmuka Card, dan banyak CardTypes yang mengimplementasikan antarmuka ini, yang disimpan dalam struktur data relatif terhadap posisinya di grid. Karena saya tidak tahu CardType sebelumnya, antarmuka diperlukan. Berpotensi isTypeOf dapat berguna jika saya ingin menggunakan sistem plugin untuk Kartu tambahan, tetapi saya belum terlalu memikirkannya, dan itu mungkin bukan ide yang baik, jadi masalah untuk hari lain!

Untuk dapat ditemukan, saya menautkan ke contoh ini yang mungkin berguna bagi orang lain juga. Semoga ini baik-baik saja.

Saya mengalami masalah yang persis sama dengan @kennedyrose , tetapi dalam kasus saya solusi yang diberikan oleh @stefanprobst tidak cukup membantu, meskipun saya tidak begitu yakin apa yang saya lakukan, saya hanya mencoba segala cara yang mungkin untuk membuat ini skema tetapi selalu mengembalikan kesalahan tentang multiple types named... .

Berikut kodenya:

exports.sourceNodes = ({ actions }) => {
  const { createTypes } = actions;
  const typeDefs = `
    type Wordpress__PAGEAcfIntro {
      title: String
      content: String
    }
    type Wordpress__PAGEAcfThe_problem {
      title: String
      content: String
    }
    type Wordpress__PAGEAcfThe_solution {
      title: String
      content: String
    }
    type Wordpress__PAGEAcf {
      Intro: Wordpress__PAGEAcfIntro
      The_problem: Wordpress__PAGEAcfThe_problem
      The_solution: Wordpress__PAGEAcfThe_solution
    }
    type Wordpress__PAGE implements Node {
      acf: Wordpress__PAGEAcf
    }
  `;
  createTypes(typeDefs);
};

Pada awalnya saya mencoba mengatur hanya jenis yang saya butuhkan (yang pertama 3) dengan bidangnya, tetapi kemudian saya mendapatkan Error: Schema must contain unique named types but contains multiple types named "Wordpress__PAGEAcfIntro". . Saat mencari solusi, saya mencoba solusi @stefanprobst (seperti dalam kode saya, tidak yakin apakah benar) tetapi tidak berhasil.

Juga, ini cukup banyak untuk membuat beberapa bidang memiliki nilai string opsional (kueri terputus jika salah satu bidang tidak memiliki judul atau konten), dan ini hanya implementasi awal, saya mungkin harus melakukannya sama di seluruh situs web untuk lebih banyak bidang yang mungkin juga opsional, jadi saya sangat takut dengan solusi ini dan sangat berharap ada cara yang lebih baik untuk menyelesaikannya.

Nah, setelah lebih menggali dan mencoba hal-hal tanpa benar-benar tahu apa yang saya lakukan, saya menemukan cuplikan ini yang memecahkan masalah:

exports.createResolvers = ({ createResolvers }) => {
  createResolvers({
    Wordpress__PAGEAcfIntro: {
      title: { type: `String` },
      content: { type: `String` },
    },
    Wordpress__PAGEAcfThe_problem: {
      title: { type: `String` },
      content: { type: `String` },
    },
    Wordpress__PAGEAcfThe_solution: {
      title: { type: `String` },
      content: { type: `String` },
    },
  });
};

Meskipun saya masih tidak yakin mengapa solusi pertama saya tidak berhasil. Ini tampaknya jauh lebih mudah untuk dipertahankan.

Pikiran terakhir adalah bahwa saya tidak yakin apakah saya hanya kurang pengetahuan tentang API Gatsby atau dokumen menyesatkan untuk masalah khusus ini. Saya pikir akan lebih mudah untuk menemukan solusi untuk pertanyaan how to have optional fields in a graphql query using gatsby , karena ini adalah hal yang sangat mendasar ketika bekerja dengan CMS seperti WordPress di mana Anda dapat memiliki beberapa bidang khusus dan kemungkinan besar banyak dari mereka akan melakukannya menjadi opsional.

Mendeklarasikan bidang sebagai array file tidak berfungsi untuk saya.

exports.sourceNodes = ({ actions }) => { const { createTypes } = actions const typeDefs = ` type MarkdownRemarkFrontmatter implements Node { images: [File] } type MarkdownRemark implements Node { frontmatter: MarkdownRemarkFrontmatter } ` createTypes(typeDefs) }
Mungkin ada hubungannya dengan https://github.com/gatsbyjs/gatsby/issues/12596

Saya mengalami masalah yang persis sama dengan @kennedyrose , tetapi dalam kasus saya solusi yang diberikan oleh @stefanprobst tidak cukup membantu, meskipun saya tidak begitu yakin apa yang saya lakukan, saya hanya mencoba segala cara yang mungkin untuk membuat ini skema tetapi selalu mengembalikan kesalahan tentang multiple types named... .

Berikut kodenya:

exports.sourceNodes = ({ actions }) => {
  const { createTypes } = actions;
  const typeDefs = `
    type Wordpress__PAGEAcfIntro {
      title: String
      content: String
    }
    type Wordpress__PAGEAcfThe_problem {
      title: String
      content: String
    }
    type Wordpress__PAGEAcfThe_solution {
      title: String
      content: String
    }
    type Wordpress__PAGEAcf {
      Intro: Wordpress__PAGEAcfIntro
      The_problem: Wordpress__PAGEAcfThe_problem
      The_solution: Wordpress__PAGEAcfThe_solution
    }
    type Wordpress__PAGE implements Node {
      acf: Wordpress__PAGEAcf
    }
  `;
  createTypes(typeDefs);
};

Pada awalnya saya mencoba mengatur hanya jenis yang saya butuhkan (yang pertama 3) dengan bidangnya, tetapi kemudian saya mendapatkan Error: Schema must contain unique named types but contains multiple types named "Wordpress__PAGEAcfIntro". . Saat mencari solusi, saya mencoba solusi @stefanprobst (seperti dalam kode saya, tidak yakin apakah benar) tetapi tidak berhasil.

Juga, ini cukup banyak untuk membuat beberapa bidang memiliki nilai string opsional (kueri terputus jika salah satu bidang tidak memiliki judul atau konten), dan ini hanya implementasi awal, saya mungkin harus melakukannya sama di seluruh situs web untuk lebih banyak bidang yang mungkin juga opsional, jadi saya sangat takut dengan solusi ini dan sangat berharap ada cara yang lebih baik untuk menyelesaikannya.

@eddiemf , tidak sepenuhnya yakin, tetapi saya pikir masalah yang mungkin Anda alami adalah bahwa jenis yang Anda coba definisikan telah disimpulkan dari sumber data Wordpress. Jadi pada dasarnya mereka didefinisikan dua kali. Menggunakan createResolvers hanya akan membuat bidang baru pada tipe yang ada, atau menimpa bidang yang ada(?) dengan tampilannya.

Banyak perbaikan kecil di 2.2.10 , termasuk hubungan Node eksplisit yang berfungsi dengan benar.

@Wolfsun Ya itulah yang saya pikirkan tentang itu, tapi saya merasa dokumen mengarahkan Anda untuk menggunakan createTypes sebagai solusi untuk masalah ini, padahal sebenarnya Anda harus menggunakan createResolvers .

Seperti yang telah saya katakan, saya pikir ini adalah masalah yang sangat umum ketika berhadapan dengan WordPress, jadi akan lebih baik untuk memiliki solusi yang terdokumentasi dengan baik untuk ini.

@eddiemf Saya tidak terlalu akrab dengan plugin wordpress, tetapi memperluas jenis dalam contoh using-wordpress tampaknya berfungsi seperti yang diharapkan. Jika Anda dapat memberikan tautan ke repo Anda, saya dapat melihat apa masalahnya.

Harap diperhatikan bahwa kami menyadari bahwa kami masih sangat kekurangan dalam hal dokumentasi. Dugaan saya adalah bahwa masalahnya berkaitan dengan tipe mana yang harus mengimplementasikan antarmuka Node -- ini adalah sesuatu yang sebagian besar harus ditangani oleh plugin itu sendiri (setelah porting ke API baru).

Semantik antarmuka Node adalah untuk menandai tipe yang didukung oleh node aktual di penyimpanan data internal Gatsby, yaitu objek yang dibuat oleh tindakan createNode oleh plugin, dan memiliki id bidang. Ini berarti bahwa meskipun tipe Frontmatter hanya ada untuk mendefinisikan bentuk pada bidang frontmatter pada node MarkdownRemark , saya kira plugin wordpress sebenarnya mendaftarkan banyak top- jenis simpul tingkat.

@stefanprobst Saya benar-benar mengerti tentang dokumentasi untuk saat ini, saya hanya mencoba membantu :)

Singkatnya, halaman WordPress di aplikasi saya memiliki struktur seperti page -> acf -> someGroupOfFields -> actualField . Dalam kueri saya akan melakukan hal berikut sebagai contoh:

wordpressPage(slug: { eq: "home" }) {
  acf {
    intro {
      title
      content
    }
  }
}

Jenis secara otomatis dihasilkan menjadi sesuatu seperti WordPress__PAGE -> WordPress__PAGEAcf -> WordPress__PAGEAcfIntro . Masalahnya adalah bahwa bidang ini mungkin sangat sering hanya bidang opsional ( title dan content ), jadi jika salah satu bidang ini tidak disediakan, kueri saya akan rusak karena dihasilkan secara otomatis berdasarkan yang diambil data.

Saya tidak melihat cara yang mungkin bagi plugin untuk membuat bidang ini secara otomatis (bagaimana cara mengetahuinya?), tetapi saya mungkin salah. Jadi solusi pertama saya adalah menggunakan createTypes dan membuat tipe WordPress__PAGEAcfIntro dengan bidang yang tepat, tetapi kemudian saya mendapatkan kesalahan yang disebutkan.

Saya akan mengatakan ada beberapa konflik antara pembuatan tipe saya dan plugin Gatsby/sumber yang membuat tipe yang sama setelah mengambil data, tetapi saya benar-benar tidak dalam posisi terbaik untuk membuat asumsi karena saya sama sekali tidak berpengalaman dengan GraphQL atau Gatsby API , jadi saya tidak yakin bagaimana seharusnya bekerja.

Tetapi seperti yang telah saya katakan, untuk saat ini, membuat resolver seperti di posting terakhir saya bekerja dengan sangat baik, jadi pada dasarnya saya membuat tipe untuk semua yang perlu saya ambil, karena mereka selalu dapat menjadi opsional di CMS.

Anda dapat memeriksa gatsby-node.js sini untuk melihat bagaimana saya melakukannya.

@eddiemf Ini menarik. Apakah Anda memiliki contoh dengan kesalahan "Skema harus berisi jenis bernama unik tetapi berisi beberapa jenis bernama "Wordpress__PAGEACfIntro""? Gatsby seharusnya dapat menangani tipe override yang disimpulkan, jadi saya tidak yakin mengapa kode Anda tidak berfungsi.

@freiksenet saya mendapatkan kesalahan ini ketika mencoba menyelesaikannya seperti ini:

exports.sourceNodes = ({ actions }) => {
  const { createTypes } = actions;
  const typeDefs = `
    type Wordpress__PAGEAcfIntro {
      title: String
      content: String
    }
  `;
  createTypes(typeDefs);
};

Bidang title disetel di CMS, tetapi content kosong, jadi saya mencoba cuplikan di atas dan mendapatkan kesalahan nama unik ini.

Saya juga memikirkan hal yang sama tentang kemungkinan mengganti tipe karena itulah yang juga dikatakan oleh dokumen dan artikel mengenai fitur baru ini, jadi saya terkejut melihatnya tidak berfungsi seperti yang diharapkan.

Saya pikir ini masalah yang hampir sama dengan yang berikut:

Saya mencoba mengatur skema untuk node frontmatter yang dihasilkan oleh gatsby-transformer-remark dan selalu mengalami kesalahan ini: Error: Schema must contain unique named types but contains multiple types named "MarkdownRemarkFrontmatter".

Skema saya terlihat seperti ini:

type MarkdownRemarkFrontmatter implements Node {
  title: String
}

Dengan perbedaan bahwa solusi yang berhasil untuknya sebenarnya tidak berhasil untuk saya. Tetapi sepertinya bagian implements Node salah digunakan di sini, sedangkan dalam kasus saya seharusnya benar.

@eddiemf Anda perlu menggunakan tipe non-simpul di suatu tempat untuk menimpanya. Jadi MarkdownFrontmatter (tanpa implementasi Node) perlu digunakan di Markdown node dan Wordpress__PageAcfIntro harus digunakan di WorpressPage. Kami akan menambahkan kesalahan yang lebih baik, tetapi kami telah membuat perilaku ini dengan cara ini sehingga seseorang tidak secara tidak sengaja menimpa simpul sebaris.

@freiksenet maksud Anda seperti yang saya lakukan di sini?

Saya mengalami masalah yang persis sama dengan @kennedyrose , tetapi dalam kasus saya solusi yang diberikan oleh @stefanprobst tidak cukup membantu, meskipun saya tidak begitu yakin apa yang saya lakukan, saya hanya mencoba segala cara yang mungkin untuk membuat ini skema tetapi selalu mengembalikan kesalahan tentang multiple types named... .

Berikut kodenya:

exports.sourceNodes = ({ actions }) => {
  const { createTypes } = actions;
  const typeDefs = `
    type Wordpress__PAGEAcfIntro {
      title: String
      content: String
    }
    type Wordpress__PAGEAcfThe_problem {
      title: String
      content: String
    }
    type Wordpress__PAGEAcfThe_solution {
      title: String
      content: String
    }
    type Wordpress__PAGEAcf {
      Intro: Wordpress__PAGEAcfIntro
      The_problem: Wordpress__PAGEAcfThe_problem
      The_solution: Wordpress__PAGEAcfThe_solution
    }
    type Wordpress__PAGE implements Node {
      acf: Wordpress__PAGEAcf
    }
  `;
  createTypes(typeDefs);
};

Pada awalnya saya mencoba mengatur hanya jenis yang saya butuhkan (yang pertama 3) dengan bidangnya, tetapi kemudian saya mendapatkan Error: Schema must contain unique named types but contains multiple types named "Wordpress__PAGEAcfIntro". . Saat mencari solusi, saya mencoba solusi @stefanprobst (seperti dalam kode saya, tidak yakin apakah benar) tetapi tidak berhasil.

Juga, ini cukup banyak untuk membuat beberapa bidang memiliki nilai string opsional (kueri terputus jika salah satu bidang tidak memiliki judul atau konten), dan ini hanya implementasi awal, saya mungkin harus melakukannya sama di seluruh situs web untuk lebih banyak bidang yang mungkin juga opsional, jadi saya sangat takut dengan solusi ini dan sangat berharap ada cara yang lebih baik untuk menyelesaikannya.

Saya mencoba membuat, katakanlah, "pohon tipe utuh" atau "model tipe", dengan mengatur setiap bidang yang mungkin dan menggunakannya seperti pada contoh, tetapi saya mendapatkan kesalahan yang sama (terkadang kesalahan yang sedikit berbeda menuduh beberapa jenis lain dari tidak unik).

Meskipun saya harus mengakui bahwa saya tidak tahu apa yang saya lakukan ketika saya mencoba ini, saya hanya mencoba setiap kombinasi solusi yang mungkin, tetapi semuanya gagal untuk saya.

@eddiemf Apakah mungkin untuk mendapatkan url situs wordpress yang Anda gunakan? Saya ingin mengujinya sendiri untuk mencari tahu apa yang menyebabkan kesalahan.

@freiksenet Tentu, urlnya adalah https://gatsbyislove.com
Saya akan mengosongkan bidang title dari bagian intro sehingga Anda dapat memeriksanya.

Anda dapat melihat di https://gatsbyislove.netlify.com/ bahwa bagian intro tidak memiliki judul, tetapi berfungsi dengan baik karena resolver yang saya buat.

@eddiemf Terima kasih banyak! Mendapat kesalahan, akan menyelidiki.

Lol, itu kesalahan paling lucu. Jadi kami tidak sengaja membuat huruf besar pada jenis wordpress. Semuanya harus dimulai dengan wordpress . Sebagai gantinya, kami membuat Nodes dengan huruf kecil, tetapi objek bagian dalam huruf besar. Jadi ini akan berhasil:

     type Wordpress__PAGEAcfIntro {
       title: String
       content: String
     }

    type Wordpress__PAGEAcf {
      Intro: Wordpress__PAGEAcfIntro
    }

    type wordpress__PAGE implements Node {
      acf: wordpress__PAGEAcf
    }

Saya mendorong perbaikan sekarang, jadi semua jenis akan dimulai dengan huruf kecil w .

Luar biasa
Tapi sekarang saya pikir, setidaknya untuk situasi khusus ini, bahwa menggunakan resolver dapat membuat kode lebih terorganisir karena saya tidak perlu mendeklarasikan bidang bersarang ini hingga bidang utama yang mengimplementasikan Node .

Apakah ini benar-benar lebih baik atau saya tidak melihat sesuatu di sini?

Pokoknya saya akan bermain-main dengan solusi yang berbeda dan melihat mana yang paling cocok untuk saya.

Terima kasih atas dukungannya yang luar biasa!

@eddiemf Boleh saja menggunakan createResolvers , tetapi Anda tidak akan mendapatkan bidang tersebut dalam parameter filter dan sort dari bidang akar jenis ini. Jika tidak apa-apa untuk Anda, gunakan createResolvers .

Inilah perbaikannya: https://github.com/gatsbyjs/gatsby/pull/12837/files

Saya mengerti, itu seharusnya tidak menjadi masalah dalam banyak kasus karena filter dan sort biasanya dibuat pada bidang yang selalu terisi, tetapi saya akan mengingatnya. Terima kasih lagi :)

Sunting : Ini tidak lagi terjadi, meskipun saya tidak memperbarui apa pun. Saya tidak tahu apa yang terjadi, atau apa yang membuat saya percaya bahwa itu tidak berhasil; tapi itu berhasil sekarang ... kerja yang bagus!

Hai teman-teman, saya bermain-main dengan kode ini:

exports.sourceNodes = ({ actions }) => {
  const { createTypes } = actions
  createTypes(`
    type MarkdownRemarkFrontmatter {
      image: File  // <---- could be a relative path, could be an empty string
    }

    type MarkdownRemark implements Node {
      frontmatter: MarkdownRemarkFrontmatter
    }
  `)
}

Saya mengharapkan untuk mendapatkan simpul File atau null saat meminta simpul komentar penurunan harga. Sebaliknya, saya selalu mendapatkan null ... Saya harus mencari file secara manual:

createResolvers({
    MarkdownRemarkFrontmatter: {
      image: {
        type: `File`,
        resolve(src, args, context) {
          const filePath = src[info.fieldName]
          // find & return the file node
        }
      }
    }
  })

Apakah ada cara bagi saya untuk memberi tahu gatsby, "ini akan menjadi simpul File, tolong temukan atau kembalikan nol"?

Hai! Apakah mungkin warning There are conflicting field types in your data. GraphQL schema will omit those fields muncul bahkan jika createTypes telah diatur, mencegah GraphQL menghilangkan bidang?

Ini adalah peringatan dari gatsby develop :

ThumbprintToken.tokens.value.web:
 - type: number
   value: 1025
   source: File "../packages/thumbprint-tokens/src/tokens/breakpoint.json"
 - type: string
   value: '4px'
   source: File "../packages/thumbprint-tokens/src/tokens/border-radius.json"

Dan ini adalah penggunaan createTypes :

exports.sourceNodes = ({ actions }) => {
    const { createTypes } = actions;
    const typeDefs = `
        type ThumbprintToken implements Node {
            tokens: [ThumbprintTokenTokens!]!
        }

        type ThumbprintTokenTokens {
            value: ThumbprintTokenTokensValue!
        }

        type ThumbprintTokenTokensValue {
            web: String
            ios: String
            android: String
        }
    `;
    createTypes(typeDefs);
};

Tanpa menggunakan createTypes , GraphQL memang menghilangkan bidang. Data untuk file JSON tersebut berasal dari gatsby-source-filesystem dan gatsby-transformer-json . Saya menggunakan fungsi untuk konfigurasi typeName di gatsby-transformer-json .

Senang membuat repro kecil jika tampaknya peringatan itu tidak muncul.

Halo!

Saya mendapatkan kesalahan saat menggunakan tipe JSON bawaan.

// gatsby-node.js

export const sourceNodes = ({ actions: { createTypes }, schema }) => {
  createTypes([
    schema.buildObjectType({
      name: 'MyTypeName',
      fields: {
        id: 'ID!',
        json: 'JSON!',
      },
    }),
  ])
}

Kesalahan berikut dipancarkan:

success source and transform nodes — 1.550 s
error UNHANDLED REJECTION


  Error: Schema must contain unique named types but contains multiple types named "JSON".

  - Array.reduce

  - SchemaComposer.js:122 SchemaComposer.buildSchema
    [gatsby-ww]/[graphql-compose]/lib/SchemaComposer.js:122:12

  - schema.js:480
    [gatsby-starter-ww]/[gatsby]/dist/schema/schema.js:480:47

  - Generator.next

  - new Promise

  - schema.js:539 addCustomResolveFunctions
    [gatsby-starter-ww]/[gatsby]/dist/schema/schema.js:539:18

  - schema.js:162
    [gatsby-starter-ww]/[gatsby]/dist/schema/schema.js:162:11

  - Generator.next

Mungkinkah ini akibat dari graphql-compose menyediakan jenis JSON daripada menggunakan versi gatsby/graphql ?



gatsby info keluaran:


  System:
    OS: macOS 10.14.2
    CPU: (4) x64 Intel(R) Core(TM) i5-7600K CPU @ 3.80GHz
    Shell: 5.6.2 - /usr/local/bin/zsh
  Binaries:
    Node: 10.15.3 - /var/folders/3z/fgqk0pmx30l2pc4801884_sm0000gn/T/yarn--1554423671012-0.23391063288947023/node
    Yarn: 1.12.3 - /var/folders/3z/fgqk0pmx30l2pc4801884_sm0000gn/T/yarn--1554423671012-0.23391063288947023/yarn
    npm: 6.4.1 - ~/.n/bin/npm
  Languages:
    Python: 2.7.10 - /usr/bin/python
  Browsers:
    Chrome: 73.0.3683.86
    Firefox: 64.0
    Safari: 12.0.2
  npmPackages:
    gatsby: 2.3.11 => 2.3.11

@angeloashmore Itu harus diperbaiki dengan https://github.com/gatsbyjs/gatsby/pull/13028 , saya akan membuat versi pra-rilis hari ini sehingga Anda dapat menguji.

@danoc Saat ini tidak ada cara untuk menonaktifkan peringatan seperti itu. Dengan https://github.com/gatsbyjs/gatsby/pull/13028 jika Anda menggunakan @dontInfer , tidak ada pemeriksaan nilai contoh yang harus dilakukan dan kemudian tidak akan ada peringatan. Namun tidak akan ada kesimpulan juga.

@d4rekanguok Bisakah Anda memberikan reproduksi kecil untuk ini? Ini harus bekerja seperti yang Anda jelaskan.

Diterbitkan [email protected]

@samovertonjr @smurrayatwork Mohon jangan

Tidak tahu bahwa mengklik itu akan memengaruhi semua orang.

Diterbitkan 2.4.0-alpha.2 .

@prashant-andani Pleae jangan lepaskan pin masalah ini. Terima kasih!

Hai, itu tidak disengaja... maaf untuk itu

Pada Selasa, 30 Apr 2019 pukul 18:38, Lennart [email protected] menulis:

@prashant-andani https://github.com/prashant-andani Mohon jangan lepas pin
masalah ini. Terima kasih!


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/gatsbyjs/gatsby/issues/12272#issuecomment-487944961 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAGKROYK4RRFYRE3MOQL2NLPTBAE7ANCNFSM4G3OVU5Q
.

>

Salam
Prashant S Andani

Apa urutan eksekusi untuk pemetaan? Saya memiliki satu set posting yang saya coba petakan ke kategori seperti contoh post -> authors . Sumber mentah saya memiliki nomor id, jadi saya menggunakan tipe create untuk menegakkan asumsi string. Sayangnya, pemetaan sepertinya tidak berfungsi jika saya menggunakan createTypes . Saya pikir createTypes berjalan sebelum skema master dibuat?

//gatsby-config.js
  mapping: {
    "MarkdownRemark.frontmatter.speaker": `AuthorsYaml.name`, // works as expected
    "MarkdownRemark.frontmatter.categories": `CategoriesYaml`,
  },
//gatsby-node.js
exports.sourceNodes = ({ actions }) => {
  const { createTypes } = actions
  const typeDefs = `
  type MarkdownRemarkFrontmatter {
    categories: [String]
  }

  type MarkdownRemark implements Node {
    frontmatter: MarkdownRemarkFrontmatter
  }
  `
  createTypes(typeDefs)
}

Menanyakan…

{
  allMarkdownRemark {
    nodes {
      frontmatter {
        categories
        speaker {
          name
        }
      }
    }
  }
}

Hasil…

    "allMarkdownRemark": {
      "nodes": [
        {
          "frontmatter": {
            "categories": [
              "22"
            ],
            "speaker": {
              "name": "Sean Higgins"
            }
          }
        }
]

Saya menemukan solusi yang berfungsi di mana saya memberi tahu tipe untuk mengharapkan tipe CategoryYaml alih-alih memaksanya ke string dan menggunakan resolver khusus untuk mengambil data.

Sepertinya dengan mekanisme pemetaan di tempat, saya mungkin harus bisa memaksakan paksaan string, dan kemudian menggunakan pemetaan untuk melakukan hookup untuk saya.

Mungkin aku kehilangan sesuatu?

Jenis bersarang:

  • Menggunakan gatsby-source-prismic
  • Ini menghasilkan tipe kompleks dengan tipe objek bersarang di dalam objek

misalnya

  PrismicNewsBody
    PrismicNewsBody
      PrismicNewsBodyPrimary
      PrismicNewsBodyItems

Tipe memiliki gagasan grup yang dapat diulang (yang berakhir di Item) tetapi jika Anda tidak memiliki apa pun di grup, kueri untuk itu gagal (karena Anda menanyakan anggota tipe yang belum disimpulkan).

Namun, jika Anda menentukan tipenya sehingga Anda dapat mendeklarasikan items , itu dipanggil sebagai duplikat setelah Anda benar-benar menggunakan grup berulang; meninggalkan Anda dalam keadaan di mana Anda memiliki bagian data [0..

Jadi bisakah kode (apakah sudah ada cara) menggabungkan jenis yang bukan implements Node ?


Berikutnya: Sistem tipe Prismik adalah PITA kerajaan dan ketika menggunakan irisan, dll, membuat tipe dengan nama yang ditambahkan ke nama wadahnya. Ini masuk akal karena cara kerjanya - ia memiliki konsep "Perpustakaan irisan", tetapi ini adalah pustaka salinan, bukan pustaka referensi - definisi tipe hanya disalin ke tipe def untuk tipe konten.

Pemrogram OTOH membenci duplikasi. Jadi saya telah berhati-hati untuk memastikan jenis Irisan dari nama yang diberikan sama di mana-mana dengan mendefinisikannya di satu halaman, menyimpannya ke "perpustakaan" dan menyalinnya ke luar - bisakah kita (apakah kita?) memiliki kemampuan untuk tambahkan antarmuka jadi alih-alih

query {
  pageOne {
    data {
      body {
        ... on PageOneBodyMyslice {
          primary {
            field
          }
        }
      }
    }
  }
  pageTwo {
    data {
      body {
        ... on PageTwoBodyMyslice {
          primary {
            field
          }
        }
      }
    }
  }
}

... kita bisa lakukan

```
antarmuka MySlice {
utama {
bidang
}
}

entah bagaimana kami menandai jenis irisan halaman sebagai menerapkan ini

permintaan {
halaman satu {
data {
tubuh {
... di MySlice {
... MySliceFragment

dll

```

@awilkins gatsby-source-prismic penulis di sini.

Kami sedang berupaya menerapkan pemuatan skema otomatis sehingga Gatsby mengetahui segalanya tentang bentuk tipe kustom Anda. Kami berharap untuk menerbitkan versi beta minggu ini (yang juga mencakup sistem pratinjau!).

Anda perlu memberikan skema Anda ke plugin di masa mendatang.

Re: pertanyaan Anda tentang antarmuka, idenya masuk akal, tetapi saya tidak yakin apakah jenisnya digabungkan. Semua irisan mengimplementasikan antarmuka Node dan mengikuti konvensi penamaan pascalcase(${customType} ${sliceZoneName} ${sliceName}) .

@motleydev Hai! Jadi createTypes dan pemetaan dijalankan hampir bersamaan. Jenis yang ditentukan oleh pengguna selalu diprioritaskan daripada jenis pemetaan. Anda perlu menggunakan penyelesai khusus dalam kasus ini. Gatsby tidak dapat benar-benar mengetahui bahwa Anda menginginkan objek yang akan diserialisasikan sebagai string dalam kasus ini, karena String dan KategoriYaml bukan tipe yang kompatibel.

@angeloashmore Terima kasih atas tanggapannya! Saya akan menantikannya; klien saya pasti menginginkan perubahan dan ini akan membuat segalanya lebih mudah.

antarmuka

Saya yakin Anda telah mencatat bahwa karena cara Prismic melakukan sesuatu, itu "slice library" hanya memungkinkan Anda menyalin informasi tipe slice ke tipe kustom Anda - jadi nama tipe yang berbeda diperlukan dari POV yang sebenarnya dapat Anda miliki jenis irisan yang sangat berbeda dengan nama yang sama di jenis halaman yang berbeda.

Ini adalah PITA untuk memperbarui jenis irisan di CMS karena Anda harus melakukannya di satu tempat, lalu salin itu ke semua jenis lainnya, lalu buka semua konten dan perbarui (jika Anda memperkenalkan perubahan yang tidak kompatibel).

Tapi... jika Anda berperilaku baik tentang hal itu dan melakukan ini secara konsisten (atau hanya memiliki set irisan yang sangat baik digunakan dan matang), manfaat dapat mendeklarasikan satu fragmen GraphQL global untuk setiap jenis irisan atau (mungkin? ) bahkan satu untuk semua irisan akan menyenangkan - tetapi fragmen hanya dapat diterapkan ke jenis atau antarmuka, oleh karena itu keinginan untuk menetapkan antarmuka umum ke jenis irisan yang berbeda tetapi identik dengan nama yang sama pada halaman yang berbeda.

Diterbitkan [email protected] .

Halo semuanya. Saya telah memperbarui ke Gatsby 2.5.0 tetapi tampaknya mengalami konflik tipe yang sama dengan @angeloashmore antara graphql-compose dan gatsby dengan tipe JSON. Apakah ada cara sederhana untuk menyelesaikan konflik ini?

Saya memutakhirkan dari Gatsby 1.9.x jika itu membantu. Log di bawah ini:

```
kesalahan PENOLAKAN YANG TIDAK TERTANGANI

Kesalahan: Skema harus berisi jenis bernama unik tetapi berisi beberapa jenis bernama "JSON".

  • Array.reduce

  • Array.reduce

  • SchemaComposer.js:130 SchemaComposer.buildSchema
    [blog]/[graphql-compose]/lib/SchemaComposer.js:130:12

  • schema.js:500
    [blog]/[gatsby]/dist/schema/schema.js:500:47

  • Generator.berikutnya

  • debuggability.js:313 Promise._execute
    [npm]/[gatsby-cli]/[bluebird]/js/release/debuggability.js:313:9

  • janji.js:483 Janji._resolveFromExecutor
    [npm]/[gatsby-cli]/[bluebird]/js/release/promise.js:483:18

  • janji.js:79 Janji baru
    [npm]/[gatsby-cli]/[bluebird]/js/release/promise.js:79:10

  • schema.js:559 addCustomResolveFunctions
    [blog]/[gatsby]/dist/schema/schema.js:559:18

  • schema.js:163
    [blog]/[gatsby]/dist/schema/schema.js:163:11

  • Generator.berikutnya

  • util.js:16 tryCatcher
    [npm]/[gatsby-cli]/[bluebird]/js/release/util.js:16:23

  • janji.js:512 Janji._settlePromiseFromHandler
    [npm]/[gatsby-cli]/[bluebird]/js/release/promise.js:512:31

  • janji.js:569 Janji._settlePromise
    [npm]/[gatsby-cli]/[bluebird]/js/release/promise.js:569:18

  • janji.js:606 Janji._settlePromiseCtx
    [npm]/[gatsby-cli]/[bluebird]/js/release/promise.js:606:10

  • async.js: 142 _drainQueueStep
    [npm]/[gatsby-cli]/[bluebird]/js/release/async.js: 142:12
    ````

@Spiderpig86 Apakah Anda memiliki masalah ini saat memutakhirkan ke 2.4? Saya ingin tahu apakah Anda dapat memberikan proyek reproduksi (atau kode ke aplikasi Anda).

Pada akhirnya, saya akhirnya menghapus dependensi apa pun yang saya miliki dan menginstal ulang semuanya sepenuhnya. Ini adalah konfigurasi yang saya gunakan sekarang dan bekerja dengan sangat baik.

Kami mengalami masalah dengan gatsby-source-prismic v3.0.0-alpha.2 dengan node File gatsby-source-filesystem .

Kami memberitahu Gatsby bidang gambar akan memiliki bidang localFile dengan tipe File , tetapi jika tidak ada File node yang dibuat di mana saja di situs, Gatsby tidak tahu apa File adalah.

Error: Type with name "File" does not exists

Maaf, ini mungkin pertanyaan gatsby-source-filesystem lebih dari pertanyaan penyesuaian skema, tetapi hanya ingin tahu apakah ada cara yang dapat dipercaya untuk memberi tahu Gatsby apa itu File . Apakah gatsby-source-filesystem perlu mengekspor definisi tipe File dari paket di mana plugin sumber dapat secara eksplisit memberikan ke Gatsby?

Masalah terkait: https://github.com/angeloashmore/gatsby-source-prismic/issues/97

@angeloashmore kita bisa membuat gatsby-source-filesystem secara eksplisit mendaftarkan tipe File (dan membuatnya tidak panic ketika jalur yang dikonfigurasi tidak ada). Dengan cara ini dimungkinkan untuk hanya menyediakan gatsby-source-filesystem (tanpa opsi) di gatsby-config dan memiliki tipe File tersedia dalam skema. Apakah sesuatu seperti ini akan berhasil dalam kasus Anda? Ini masih memerlukan gatsby-source-filesystem untuk diinstal karena memiliki tipe tersebut -- tetapi ada rencana yang belum konkrit untuk mungkin mempromosikan File ke tipe inti di beberapa titik.

@stefanprobst Ya, sesuatu seperti itu sepertinya bisa berhasil.

Berkenaan dengan pembuat plugin, jika plugin secara nondeterministik membuat node File, ini berarti:

  1. Penulis plugin harus meminta pengguna plugin untuk selalu menambahkan gatsby-source-filesystem ke gatsby-config.js untuk memastikan Gatsby mengetahui tipe File , atau
  2. Penulis plugin hanya menyertakan bidang yang menggunakan definisi tipe File jika plugin dapat menentukan node File akan dibuat. Yaitu jika kita tahu tidak ada node yang akan dibuat dengan bidang File , jangan sertakan bidang File pada simpul yang menggunakannya. Ini dapat merusak build jika kueri berisi bidang yang sekarang tidak ada.

Dengan Opsi 1, pengguna dapat melihat pesan kesalahan jalur yang tidak ada pada setiap develop atau build jika mereka tidak menyediakan jalur. Dalam beberapa proyek, mungkin tidak perlu menggunakan gatsby-source-filesystem kecuali untuk menyediakan tipe File . Mungkin kita bisa mengubahnya sehingga hanya memeriksa apakah ada jalur jika jalur disediakan?

Dengan Opsi 2, pembuat plugin perlu menangani peningkatan kompleksitas pelacakan pembuatan simpul File . Ini bisa sesederhana memperbarui variabel global tetapi masih sesuatu yang perlu dipertimbangkan.

Jika gatsby-source-filesystem mengekspor tipe File (melalui objek GraphQL atau string SDL) dan mengizinkan pembuat plugin untuk mendaftarkannya dengan createType , pengguna tidak perlu mengubah alur kerja dan pembuat plugin mereka tidak perlu melacak penggunaan File .

Hal ini berpotensi menyebabkan masalah di masa depan jika / ketika File jenis perubahan dan plugin menggunakan berbagai gatsby-source-filesystem versi dengan tidak kompatibel File definisi. Ini berfungsi dengan baik sekarang karena, dari apa yang saya pahami, Gatsby menyimpulkan bentuk secara agregat.

Untuk referensi, di sinilah kita mendefinisikan bidang menggunakan File : standardTypes.graphql . Ini diteruskan langsung ke createTypes .

Koreksi saya jika saya salah @pieh , @stefanprobst , tapi saya pikir menjadikan File sebagai tipe inti tidak akan menjadi perubahan besar. Itu hanya akan memecahkan kasus-kasus yang dulunya gagal karena File tidak ada di sana. Jadi saya mengusulkan agar kita melakukannya.

Maaf karena memasukkan ini ke sini, jika Anda dapat mengarahkan saya ke arah yang benar, saya akan mengajukan tiket yang lebih fokus.

tl;dr Jenis yang digerakkan oleh Frontmatter.

Saya berasal dari latar belakang CMS sehingga mengendalikan skema saya menarik. Situs Gatsby saya menggunakan Markdown frontmatter dengan type: author di YAML untuk menentukan "tipe", tetapi karena semuanya adalah tipe simpul MarkdownRemark , saya tidak mendapatkan skema nyata.

Saya sekarang memiliki tipe Author melalui createTypes . Saya telah mencoba beberapa cara untuk membuat simpul Author , lebih disukai sebagai anak dari simpul MarkdownRemark (sehingga dapat dihapus secara gratis), tetapi saya tidak dapat menemukan cara untuk melakukannya jadi. createNode tampaknya tidak tersedia di resolver.

@pauleveritt Salah satu cara untuk mengatur hubungan kunci asing antar bidang adalah dengan direktif @link . Untuk blog biasa (diposting sebagai file .md , info penulis, dan tag dalam file .yaml ), tampilannya seperti ini:

exports.sourceNodes = ({ actions }) => {
  actions.createTypes(`
    type MarkdownRemark implements Node <strong i="10">@dontInfer</strong> {
      frontmatter: Frontmatter
    }
    type Frontmatter {
      title: String!
      author: AuthorYaml @link(by: "email")
      tags: [TagYaml] @link(by: "slug")
    }
    type AuthorYaml implements Node <strong i="11">@dontInfer</strong> {
      name: String!
      email: String!
      info: String
      posts: [MarkdownRemark] @link(by: "frontmatter.author.email", from: "email")
    }
    type TagYaml implements Node <strong i="12">@dontInfer</strong> {
      slug: String!
      title: String!
      description: String
      posts: [MarkdownRemark] @link(by: "frontmatter.tags.slug", from: "slug")
    }
  `)
}

Saya juga telah menggabungkan ini dalam repo ini .

Kami juga akhirnya memiliki sedikit dokumentasi tentang API kustomisasi skema di sini . Harap beri tahu kami jika ada yang kurang jelas atau kurang.

@freiksenet Saya pikir itu tergantung apakah itu berarti memindahkan definisi tipe untuk File ke inti, atau jika (bagian dari) apa yang sekarang gatsby-source-filesystem harus dipindahkan juga. Memindahkan File saja menurut saya tidak masalah.

@stefanprobst Konsep rapi ... tapi saya pikir tantangannya ada di sini:

https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-transformer-remark/src/on-node-create.js#L45

Saya tidak tahu bagaimana saya bisa membuat simpul dibuat sebagai AuthorYaml berdasarkan frontmatter yang berasal dari gatsby-source-filesystem dan gatsby-transformer-remark .

Sepertinya saya harus berhenti memikirkan target tautan sebagai konten Penurunan harga dan menggunakan .yaml gatsby-transformer-yaml yang memungkinkan saya memberi nama jenis simpul.

@pauleveritt

gunakan .yaml gatsby-transformer-yaml

ya, inilah yang saya lakukan dalam contoh tertaut. Adakah alasan untuk memasukkan info penulis ke dalam file penurunan harga?

@stefanprobst "Ada alasan untuk menaruh info penulis di file penurunan harga?"

Saya ingin semuanya -- penulis, kategori, tag, dll. -- menjadi "sumber daya" kaya yang dapat diedit orang, menambahkan gambar, blok kode, hal-hal MDX di Markdown, dll.

Tapi aku tidak akan mendapatkan itu dengan mudah. :) Saya akan beralih ke YAML untuk itu. Sayangnya "konten reguler" saya (tutorial, artikel, posting blog) juga dapat menggunakan tipe dengan skema berbeda, tetapi saya akan tetap menggunakan skema yang disimpulkan, alih-alih dunia baru tipe/skema eksplisit yang dipromosikan sejak 2.2.2.

@pauleveritt ya, gatsby-transformer-remark hanya akan membuat satu jenis MarkdownRemark - dan menggunakannya untuk mewakili entitas yang berbeda akan menjadi masalah. jadi ini sebenarnya bukan masalah terkait skema, tetapi Anda memerlukan plugin transformator penurunan harga yang dapat membuat node makrkdown dengan nama berbeda (yang seharusnya cukup bisa dilakukan).

mengatakan bahwa (hanya sebagai percobaan), adalah mungkin untuk melakukan hal ini dengan MarkdownRemark node saja dan menggunakan @link pada bidang frontmatter. itu terlihat agak jelek tetapi berhasil, lihat di sini untuk contohnya.

@stefanprobst Saya mengerti maksud Anda, tapi saya pikir jika tujuannya adalah untuk melakukan lebih sedikit skema yang disimpulkan dan lebih banyak skema yang dideklarasikan, Markdown frontmatter harus ada dalam cakupan. Gatsby dengan file penurunan harga adalah kombo yang populer. Saya

Memiliki tipe/skema yang berbeda di Markdown akan lebih mudah jika gatsby-transformer-remark tidak membuat luas permukaan forking menjadi begitu besar. Ada banyak hal yang terjadi dalam fungsi panah yang melakukan penetapan tipe simpul.

Mari kita tutup percakapan ini. Saya mungkin termasuk sebagian kecil dari mereka yang menginginkan jenis konten yang berbeda dalam Penurunan Harga. Terima kasih banyak untuk kode sampelnya, itulah arah yang akan saya ambil untuk saat ini.

Mengenai runQuery dan parameter query ...Saya memiliki filter berfungsi dengan benar tetapi saya tidak bisa mendapatkan contoh sort berfungsi. Tes yang menggunakan sort tampaknya menggunakan runQuery dari string template. Ketika saya mencoba sort: { order: 'DESC', fields: ['frontmatter___date'] } (atau dengan 'desc' sebagai string) penyelesaiannya keluar.

@pauleveritt Apakah ini berfungsi dengan Array pada order ?

@stefanprobst Sayangnya, tidak. Ini:

sort: { order: ['DESC'], fields: ['frontmatter___date'] }

...mengarah ke:

error gatsby-node.js returned an error

  TypeError: Cannot read property 'resolve' of undefined

  - prepare-nodes.js:34 awaitSiftField
    [gatsby-theme-bulmaio]/[gatsby]/dist/redux/prepare-nodes.js:34:13

  - prepare-nodes.js:52 
    [gatsby-theme-bulmaio]/[gatsby]/dist/redux/prepare-nodes.js:52:69

  - Array.map

  - prepare-nodes.js:52 resolveRecursive
    [gatsby-theme-bulmaio]/[gatsby]/dist/redux/prepare-nodes.js:52:44
...

@pauleveritt sayangnya saya tidak dapat mereproduksi dengan pengaturan dasar ini - apakah Anda dapat memberikan repro kecil untuk masalah ini untuk dilihat? Ini akan sangat membantu, terima kasih!

@stefanprobst Menemukan penyebabnya: ini 2.8.x -- ingin saya mengajukan tiket baru?

Bayangkan gatsby-blog untuk repo YAML. Tambahkan ini ke gatsby-node.js :

exports.createResolvers = ({ createResolvers, schema }) => {
  createResolvers({
    Query: {
      allResourcesByType: {
        type: ['MarkdownRemark'],
        args: {
          resourceType: 'String'
        },
        resolve(source, args, context, info) {
          return context.nodeModel.runQuery({
            query: {
              filter: {
                frontmatter: {}
              },
              sort: { fields: ["frontmatter___title"], order: ["ASC"] },
            },
            type: `MarkdownRemark`
          })
        }
      }
    }
  })
}

Di gatsby 2.7.6 Anda dapat meminta allResourcesByType di explorer. Di 2.8.0-2.8.2 Anda mendapatkan kesalahan penyelesaian.

@stefanprobst Saya mencoba mengonversi tag yang saya tentukan sebagai array string di frontmatter posting saya menjadi tipe Tag dengan bidang title dan slug mana title hanyalah string yang saya tulis dan slug = _.kebabCase(title) . Saya mengumpulkan cuplikan ini

exports.sourceNodes = ({ actions, schema }) => {
  actions.createTypes([
    `type MarkdownRemark implements Node {
      frontmatter: MarkdownRemarkFrontmatter
    }`,
    `type Tag { title: String!, slug: String! }`,
    schema.buildObjectType({
      name: `MarkdownRemarkFrontmatter`,
      fields: {
        tags: {
          type: `[Tag!]`,
          resolve(source) {
            if (!source.tags) return null
            return source.tags.map(tag => ({
              title: tag,
              slug: kebabCase(tag),
            }))
          },
        },
      },
    }),
  ])
}

yang berfungsi untuk menambahkan tipe Tag ke MarkdownRemarkFrontmatter.tags . Tapi tentu saja, ketika saya mencoba mengelompokkan semua tag dengan

tags: allMarkdownRemark {
  group(field: frontmatter___tags) {
    title: fieldValue
    count: totalCount
  }
}

Saya hanya mendapatkan string yang saya tulis ke frontmatter. Saya mencoba menulis resolver untuk allTags seperti itu

exports.createResolvers = ({ createResolvers }) => {
  const resolvers = {
    Query: {
      allTags: {
        type: [`Tag`],
        resolve(source, args, context) {
          return context.nodeModel.getAllNodes({
            type: `MarkdownRemarkFrontmatterTags`,
          })
        },
      },
    },
  }
  createResolvers(resolvers)
}

tapi tidak bisa membuatnya bekerja. Ada saran?

@janosh

  • Saat mengubah jenis bidang frontmatter.tags dari [String] menjadi [Tag] , argumen field dari group juga harus disesuaikan frontmatter___tags___title atau frontmatter___tags___slug . Sayangnya ini belum bekerja dengan benar, karena kami tidak memanggil penyelesai bidang untuk bidang group , hanya untuk bidang filter dan sort (lihat #11368).
  • Untuk saat ini, Anda dapat mengatasinya dengan menggunakan filter tiruan untuk memicu penyelesai bidang:
{
  allMarkdownRemark(filter: {frontmatter: {tags: {elemMatch: {title: {ne: null}}}}}) {
    group(field: frontmatter___tags___title) {
      fieldValue
      totalCount
      nodes {
        frontmatter {
          title
        }
      }
    }
  }
}

Memperbaiki ini ada di daftar tugas saya -- saya akan melakukannya secepatnya

  • Masalah dengan cuplikan createResolvers adalah ini: getAllNodes akan mengambil node menurut jenisnya, di mana "node" berarti objek dengan ID unik yang dibuat oleh plugin sumber atau transformator (dengan createNode tindakan). Jadi, Anda harus mengambil node MarkdownRemark , dan kemudian memanipulasi lebih lanjut hasilnya di resolver.
  • Bergantung pada kasus penggunaan Anda, Anda bahkan mungkin tidak perlu menggunakan createTypes , tetapi cukup menambahkan bidang kueri root khusus untuk mengelompokkan posting berdasarkan tag, dan menyertakan bidang slug:
// gatsby-node.js
const { kebabCase } = require(`lodash`)

exports.createResolvers = ({ createResolvers }) => {
  createResolvers({
    Query: {
      allMarkdownRemarkGroupedByTag: {
        type: [
          `type MarkdownRemarkGroup {
            nodes: [MarkdownRemark]
            count: Int
            tag: String
            slug: String
          }`,
        ],
        resolve(source, args, context, info) {
          const allMarkdownRemarkNodes = context.nodeModel.getAllNodes({
            type: `MarkdownRemark`,
          })

          const groupedByTag = allMarkdownRemarkNodes.reduce((acc, node) => {
            const { tags } = node.frontmatter
            tags.forEach(tag => {
              acc[tag] = (acc[tag] || []).concat(node)
            })
            return acc
          }, {})

          return Object.entries(groupedByTag).map(([tag, nodes]) => {
            return {
              nodes,
              count: nodes.length,
              tag,
              slug: kebabCase(tag),
            }
          })
        },
      },
    },
  })
}

@stefanprobst Terima kasih atas balasan cepatnya!

Jadi, Anda harus mengambil node MarkdownRemark, dan kemudian memanipulasi lebih lanjut hasilnya di resolver.

Saya berpikir untuk melakukan itu tetapi curiga bahwa saya mengabaikan sesuatu dan karenanya mendekati ini dari sudut yang salah. Terima kasih telah menyelesaikan masalah ini dan berencana menambahkan dukungan untuk resolver bidang untuk bidang group !

Mungkin solusi lain adalah membiarkan Tag mengimplementasikan Node sedemikian rupa sehingga Gatsby membuat kueri allTag secara otomatis.

type Tag implements Node { title: String!, slug: String! }

Maka yang harus saya lakukan adalah benar-benar membuat simpul bertipe Tag setiap kali saya menemukan yang baru dalam panggilan ke schema.buildObjectType untuk MarkdownRemarkFrontmatter . Apakah mungkin untuk menerapkan efek samping seperti ini dari dalam resolver? Yaitu dalam hal ini periksa apakah Tag dengan judul MyTag ada dan jika tidak createNode({type: `Tag`, title: `MyTag, slug: `my-tag` }) .

@pauleveritt maaf atas jawaban yang terlambat!

Dalam contoh Anda, penyortiran harus bekerja dengan ini:

exports.createResolvers = ({ createResolvers }) => {
  createResolvers({
    Query: {
      allResourcesByType: {
        type: ["MarkdownRemark"],
        args: {
          resourceType: "String",
        },
        resolve(source, args, context, info) {
          return context.nodeModel.runQuery({
            query: {
              sort: { fields: ["frontmatter.post_title"], order: ["DESC"] },
            },
            type: "MarkdownRemark",
          })
        },
      },
    },
  })
}

Perhatikan bahwa keduanya mengurutkan fields dan order adalah array, dan fields menggunakan notasi titik alih-alih garis bawah tiga kali untuk memisahkan bidang. (Kita harus mendokumentasikan ini! EDIT: #14681)
Ada dua alasan mengapa ini berbeda di runQuery dibandingkan saat menggunakan string kueri (yaitu di Graph_i_ql explorer):

  • pada bidang daftar, nilai skalar akan secara otomatis diuraikan sebagai larik item tunggal (inilah mengapa mungkin untuk mengatakan DESC ). saat ini kami tidak melakukannya dengan runQuery (mungkin sebaiknya)
  • fields dan order keduanya adalah bidang GraphQLEnum . Di Graph_i_ql Anda akan menggunakan kunci enum, sementara runQuery membutuhkan nilai enum internal. Misalnya enum fields memisahkan bidang dengan garis bawah tiga kali karena graphql tidak mengizinkan titik, tetapi secara internal ini diterjemahkan ke bidang dalam notasi titik.

Pengelompokan @janosh pada bidang yang diselesaikan sekarang harus bekerja dengan [email protected]

@stefanprobst Wow, itu cepat! Terima kasih untuk pembaruannya.

Apakah ada cara untuk mendapatkan judul dan siput tag dalam satu pengelompokan? Saya hanya dapat mengetahui cara mengelompokkan salah satunya dan kemudian hanya memiliki akses ke salah satunya.

{
  tags: allMarkdownRemark {
    group(field: frontmatter___tags___(slug|title)) {
     (slug|title): fieldValue
      count: totalCount
    }
  }
}

Jika saya mencoba mengelompokkan berdasarkan frontmatter___tags ,

{
  tags: allMarkdownRemark {
    group(field: frontmatter___tags) {
      tag: fieldValue
      count: totalCount

    }
  }
}

Saya hanya mendapatkan satu hasil

{
  "data": {
    "tags": {
      "group": [
        {
          "tag": "[object Object]",
          "count": 52
        }
      ]
    }
  }
}

@janosh Anda hanya dapat mengelompokkan berdasarkan satu bidang (sub-pengelompokan hierarkis tidak dimungkinkan). jika Anda membutuhkan nilai title dan slug , Anda dapat mengelompokkan satu per satu, dan mendapatkan nilai yang lain dari hasilnya (mungkin saya salah paham?):

{
  allMarkdownRemark {
    group(field: frontmatter___tags___title) {
      fieldValue
      totalCount
      nodes {
        frontmatter {
          tags {
            slug
            title
          }
        }
      }
    }
  }
}

@stefanprobst Itu tidak sesuai dengan kasus penggunaan saya, tetapi itu hanya ketidaknyamanan kecil. Terima kasih atas semua pekerjaan luar biasa yang Anda lakukan dalam penyesuaian skema!

Saya mengalami masalah sejak 2.2.0 yang tampaknya terkait dengan OS. Saya akan berterima kasih untuk mendapatkan mata pengguna Windows 10 lain untuk pengujian sehingga saya dapat mengonfirmasi atau mengesampingkannya: https://github.com/escaladesports/gatsby-plugin-netlify-cms-paths/issues/10

Terima kasih!

@laradevitt Saat ini saya tidak memiliki akses ke mesin windows, dan saya juga tidak terbiasa dengan gatsby-plugin-netlify-cms-paths -- tetapi apakah itu berfungsi jika Anda mengganti jalur pada frontmatter.image ke jalur relatif , yaitu ../static/media/gatsby-astronaut.png ?

@stefanprobst - Terima kasih atas balasan Anda! Ya, memang, tetapi inti dari plugin adalah Anda tidak harus menggunakan jalur relatif:

Plugin gatsby untuk mengubah jalur file di file penurunan harga menjadi jalur ramah-Gatsby saat menggunakan Netlify CMS untuk mengeditnya.

Saya telah membuat permintaan tarik dengan perbaikan yang membuat platform jalur relatif yang dikembalikan agnostik.

Saya masih tidak tahu mengapa putus dengan 2.2.0. 🤷♀

@laradevitt ah, maaf, seharusnya memeriksa readme.

Saya masih tidak tahu mengapa putus dengan 2.2.0.

Ini sangat mungkin merupakan regresi di Gatsby, karena inferensi tipe 2.2.0 sedikit berubah -- tetapi menormalkan jalur di gatsby-plugin-netlify-cms-paths tampaknya lebih benar :+1:

@stefanprobst

Saya baru saja membuat tiket baru yang terkait dengan penyesuaian skema. Jika lebih baik bagi saya untuk menutupnya dan memasukkannya ke dalam utas payung ini, beri tahu saya.

https://github.com/gatsbyjs/gatsby/issues/16099

Terima kasih!

Keterangan

Argumen dalam kueri graphQL tidak berfungsi saat menggunakan penyesuaian skema.

Setelah menonton aliran belajar dengan Jason di GraphQL tingkat lanjut (dipecah menjadi beberapa bagian karena kesulitan teknis), saya memasukkan banyak hal yang dibicarakan ke dalam tema saya.
Namun menggunakan argumen graphQL (seperti filter dan sortir) yang mengandalkan nilai dari skema yang disesuaikan tidak berfungsi.

Langkah-langkah untuk mereproduksi

jalankan cabang tema saya ini secara lokal.
Jalankan /___graphql dan query allBlogPosts.
Sekarang coba query allBlogPosts lagi dengan mengurutkan berdasarkan tanggal turun.
HASIL: tidak ada perubahan urutan (ASC, atau DESC)

Contoh 2

Query untuk semua posting dan tampilkan judulnya.

query MyQuery {
  allBlogPost {
    nodes {
      title
    }
  }
}

HASIL: bekerja

sekarang kueri untuk semua posting yang memiliki tag dengan slug "lorem-ipsum"

query MyQuery {
  allBlogPost(filter: {tags: {elemMatch: {slug: {eq: "lorem-ipsum"}}}}) {
    nodes {
      title
    }
  }
}

HASIL: array node kosong.

solusi sementara, kemungkinan alasan mengapa itu tidak berhasil?

Cobalah untuk menanyakan satu BlogPost (pilih yang pertama secara default jika tidak ada argumen yang diberikan).
Sekarang coba kueri blogPost(slug: {eq: "herp-derpsum"}) .
Ini berfungsi, saya pikir karena saya menambahkan siput ke simpul MdxBlogPost.
https://github.com/NickyMeuleman/gatsby-theme-nicky-blog/blob/d29c966e639f4733caf9ee43e9f5755df42db71d/theme/gatsby-node.js#L209 -L210

Sepertinya argumen graphql menggunakan data dari node MdxBlogPost daripada hasil akhirnya setelah menjalankan resolvernya. Apakah kecurigaan saya dekat?

Lingkungan

Sistem:
OS: Linux 4.19 Ubuntu 18.04.2 LTS (Bionic Beaver)
CPU: (4) x64 Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz
Shell: 4.4.19 - /bin/bash
Biner:
Node: 12.4.0 - /tmp/yarn--1565124765846-0.45931526383359134/node
Benang: 1.16.0 - /tmp/benang--1565124765846-0.45931526383359134/benang
npm: 6.9.0 - ~/.nvm/versions/node/v12.4.0/bin/npm
Bahasa:
Python: 2.7.15+ - /usr/bin/python

Catatan tambahan

Bagian kode yang relevan ada di gatsby-node.js di direktori tema.
khususnya siklus hidup createSchemaCustomization dan onCreateNode .
Saya mencoba banyak berkomentar untuk menunjukkan proses pemikiran saya.

@NickyMeuleman maaf belum sempat melihat lebih dekat tetapi sepertinya Anda kehilangan ekstensi tautan di antarmuka BlogPost.

Anda menentukan bidang MdxBlogPost.tags untuk ditautkan berdasarkan nama:

tags: {
  type: "[Tag]",
  extensions: {
    link: { by: "name" },
  },
},

di typedefs untuk antarmuka BlogPost yang Anda miliki:

  interface BlogPost <strong i="12">@nodeInterface</strong> {
    tags: [Tag]
  }

Apakah itu bekerja dengan

  interface BlogPost <strong i="16">@nodeInterface</strong> {
    tags: [Tag] @link(by: "name")
  }

Terkait: #16466

Setelah menambahkan saran Anda, kueri allBlogPost dengan filter berdasarkan tag berhasil! Terima kasih!

di masa mendatang, apakah saya dapat menghapus @link dari antarmuka, karena Tag mungkin ditautkan secara berbeda per jenis yang mengimplementasikan antarmuka BlogPost? (pertanyaan yang sama untuk Penulis, pemfilteran di sana tidak berfungsi, bahkan dengan @link dipindahkan ke tingkat antarmuka.

@NickyMeuleman
terima kasih telah bereksperimen!
setelah melihat ini, saya pikir itu adalah sesuatu yang perlu kita perbaiki di inti: kedua masalah harus dengan fakta bahwa kita menggunakan penyelesai antarmuka saat menyiapkan node secara manual sehingga kita dapat menjalankan filter pada mereka. sebagai gantinya, kita harus menjalankan resolver dari tipe yang kita dapatkan dari antarmuka resolveType , yang juga terjadi ketika graphql memproses set pilihan.

Setelah https://github.com/gatsbyjs/gatsby/pull/17284 digabungkan, saya mencoba menghapus logika dalam tema saya untuk mengatasi ini.

Versi Gatsby bekas: 2.15.14
Tampaknya tidak berfungsi.
https://github.com/NickyMeuleman/gatsby-theme-nicky-blog/blob/bbc782332e6938daaa2fca1b25d6df7e78f19c6c/theme/gatsby-node.js#L278 -L282
Saat Anda mengomentari baris yang ditautkan di atas, pemfilteran di GraphQL pada bidang ini tidak lagi dimungkinkan.

LekoArts menyarankan agar saya mengajukan pertanyaan ini lebih terbuka daripada di perselisihan, karena ini mungkin topik yang bagus untuk dokumentasi.

Bagaimana cara menjelaskan hubungan Banyak ke Banyak dengan createSchemaCustomization?

Kasus penggunaan yang saya miliki adalah sebagai berikut:

  1. Saya memiliki Produk dan Toko. Toko dapat menampung sejumlah produk, dan produk tidak eksklusif untuk satu toko. Apa cara terbaik untuk mengekspresikan kedua jenis node ini?
  2. Saya mencoba membuat halaman untuk sistem permainan. Saya telah menyatakan setiap Kemampuan sebagai Node. Kemampuan memiliki sejumlah prasyarat, dan sejumlah keterampilan yang bergantung. Sebaiknya saya ingin menautkan ke halaman tersebut (prasyarat dan tanggungan) di halaman untuk keterampilan itu sendiri. Bagaimana cara memodelkan hubungan ini dalam graphQL, dan lebih jauh lagi, dalam api Gatsby untuk itu?

@Everspace Coba ini untuk 1. tambahkan ke gatsby-node.js . Saya belum mencoba ini tetapi saya melakukan sesuatu yang mirip dengan menautkan dari tipe khusus (menggunakan antarmuka simpul) ke gambar, dan itu berfungsi. Itu bergantung pada ekstensi tautan sehingga Anda harus menggunakan ID yang ditetapkan oleh Gatsby. Saya kira Anda dapat memetakan ID apa pun yang Anda gunakan di sumber data Anda ke ID Gatsby selama createPages ?

exports.createSchemaCustomization = ({ actions }) => {
  const { createTypes } = actions
  const typeDefs = [
    schema.buildObjectType({
      name: 'Store',
      fields: {
        products: {
          type: "[Product]",
          extensions: {
            link: {},
          },
        },
      },
      interfaces: ['Node'],
    }),
    schema.buildObjectType({
      name: 'Product',
      fields: {
        stores: {
          type: "[Store]",
          extensions: {
            link: {},
          },
        },
      },
      interfaces: ['Node'],
    }),
  ]
  createTypes(typeDefs)
}

@NickyMeuleman Apakah maksud Anda Anda tidak mendapatkan hasil atau Anda tidak melihat bidang di objek input?

Ketika saya mengomentari kunci date di tautan itu , pengurutan berdasarkan tanggal tidak lagi berpengaruh.

query MyQuery {
  allBlogPost(sort: {fields: date, order: DESC}) {
    nodes {
      date(fromNow: true)
    }
  }
}

memiliki hasil (tidak kosong) yang sama dengan kueri yang sama dengan urutan yang disetel ke ASC .
Berharap itu tidak perlu karena ada penyelesai tanggal khusus

Apakah ada contoh di luar sana tentang cara menangani penyesuaian skema untuk gambar opsional yang berasal dari Contentful?

Sudah lama sejak Skema Kustomisasi telah dirilis dan semuanya stabil. Saya pikir sudah waktunya untuk menutup masalah ini

Kerja luar biasa @freiksenet dan @stefanoverna ❤️

Teman-teman, jika Anda mengalami masalah terkait dengan Kustomisasi Skema, mari kita buka masalah independen. Terima kasih!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

benstr picture benstr  ·  3Komentar

ferMartz picture ferMartz  ·  3Komentar

signalwerk picture signalwerk  ·  3Komentar

ghost picture ghost  ·  3Komentar

andykais picture andykais  ·  3Komentar