@Akryum
vue init
yarn global add @vue/cli
yarn global remove vue-cli
vue create my-app
cd ./my-app
yarn serve
yarn build
vue create
vue create
vue-cli-service <command>
@vue/cli-service
@vue/cli-plugin-typescript
@vue/cli-plugin-eslint
@vue/cli-plugin-pwa
vue ui
Graphical User Interface (Vue app)
Server
(Node.js + Apollo)
vue ui
GraphQL
@Compulves
Install vue cli plugins
Execute plugin generators
Install additional dependencies
Final processing
// prompts.js
module.exports = [
  {
    type: 'confirm',
    name: 'addApolloEngine',
    message: 'Add Apollo Engine?',
    link: 'http://engine.apollographql.com/',
    default: false,
    group: 'GraphQL Server',
    when: answers => answers.addServer,
  },
  {
    type: 'input',
    name: 'apolloEngineKey',
    message: 'API Key:',
    validate: input => !!input,
    group: 'GraphQL Server',
    when: answers => answers.addApolloEngine,
  },
]
// ui.js
module.exports = api => {
  // Config file
  api.describeConfig({
    id: CONFIG,
    name: 'Apollo Server',
    description: 'Integrated GraphQL server',
    link: 'https://github.com/Akryum/vue-cli-plugin-apollo#configuration',
    files: {
      vue: {
        js: ['vue.config.js'],
      },
      graphql: {
        yaml: ['.graphqlconfig.yml'],
      },
    },
    onRead: ({ data, cwd }) => {
      return {
        prompts: [
          {
            name: 'enableMocks',
            message: 'Mocking',
            description: 'Enable auto-mocking for quick prototyping',
            link: 'https://github.com/Akryum/vue-cli-plugin-apollo#mocks',
            type: 'confirm',
            file: 'vue',
            default: false,
            value: getConfigData(data).enableMocks,
          },
        ],
      }
    },
    onWrite: async ({ api, prompts, cwd }) => {
      const result = {}
      for (const prompt of prompts.filter(p => p.raw.file === 'vue')) {
        result[`pluginOptions.apollo.${prompt.id}`] = await api.getAnswer(prompt.id)
      }
      api.setData('vue', result)
      // Update app manifest
      const serverFolder = result['pluginOptions.apollo.serverFolder'] || prompts.find(p => p.id === 'serverFolder').raw.default
      api.setData('graphql', {
        'projects.app.schemaPath': path.join(serverFolder, 'schema.graphql'),
      })
    },
  })
}// ui.js
module.exports = api => {
  api.addClientAddon({
    id: 'org.akryum.vue-apollo.client-addon',
    path: path.resolve(__dirname, './client-addon-dist'),
  })
}// During plugin dev
module.exports = api => {
  api.addClientAddon({
    id: 'org.akryum.vue-apollo.client-addon',
    url: 'http://localhost:8043/index.js'
  })
}// src/main.js
import News from './components/News.vue'
ClientAddonApi.component('org.vue.widgets.components.news', News)
In client addon:
// vue.config.js
const { clientAddonConfig } = require('@vue/cli-ui')
module.exports = {
  ...clientAddonConfig({
    id: 'vue-apollo',
    port: 8043,
  }),
  outputDir: '../client-addon-dist',
}
// ui.js
module.exports = api => {
  api.describeTask({
    match: /vue-cli-service apollo:watch/,
    description: 'Run and watch the GraphQL server',
    link: 'https://github.com/Akryum/vue-cli-plugin-apollo#injected-commands',
    prompts: [
      {
        name: 'open',
        type: 'confirm',
        default: false,
        description: 'org.akryum.apollo.tasks.watch.open'
      },
    ],
    views: [
      {
        id: 'org.akryum.vue-apollo.views.playground',
        label: 'Playground',
        icon: 'gamepad',
        component: 'org.akryum.vue-apollo.components.playground',
      },
    ],
    defaultView: 'org.akryum.vue-apollo.views.playground',
    onRun: () => {
      api.ipcOn(onGraphqlServerMessage)
      setSharedData('running', true)
    },
    onExit: () => {
      api.ipcOff(onGraphqlServerMessage)
      resetData()
    },
  })
}// ui.js
module.exports = api => {
  api.registerWidget({
    id: 'org.vue.widgets.news',
    title: 'org.vue.widgets.news.title',
    description: 'org.vue.widgets.news.description',
    icon: 'rss_feed',
    component: 'org.vue.widgets.components.news',
    detailsComponent: 'org.vue.widgets.components.news',
    minWidth: 2,
    minHeight: 1,
    maxWidth: 6,
    maxHeight: 6,
    defaultWidth: 2,
    defaultHeight: 3,
    openDetailsButton: true,
    defaultConfig: () => ({
      url: 'https://vuenews.fireside.fm/rss'
    }),
    onConfigOpen: async ({ context }) => {
      return {
        prompts: [
          {
            name: 'url',
            type: 'input',
            message: 'org.vue.widgets.news.prompts.url'
          }
        ]
      }
    }
  })
}Silver sponsor
Guillaume Chau
@Akryum
github.com/Akryum