0
votes

I setup a new Vue project with basic scaffolding using the Vue CLI and Vuetify with tree shaking to eliminate any components I don't need. I'm really only interested in the vendor files that have the Vuetify components (presumably the chunk-vender... files under dist/js and dist/css).

The HTML in my project is including those vendor files, but I don't understand how to register the plugin with Vue. For example, in my app's JS file:

Vue.use(vuetify); // where do I get the vuetify plugin object from?
new Vue({...})

Just to be clear, I'm not interested in the app JS/CSS files generated by the npm build. I'm only using that whole setup so that I can manually cherry pick the Vuetify components I want and create the necessary JS/CSS.

If I include the full-fat Vuetify script/css in my HTML from a CDN e.g.

<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/2.3.17/vuetify.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vuetify/2.3.17/vuetify.min.css" rel="stylesheet" type="text/css"/>

...then I can initialize Vuetify in my apps JS like:

new Vue({
    el: '#my-app',
    vuetify: new Vuetify(),
})

...so what I'm hoping to find out is if there is a way to initialize Vuetify using the vendor JS file produced from the Vue CLI build instead of the full CDN version. If I try to use the same initialzation method above when using the vendor build JS file, I get the error Vuetify is not defined.

1
if you added vuetify using vue cli, then isn't this all done for you? vuetifyjs.com/en/features/treeshaking/#vuetify-loader - Jaromanda X
I have an existing project that wasn’t created using the cli. I want to integrate some Vuetify components into my project. The only way I know of to get a selection of the components i want is to configure a build using the cli. I have the vendor output files from the build, but I don’t know how to use them. Presumably, the dummy app file created as part of the build is registering the Vuetify plugin somehow, but its minified/mangled so I can’t make any sense of it. - RTF
Why can't you just setup Vuetify tree-shaking in your other non-Vue-CLI project? - tony19
@tony19 I'm not actually using any build tools for my project or package manager. I'm just adding a version number to the Vuetify vendor files produced by the build. Although, as an alternative solution maybe you could provide a example of how to set that up or point me in the right direction? - RTF

1 Answers

1
votes

There's actually a more idiomatic way to create a library with Vue CLI. Your build NPM-script should specify the library build type and an entry point that exports a Vue plugin (e.g., src/plugins/vuetify.js), where only specific Vuetify components are installed.

For example, to create a Vue plugin that installs only VApp (required as root component in Vuetify 2.x), VContainer, VBtn, and VTextField components:

  1. Run these commands to generate a Vue CLI project with the default options:

    npx @vue/cli create --default my-vuetify
    cd my-vuetify
    
  2. Run this command from the project's root directory to add Vuetify to the project (and choose Default preset at prompt):

    npx @vue/cli add vuetify
    
  3. Edit the project's build NPM-script in package.json to create a library called MyVuetify (this will be the global variable set when the library is imported in your <script> tag):

    // package.json
    {
      "scripts": {
        // BEFORE:
        "build": "vue-cli-service build",
    
        // AFTER:
        "build": "vue-cli-service build --target lib --name MyVuetify src/plugins/vuetify.js",
      }
    }
    
  4. In the plugin's entry file, export a vuetify function that constructs a new Vuetify instance:

    // src/plugins/vuetify.js
    import Vuetify from 'vuetify/lib'
    
    export const vuetify = options => new Vuetify({ ...options })
    

    Also export a plugin object, containing an install function that specifies only the Vuetify components of interest:

    // src/plugins/vuetify.js
    import { VApp, VContainer, VBtn, VTextField } from 'vuetify/lib'
    
    export const plugin = {
      install(app, options) {
        app.use(Vuetify, {
          components: {
            // Vuetify 2.x requires `VApp` to be the root component, so `VApp`
            // needs to be exported unless you prefer the consumer app provided it
            VApp,
            VContainer,
    
            VBtn,
            VTextField,
          },
          ...options
        })
      }
    }
    
  5. Run this command to build the library:

    npm run build
    

Usage

In dist/demo.html from the library build output, load the UMD script (MyVuetify.umd.js), which sets a global named MyVuetify, containing the exports from the build output (defined earlier in step 4). Also load the styles (MyVuetify.css), which contains the CSS for the used Vuetify components.

<script src="./MyVuetify.umd.js"></script>
<link rel="stylesheet" href="./MyVuetify.css">

Finally, create a <script> block that installs the plugin from MyVuetify.plugin and initializes the Vue app's vuetify with MyVuetify.vuetify():

<script>
Vue.use(MyVuetify.plugin)

new Vue({
  vuetify: MyVuetify.vuetify(/* Vuetify options (e.g., `theme`) */),
})
</script>

Here's a complete dist/demo.html:

<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<script src="./MyVuetify.umd.js"></script>
<link rel="stylesheet" href="./MyVuetify.css">

<v-app id="app">
  <v-container>
    <form @submit.prevent="greet">
      <v-text-field v-model="name" label="Name"></v-text-field>
      <v-btn type="submit">Greet</v-btn>
    </form>
  </v-container>
</v-app>

<script>
Vue.use(MyVuetify.plugin)

new Vue({
  el: '#app',
  vuetify: MyVuetify.vuetify(),
  data: () => ({
    name: '',
  }),
  methods: {
    greet() {
      alert(`Hi ${this.name.trim() || 'there'}!`)
    }
  }
})
</script>

GitHub demo