Skip to content

Instantly share code, notes, and snippets.

@renoirb
Last active October 30, 2018 04:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save renoirb/fad59b87f07f345d980994e1934410cf to your computer and use it in GitHub Desktop.
Save renoirb/fad59b87f07f345d980994e1934410cf to your computer and use it in GitHub Desktop.
Attempt at making local module for Apollo GraphQL for Vue on Nuxt
From f1cf052838fa56c305f57e02f039bea5d957d81f Mon Sep 17 00:00:00 2001
From: Renoir Boulanger <hello@renoirboulanger.com>
Date: Mon, 29 Oct 2018 23:58:40 -0400
Subject: [PATCH] Attempt adding own Vue Apollo
---
modules/graphql.js | 73 ++++++++++++++++++++++++++++++++++
nuxt.config.js | 1 +
package.json | 14 +++++--
plugins/graphql-client.js | 41 +++++++++++++++++++
utils/apollo-client-factory.js | 61 ++++++++++++++++++++++++++++
5 files changed, 187 insertions(+), 3 deletions(-)
create mode 100644 modules/graphql.js
create mode 100644 plugins/graphql-client.js
create mode 100644 utils/apollo-client-factory.js
diff --git a/modules/graphql.js b/modules/graphql.js
new file mode 100644
index 0000000..da1de9b
--- /dev/null
+++ b/modules/graphql.js
@@ -0,0 +1,73 @@
+/**
+ * Nuxt.js GraphQL integration.
+ *
+ * Inspired by nuxt-community/apollo-module [1], but no need to de-duplicate Session.
+ * Refer to Nuxt module documentaiton [2]
+ *
+ * Methods available to this function are documented in api/internals-nuxt [3] as this.nuxt.
+ *
+ * [1]: https://github.com/nuxt-community/apollo-module/blob/master/lib/module.js
+ * [2]: https://nuxtjs.org/guide/modules
+ * [3]: https://nuxtjs.org/api/internals-nuxt
+ */
+
+/**
+ * path methods:
+ * - resolve
+ * - normalize
+ * - isAbsolute
+ * - join
+ * - relative
+ * - toNamespacedPath
+ * - dirname
+ * - basename
+ * - extname
+ * - format
+ * - parse
+ * - sep
+ * - delimiter
+ * - win32
+ * - posix
+ */
+import path from 'path'
+
+/**
+ * GraphQL Nuxt Module.
+ *
+ * Notice we're returning a function because we want access to this.
+ */
+export default function GraphQueryLanguageClientNuxtModule (moduleOptions = {}) {
+ // this.nuxt
+ // this.options
+ // this.requiredModules
+
+ const options = this.options.apollo || moduleOptions
+
+ const pathToPlugins = path.resolve(__dirname).replace(/modules/, 'plugins')
+ this.addPlugin(path.join(pathToPlugins, 'graphql-client.js'))
+
+ // Add graphql loader
+ this.extendBuild((config, {
+ isServer,
+ }) => {
+ config.resolve.extensions = config.resolve.extensions.concat('.graphql', '.gql')
+
+ const gqlRules = {
+ test: /\.(graphql|gql)$/,
+ use: 'graphql-tag/loader',
+ exclude: /(node_modules)/,
+ }
+
+ if (options.includeNodeModules) {
+ delete gqlRules.exclude
+ }
+
+ if (!config.module.rules.find(rule => rule.use === 'graphql-tag/loader')) {
+ config.module.rules.push(gqlRules)
+ }
+ if (isServer) {
+ // Adding proper way of handling whitelisting with Nuxt 2
+ this.options.build.transpile.push(/^vue-cli-plugin-apollo/)
+ }
+ })
+}
diff --git a/nuxt.config.js b/nuxt.config.js
index 9123d90..7198456 100644
--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -76,0 +77 @@ export default {
+ '@/modules/graphql',
diff --git a/package.json b/package.json
index a945142..951cb11 100644
--- a/package.json
+++ b/package.json
@@ -16 +15,0 @@
- "@unify360/ui": "https://u360main.cangis.cgi.com:50043/Unify360/ui.git#semver:^0.1.12",
@@ -18,0 +18 @@
+ "@unify360/ui": "https://u360main.cangis.cgi.com:50043/Unify360/ui.git#semver:^0.1.12",
@@ -21 +21 @@
- "nuxt": "^2.0.0",
+ "nuxt": "^2.2.0",
@@ -25 +25,9 @@
- "vuex-persistedstate": "^2.5.4"
+ "vuex-persistedstate": "^2.5.4",
+ "graphql": "^0.12.3",
+ "graphql-tag": "^2.10.0",
+ "vue-apollo": "^3.0.0-beta.25",
+ "apollo-client": "^2.4.1",
+ "vue-cli-plugin-apollo": "^0.17.0",
+ "apollo-cache-inmemory": "^1.2.9",
+ "apollo-link": "^1.0.3",
+ "apollo-link-http": "^1.2.0"
diff --git a/plugins/graphql-client.js b/plugins/graphql-client.js
new file mode 100644
index 0000000..bd2abd9
--- /dev/null
+++ b/plugins/graphql-client.js
@@ -0,0 +1,41 @@
+/**
+ * Nuxt.js GraphQL integration plugin.
+ *
+ * Where we bind how Vue/Nuxt configuration from the Module.
+ * Partly copied from [1]
+ *
+ * [1]: https://github.com/nuxt-community/apollo-module/blob/master/lib/templates/plugin.js
+ */
+
+import Vue from 'vue'
+import VueApollo from 'vue-apollo'
+import {
+ createApolloClient, createApolloProvider,
+} from '@/utils/apollo-client-factory'
+
+Vue.use(VueApollo)
+
+export default async ({
+ app, beforeNuxtRender, req, store, $axios, isHMR,
+}, inject) => {
+ const ApolloClient = createApolloClient()
+ const apolloProvider = createApolloProvider(ApolloClient)
+ app.apolloProvider = apolloProvider
+
+ if (process.server) {
+ const ApolloSSR = require('vue-apollo/ssr')
+ Vue.use(ApolloSSR)
+ beforeNuxtRender(async ({
+ Components, nuxtState,
+ }) => {
+ Components.forEach(Component => {
+ // Fix https://github.com/nuxt-community/apollo-module/issues/19
+ if (Component.options && Component.options.apollo && Component.options.apollo.$init) {
+ delete Component.options.apollo.$init
+ }
+ })
+ await ApolloSSR.prefetchAll(apolloProvider, Components, ctx)
+ nuxtState.apollo = ApolloSSR.getStates(apolloProvider)
+ })
+ }
+}
diff --git a/utils/apollo-client-factory.js b/utils/apollo-client-factory.js
new file mode 100644
index 0000000..c6570c4
--- /dev/null
+++ b/utils/apollo-client-factory.js
@@ -0,0 +1,61 @@
+/**
+ * Apollo Client wrapper.
+ *
+ * The client property should be an usable Apollo GraphQL client.
+ * As per graphql-client [1]
+ *
+ * [1]: https://github.com/Akryum/vue-cli-plugin-apollo/blob/master/graphql-client/src/index.js#L14
+ * https://akryum.github.io/vue-apollo/guide/installation.html#vue-cli-plugin
+ */
+
+import {
+ InMemoryCache,
+} from 'apollo-cache-inmemory'
+import VueApollo from 'vue-apollo'
+import {
+ createApolloClient as createApolloClientFactory,
+} from 'vue-cli-plugin-apollo/graphql-client'
+
+export const createApolloClient = opts => {
+ let clientConfig = {}
+
+ clientConfig.tokenName = 'UserToken'
+
+ const cache = Reflect.has(opts, 'cache') ? opts.cache : new InMemoryCache()
+
+ clientConfig.ssr = !!process.server
+ if (!process.server) {
+ cache.restore(window.__NUXT__ ? window.__NUXT__.apollo.defaultClient : null)
+ }
+
+ Object.keys(opts).forEach(key => Object.assign(clientConfig, Reflect.get(opts, key)))
+
+ clientConfig.cache = cache
+
+ let client = createApolloClientFactory({
+ ...clientConfig,
+ })
+
+ client.apolloClient.wsClient = client.wsClient
+
+ return client
+}
+
+export const createApolloProvider = apolloInstance => {
+ let providerOptions = {
+ clients: {},
+ }
+ providerOptions.defaultClient = apolloInstance.apolloClient
+
+ const vueApolloOptions = Object.assign(providerOptions, {
+ errorHandler (error) {
+ console.log(
+ '%cError',
+ 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;',
+ error.message
+ )
+ },
+ })
+
+ return new VueApollo(vueApolloOptions)
+}
--
2.17.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment