Vue CLI

@Akryum

Guillaume Chau

@Akryum

Vue.js Core Team

Creating a Vue project

Previously...

vue init

The good old'

Lots of incompatible 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!

Getting Started

vue create my-app
cd ./my-app
yarn serve
yarn build
vue create

Built-in features

Webpack 4

Babel 7

Typescript

PWA

Linting

Sass

Less

Stylus

Modern mode

Multi-page

Web components

Jest

Mocha

Cypress

Nightwatch

How?

Template

PLUGINS

Add new ones after project creation

Upgrade the features by upgrading the plugins

Pick the features you want

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

Vue CLI Runtime

Modify Webpack config on-the-fly

Register new commands

Creation

Development

Production build

Deployment

...

Testing

Something is still missing?

Community plugins

460+ plugins already available

Create your own!

One more thing...

Vue CLI

UI

vue ui

Graphical User Interface (Vue app)

Server

(Node.js + Apollo)

vue ui

GraphQL

No

electron

needed

CLI is for "Command Line Interface"?!?

BUT 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

@Compulves

Everything

More context

Detailed explanations

Better discoverability

Better prompts

Localization

And much more!

Install vue cli plugins

Execute plugin generators

Install additional dependencies

Final processing

What's going on?

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

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

What's next?

Better vue upgrade

Better error overlay

PNPM support

Settings page

Command box and keyboard shortcuts

Global UI Plugins

And more!

Check out

cli.vuejs.org

Silver sponsor

Bronze 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!

  • 6,816