Vue CLI

Creating a Vue project...

Previously

vue init

The good old'

Lots of templates

Scaffolding only

Eject only

Difficult upgrades

Enter the next best thing...

Vue CLI 3.0

yarn global add @vue/cli
yarn global remove vue-cli

Install it now!

How is it different?

A complete rewrite from scratch

An entirely new architecture based on plugins

A powerful and extensive API

The Ultimate Objective...

The standard build toolchain for Vue

Vue CLI 3.0

Feature-rich

vue create

Built-in

zero-config

fully-featured

Webpack 4

Babel 7

PostCSS

SASS

Stylus

LESS

Auto-generated HTML

Modern mode

Multi-page support

Library target

Web component target

All of this...

Out-of-the-box!

No Template

PLUGINS

Pick

the additional features

you want...

Typescript

ESLint/TSLint/Prettier

Vue Router

Vuex

PWA

Want to write

tests?

Cypress

Jest

Mocha

Nightwatch

Add new features after project creation

Plugins can be upgraded thus upgrading the app

vue create

is not the end of the story...

vue-cli-service <command>

@vue/cli-service

@vue/cli-plugin-typescript

@vue/cli-plugin-eslint

@vue/cli-plugin-pwa

Your project

Creation

Development

Production build

Deployment

...

Something is still missing?

Community plugins

275+ plugins already available

Create your own!

One more thing...

Vue CLI

UI

vue ui

Graphical User Interface (web app)

Node.js GraphQL Server

vue ui

No

electron

needed

But CLI is "Command Line Interface"?!?

WAIT

Vue CLI 3.0 is more complex

More choices

More commands

More options

But we still shoot for

Ease of Access

with simple-to-use tools

So let's

Interfacize

(thanks, @Compulves)

Everything

More context

Detailed explanations

Better discoverability

Better prompts

Localization

More context

Detailed explanations

Discoverability

Better prompts UI

Localization

That's not all...

UI Plugin API

EXTEND

VUE-CLI UI!

Install Prompts

// 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,
  },
]

Install Prompts

Configuration Screen

// 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'),
      })
    },
  })
}

Configuration Screen

Custom components

// 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'
  })
}

Custom components

// 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',
}

Augmented Task

// 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()
    },
  })
}

Augmented Task

Widget

// 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'
          }
        ]
      }
    }
  })
}

Widget

UI Plugin API

  • Suggestions
  • Custom page
  • Custom components
  • Shared data
  • Actions
  • Hooks

What's coming up?

vue upgrade

Better error overlay

Settings page

Command box and keyboard shortcuts

Global UI Plugins

More info

cli.vuejs.org

Silver sponsor

Guillaume Chau

@Akryum

github.com/Akryum

Thank you!

Why vue-cli needed a UI and what you can do with it

By Guillaume Chau

Why vue-cli needed a UI and what you can do with it

We will go through why and how the UI was built and how you can extend it so it can be even more useful!

  • 5,507