Skip to content

Manual Installation

This guide will walk through installing and setting up VueVentus along with Vite.js, Vue.js, Tailwind CSS, Vitest, Vue Test Utils and happy-dom.

Installing Vite/Vue

For this example guide, we'll use Vite.js to install both Vite and Vue.js. So navigate to the directory where you want to begin your project in the command line console and run the vite create command:

bash
npm create vite@latest
  1. Enter a Project Name in the Vite CLI interface
  2. Select vue for the framework
  3. Select vue-ts for the variant
  4. Either cd into your new directory if you want to run the app from inside the generated folder, or grab the generated files and move them all into the project root directory and delete the generated directory
  5. Install the application dependencies with:
bash
npm install

You can check to see the installation was successful by launching Vite's local dev server with:

bash
npm run dev

Installing Tailwind Labs Packages

To install Tailwind CSS and Headless UI, we'll be using the Vite.js Guide variation for this guide and example.

So from the project's root directory, run the following commands:

bash
npm install -D tailwindcss postcss autoprefixer tailwind-scrollbar @headlessui/vue @headlessui/tailwindcss
bash
npx tailwindcss init -p

Next up, open up the generated ./tailwind.config.cjs file now in the project root directory, and add the following code to include Vite/Vue files into Tailwind's parser:

javascript
// ./tailwind.config.cjs
module.exports = {
    content: [
        "./index.html",
        "./src/**/*.{vue,js,ts,jsx,tsx}",
    ],
    theme: {
        extend: {},
    },
    plugins: [],
}

Next, create a new file ./src/css/tailwind.css, and add the base Tailwind CSS directives to the file:

css
/* ./src/css/tailwind.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

Next up, include the tailwind.css file into the app and Vite's build process, by opening up the ./src/main.ts file and importing the css file like so:

javascript
import './css/tailwind.css'

Once everything has been added and saved, you can restart Vite and see Tailwind's effect on Vite's initial HelloWorld.vue and App.vue components with:

bash
npm run dev

Installing VueVentus

With Vue and Tailwind installed, it's time to install VueVentus. From your project's root directory, you can install the VueVentus package with:

bash
npm install @obewds/vueventus --save-dev

Updating Tailwind's Config

There's a few mods to the Tailwind config file needed to open up a more "design system" configuration for your app. These Tailwind updates bring a handful of extensions and additions to Tailwind's already awesome arsenal of atomic class name fragments.

To manage and maintain this, VueVentus uses JSON formatted data files as modules thanks to Node.js.

TIP

Feel free to read more about the Tailwind Data Modules used below before proceeding. Or continue to follow the docs from here and you will get to them soon enough!

Go ahead and open up your app's ./tailwind.config.cjs file, and add the following variables and require() methods:

javascript
// ./tailwind.config.cjs

const defaultTheme = require('tailwindcss/defaultTheme')
const vvPath = './node_modules/@obewds/vueventus/dist/data/'

module.exports = {

    // Enable darkMode using the 'class' option
    darkMode: 'class',

    content: [
        "./index.html",
        "./src/**/*.{vue,js,ts,jsx,tsx}",
        "./docs/**/*.{md,html,js}",
        // Include VueVentus default TWCSS classes (for prototyping):
        "./node_modules/@obewds/vueventus/**/*.{vue,js,ts,jsx,tsx,json}",
    ],

    theme: {
        extend: {
            // VueVentus heading/body text fragments and format to add custom/Google fonts
            fontFamily: {
                sans: ['Nunito', ...defaultTheme.fontFamily.sans],
                heading: ['Nunito', ...defaultTheme.fontFamily.sans],
                body: ['Nunito', ...defaultTheme.fontFamily.sans],
            },
            // VueVentus TW theme extensions
            animation: require( vvPath + 'extend.animation.json' ),
            keyframes: require( vvPath + 'extend.keyframes.json' ),
            maxWidth: require( vvPath + 'extend.maxWidth.json' ),
            rotate: require( vvPath + 'extend.rotate.json' ),
            scale: require( vvPath + 'extend.scale.json' ),
            transitionDuration: require( vvPath + 'extend.transitionDuration.json' ),
            width: require( vvPath + 'extend.width.json' ),
        },
        // VueVentus TW theme overrides
        colors: require( vvPath + 'app.color.data.json' ),
        fontSize: require( vvPath + 'theme.fontSize.json' ),
        listStyleType: require( vvPath + 'theme.listStyleType.json' ),
        opacity: require( vvPath + 'theme.opacity.json' ),
        screens: require( vvPath + 'theme.screens.json' ),
    },

    variants: {
        extend: {
            // VueVentus enable disabled variants for opacity classes
            opacity: ['disabled']
        },
        scrollbar: ['dark']
    },

    plugins: [
        // VueVentus deps should already be in node_modules :)
        require('@tailwindcss/forms'),
        require('@tailwindcss/typography'),
        require('@tailwindcss/aspect-ratio'),
        require('tailwind-scrollbar'),
        require('@headlessui/tailwindcss'),
    ],
}

Vite Setup

There's also a couple of tiny tweaks to make in our project's ./vite.config.js file:

javascript
// ./vite.config.ts

// import the resolve method
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

export default defineConfig({
    plugins: [
        vue()
    ],
    // add a resolve parameter/alias
    resolve: {
        alias: {
            '@': resolve(__dirname, 'src'),
        },
    },
    // optionally open page on server start
    server: {
        open: true,
    },
    build: {...},
})

Notice node.js's resolve() method import and it's use in the ./vite.config.js file. Using node method's with Typescript necessitates providing Typescript with types for node.js. So there's a couple additional things to do before moving on.

First up, we need to install node.js types using the @types/node package:

bash
npm install @types/node --save-dev

With @types/node installed, we still need to actually let Typescript know about node's types. And while we're in there, we might as well go ahead and provide Typescript with vite/client types, too!

Open up the project ./tsconfig.json file and add the following code into the compilerOptions object:

json
{
  "compilerOptions": {
    // ...
    "types": ["node", "vite/client"]
  },
  // ...
}

With the new types package and new tsconfig compiler options, it's often a good idea to close the project (in VS Code) and re-open it, to get Typescript to connect all the dots. Afterwards you can test that things are working as expected with:

bash
npm run dev

Installing Vitest

Vite.js and Vitest.js go together like peas and carrots, so let's go ahead and install Vitest and necessary dependencies for goodies like coverage reports and Vue Test Utils!

bash
npm install --save-dev vitest @vue/test-utils happy-dom @vitest/coverage-v8

With your testing deps installed, you can now add the following commands to your project ./package.json file:

json
{
  "scripts": {
    "test": "vitest --dom",
    "coverage": "vitest run --dom --coverage"
  }
}

And lastly, with Typescript involved it's advantageous to use a Vitest config file to control Vitest and not interfere with the Vite/Typescript configs. So go ahead and create a new file in the project root directory called ./vitest.config.ts and add the following code:

typescript
// ./vitest.config.ts

import vue from '@vitejs/plugin-vue'

export default {
    plugins: [
        vue()
    ],
    test: {
        globals: true,
        environment: 'happy-dom',
    },
}

Vitest Unit Test Example

Now to actually ensure everything is working, we need to create a quick component and a couple of rudimentary tests for that component to know we're ready to get to business!

The first step is to create a new component. For this example, and a standard Vue structure this would be: ./src/components/HelloVueVentus.vue, while in a Nuxt.js project structure this would be: ./components/HelloVueVentus.vue. Either way, add code like this to taste:

html
<!-- ./src/components/HelloVueVentus.vue // for Vue/Vite CLIs -->
<!-- ./components/HelloVueVentus.vue // for Nuxt -->
<script setup lang="ts">
    import { VvButton } from '@obewds/vueventus'
</script>
<template>
    <VvButton>
        <slot>Hello VueVentus</slot>
    </VvButton>
</template>

And lastly, create a new directory and/or test file ./tests/HelloVueVentus.test.js and add the following tests:

javascript
// ./tests/HelloVueVentus.test.js

import { mount } from '@vue/test-utils'
// for Vue/Vite CLI projects use:
import HelloVueVentus from '../src/components/HelloVueVentus.vue'
// for Nuxt projects use:
import HelloVueVentus from '../components/HelloVueVentus.vue'

test('HelloVueVentus.vue component imports successfully', async () => {
    expect(HelloVueVentus).toBeTruthy()
})

test('HelloVueVentus.vue component accepts an object literal slot value with markup and text content', async () => {
    const testObjLiteral = `<div>Hello VueVentus!!!</div>`
    const wrapper = mount(HelloVueVentus, {
        slots: { default: testObjLiteral },
    })
    expect(wrapper.html()).toContain(testObjLiteral)
})

Now you can run Vitest and see the fruits of your labor with:

bash
npm run test

And assuming @vitest/coverage-v8 was installed, you can run your testing coverage, too:

bash
npm run coverage

Released under the MIT License