DEV Community

Kelvin Igbinoba
Kelvin Igbinoba

Posted on

Creating and Publishing a vue-file-validator plugin with Vite and npm : A Comprehensive Guide

Introduction

As developers, we often face the challenge of validating file uploads in our web applications. Whether it's ensuring images meet certain dimensions or verifying that PDFs are within acceptable size limits, having a robust validation mechanism is crucial. This need inspired the creation of vue-file-validator, a versatile Vue.js plugin designed to simplify file validation for images and PDFs. In this post, I'll walk you through the journey of developing this plugin and the process of how i published it to npm and let me tell you this for free lol, it wasn't a smooth road 🛣️.

The Idea

The concept for vue-file-validator emerged from a common requirement: the need to validate different types of files (to handle repetition mostly) in a seamless and user-friendly way within Vue.js applications. The goal was to create a plugin that:

  • Handles various file types, particularly images and PDFs.
  • Allows customization through user-defined validation rules.
  • Provides meaningful error messages and alerts to users.

Planning and Initial Setup
Defining Core Requirements

Before diving into development, it was essential that i outline the core features:

  • File Type Validation: Ensure the uploaded file matches allowed MIME types.

  • File Size Validation: Verify that the file does not exceed a specified size.

  • Image Dimension Validation: Check the dimensions (height and width) of uploaded images.

  • PDF Validation: Validate basic properties of PDFs, such as ensuring they are readable and meet page count requirements.

  • Custom Validations: Allow users to define their own validation logic for both images and PDFs. This is actually the holy grail or the sauce 🤣 as you can pass any validation you need :)

Setting Up the Project
I began by setting up the project structure and initialising it with npm:

1. Create a New Directory:

mkdir vue-file-validator
cd vue-file-validator
Enter fullscreen mode Exit fullscreen mode

2. Initialize npm:

vue create vue-file-validator
Enter fullscreen mode Exit fullscreen mode

Writing the Plugin
I began by setting up a basic plugin structure, ensuring that it could be easily integrated into any Vue.js project. This involved defining a simple install method to register the validation function with Vue’s global properties.

Core Functionality
The core functionality revolves around validating files based on size, type, and custom rules. Here’s a step-by-step breakdown of how i implemented this:

1.File Size Validation: The plugin first checks the size of the selected file. If the file size exceeds the allowed limit, it triggers an alert (if enabled) and rejects the promise with an appropriate error message.

if (file.size / 1024 > options.sizeInKbAllowed) {
  if (options.showAlert) {
    alert(options.messages.fileSize);
  }
  reject(options.messages.fileSize);
  return;
}
Enter fullscreen mode Exit fullscreen mode

2. File Type Validation: Next, the plugin verifies the MIME type of the file against a list of allowed types. If the file type is not permitted, an alert is shown, and the promise is rejected. Note the showAlert is on by default.

if (!options.allowedTypes.includes(file.type)) {
  if (options.showAlert) {
    alert(options.messages.fileType);
  }
  reject(options.messages.fileType);
  return;
}
Enter fullscreen mode Exit fullscreen mode

3. Custom Validations (the sauce): Custom validation logic can be defined for both images and PDFs. This allows users to implement specific checks tailored to their application’s needs.

for (const validation of options.customValidations.image) {
  const result = validation(file, image);
  if (result !== true) {
    if (options.showAlert) {
      alert(result);
    }
    reject(result);
    return;
  }
}
Enter fullscreen mode Exit fullscreen mode

Image Validation
For image files, the plugin reads the file using the FileReader API and creates an Image object to check its dimensions. If the dimensions exceed the specified limits, an alert is shown, and the promise is rejected.

if (file.type.startsWith('image/')) {
  const image = new Image();
  image.src = event.target.result;
  image.onload = () => {
    if (image.height > options.heightOfImage || image.width > options.widthOfImage) {
      if (options.showAlert) {
        alert(options.messages.dimensions);
      }
      reject(options.messages.dimensions);
    } else {
      // Run custom image validations
      for (const validation of options.customValidations.image) {
        const result = validation(file, image);
        if (result !== true) {
          if (options.showAlert) {
            alert(result);
          }
          reject(result);
          return;
        }
      }
      resolve(file);
    }
  };
};
Enter fullscreen mode Exit fullscreen mode

PDF Validation
For PDF files, the plugin reads the file as an array buffer and checks its content to ensure it is a valid PDF. Custom PDF validations can also be applied, such as verifying the number of pages.

else if (file.type === 'application/pdf') {
  const pdfData = new Uint8Array(event.target.result);
  const pdfText = new TextDecoder('utf-8').decode(pdfData);
  if (pdfText.includes('PDF')) {
    // Run custom PDF validations
    for (const validation of options.customValidations.pdf) {
      const result = validation(file, pdfData, pdfText);
      if (result !== true) {
        if (options.showAlert) {
          alert(result);
        }
        reject(result);
        return;
      }
    }
    resolve(file);
  } else {
    if (options.showAlert) {
      alert(options.messages.invalidPdf);
    }
    reject(options.messages.invalidPdf);
  }
};
Enter fullscreen mode Exit fullscreen mode

Ensuring Vue Compatibility
One of the critical aspects was ensuring compatibility with both Vue 2 and Vue 3. This required conditional checks to determine the Vue version and register the validation function accordingly.

if (isVue3) {
  Vue.config.globalProperties.$validateFile = validateFile;
} else {
  Vue.prototype.$validateFile = validateFile;
}
Enter fullscreen mode Exit fullscreen mode

Challenges
1. PDF Validation: Reading and validating PDFs was challenging. I used the FileReader API to read the file as an array buffer and then interpreted it as text.

2. Compatibility: Ensuring compatibility between Vue 2 and Vue 3 was crucial. I used conditional checks based on the Vue version to handle differences.

Configuring Vite for Building the Plugin
To streamline the build process, I chose Vite, a fast build tool and development server for modern web projects. Vite's configuration is simple and efficient, making it a perfect choice for the needs of this plugin.

Vite Configuration
Here's how i configured Vite for the vue-file-validator:

1. Install Vite and Vite Vue Plugin (if you are not using vue3):

npm install vite @vitejs/plugin-vue --save-dev
Enter fullscreen mode Exit fullscreen mode

2.Create vite.config.js:

import { fileURLToPath, URL } from 'node:url';
import { resolve } from 'path';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [
    vue(),
  ],
  build: {
    lib: {
      entry: resolve(__dirname, 'lib/vue-file-validator.js'),
      name: 'vueFileValidator',
      fileName: 'vue-file-validator',
    },
    rollupOptions: {
      external: ['vue'],
      output: {
        globals: {
          vue: 'Vue',
        },
      },
    },
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

package.json Configuration
Here’s the package.json file and an explanation of the scripts key components:

{
  "name": "vue-file-validator",
  "version": "1.0.0",
  "private": false,
  "description": "A Vue.js plugin for validating files",
  "type": "module",
  "files": [
    "dist"
  ],
  "main": "./dist/vue-file-validator.umd.cjs",
  "module": "./dist/vue-file-validator.js",
  "exports": {
    ".": {
      "import": "./dist/vue-file-validator.js",
      "require": "./dist/vue-file-validator.umd.cjs"
    }
  },
  "repository": {
    "type": "git",
  },
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "keywords": [
    "vue",
    "plugin",
    "image",
    "file",
    "pdf",
    "library",
    "validation"
  ],
  "author": "Kelvin Igbinoba",
  "license": "MIT",
  "dependencies": {
    "typescript": "^4.0.0",
    "vue": "^3.4.21"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.4",
    "vite": "^5.2.8"
  }
}
Enter fullscreen mode Exit fullscreen mode

scripts for common tasks:

  • dev: Runs the Vite development server.
  • build: Builds the library using Vite.
  • preview: Previews the built library.

Building the plugin
The scripts section of the package.json includes a build script that uses Vite to build the library. Running npm run build triggers Vite to compile the source code into a production-ready bundle, which is output to the dist folder.

npm run build
Enter fullscreen mode Exit fullscreen mode

Publishing to npm

Once the plugin was built and tested, the final step was to publish it to npm.

1. Login to npm:

npm login
Enter fullscreen mode Exit fullscreen mode

2. Publish the Package:

npm publish --access public
Enter fullscreen mode Exit fullscreen mode

Conclusion

Building vue-file-validator was a rewarding experience. The process taught me a lot about file validation, plugin development, and the power of tools like Vite for building modern web projects. I hope this plugin helps you reading this and other developers to easily implement robust file validation in their Vue.js applications.

Feel free to check out the vue-file-validator package on npm.

Top comments (0)