vite-plugin-proto-global
v2.0.0
Published
Auto-import pure functions from utils folder and extend JavaScript prototypes globally in your Vite project
Maintainers
Readme
vite-plugin-proto-global
Transform your JavaScript development by auto-importing pure utility functions and extending native prototypes globally in your Vite project.
✨ Features
- 🚀 Auto-import from utils folder - Point to a directory and automatically extend prototypes
- 📁 Folder-based organization - Structure your utilities by type (
utils/array/,utils/string/) - 🎯 Pure functions - Keep your utilities testable and reusable
- 🔧 Manual configuration - Full control when you need it
- 📦 Zero runtime overhead - Extensions are injected at build time
- 🎨 TypeScript support - Full type definitions included
- ⚡ Vite 7 compatible - Works with the latest Vite
📦 Installation
npm i vite-plugin-proto-global -D
# or
yarn add vite-plugin-proto-global -D
# or
pnpm add vite-plugin-proto-global -D🚀 Quick Start
Auto-Import Mode (Recommended)
1. Create your utils folder structure:
utils/
├── array/
│ ├── sum.js
│ ├── average.js
│ └── unique.js
├── string/
│ ├── capitalize.js
│ ├── truncate.js
│ └── reverse.js
└── number/
├── square.js
└── clamp.js2. Write pure utility functions:
// utils/array/sum.js
export default function sum() {
return this.reduce((acc, val) => acc + val, 0);
}
// utils/string/capitalize.js
export default function capitalize() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
// utils/number/clamp.js
export default function clamp(min, max) {
return Math.min(Math.max(this, min), max);
}3. Configure the plugin:
// vite.config.js
import { defineConfig } from 'vite';
import { protoGlobalPlugin } from 'vite-plugin-proto-global';
export default defineConfig({
plugins: [
protoGlobalPlugin({
utilsDir: './utils',
namingConvention: 'folder', // Use folder name to determine prototype
}),
],
});4. Use anywhere in your project:
// No imports needed! Methods are available globally
const numbers = [1, 2, 3, 4, 5];
console.log(numbers.sum()); // 15
console.log(numbers.average()); // 3
const text = 'hello world';
console.log(text.capitalize()); // "Hello world"
const value = 150;
console.log(value.clamp(0, 100)); // 100📖 Configuration Options
Auto-Import Configuration
interface AutoImportConfig {
/**
* Path to the utilities directory (relative to project root)
* @example './utils'
*/
utilsDir: string;
/**
* Include only files matching these patterns
* @example ['sum', 'average']
*/
include?: string[];
/**
* Exclude files matching these patterns
* @example ['test', 'spec']
*/
exclude?: string[];
/**
* Naming convention for determining which prototype to extend
* - 'folder': Use folder name (e.g., utils/array/sum.js -> Array.prototype.sum)
* - 'prefix': Use file prefix (e.g., array_sum.js -> Array.prototype.sum)
* - 'auto': Try folder first, then prefix (default)
* @default 'auto'
*/
namingConvention?: 'folder' | 'prefix' | 'auto';
}Manual Configuration
For full control, you can still use the manual configuration:
// vite.config.js
import { defineConfig } from 'vite';
import { protoGlobalPlugin } from 'vite-plugin-proto-global';
export default defineConfig({
plugins: [
protoGlobalPlugin([
{
className: 'Array',
methods: {
sum: function () {
return this.reduce((acc, val) => acc + val, 0);
},
average: function () {
return this.length > 0 ? this.sum() / this.length : 0;
},
},
},
{
className: 'String',
methods: {
capitalize: function () {
return this.charAt(0).toUpperCase() + this.slice(1);
},
},
},
]),
],
});🎯 Use Cases
1. Project-Wide Utilities
Keep your codebase DRY by defining utilities once and using them everywhere:
// utils/array/chunk.js
export default function chunk(size) {
const chunks = [];
for (let i = 0; i < this.length; i += size) {
chunks.push(this.slice(i, i + size));
}
return chunks;
}
// Use anywhere
const items = [1, 2, 3, 4, 5, 6];
console.log(items.chunk(2)); // [[1, 2], [3, 4], [5, 6]]2. Domain-Specific Extensions
Add business logic helpers:
// utils/number/toCurrency.js
export default function toCurrency(currency = 'USD') {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency,
}).format(this);
}
// Use in your app
const price = 1234.56;
console.log(price.toCurrency()); // "$1,234.56"3. Shareable Utility Packages
Create and share utility collections across projects:
npm install my-company-utils// vite.config.js
protoGlobalPlugin({
utilsDir: './node_modules/my-company-utils/dist',
});🏗️ Project Structure Examples
Folder-Based (Recommended)
utils/
├── array/
│ ├── sum.js
│ ├── average.js
│ ├── unique.js
│ └── chunk.js
├── string/
│ ├── capitalize.js
│ ├── truncate.js
│ ├── slugify.js
│ └── reverse.js
└── number/
├── square.js
├── clamp.js
└── toCurrency.jsPrefix-Based
utils/
├── array_sum.js
├── array_average.js
├── string_capitalize.js
├── string_truncate.js
├── number_square.js
└── number_clamp.js💡 Best Practices
1. Keep Functions Pure
Your utility functions should be pure and only operate on this:
// ✅ Good - Pure function
export default function double() {
return this.map(x => x * 2);
}
// ❌ Bad - Side effects
export default function double() {
this.forEach((x, i) => (this[i] = x * 2)); // Mutates original
return this;
}2. Use Descriptive Names
Function names become method names, so make them clear:
// ✅ Good
export default function removeWhitespace() {
return this.replace(/\s+/g, '');
}
// ❌ Bad
export default function rw() {
return this.replace(/\s+/g, '');
}3. Document Your Functions
Add JSDoc comments for better IDE support:
/**
* Truncate a string to a specified length
* @param {number} length - Maximum length
* @param {string} suffix - Suffix to add (default: '...')
* @returns {string} The truncated string
*/
export default function truncate(length, suffix = '...') {
if (this.length <= length) return this.toString();
return this.substring(0, length) + suffix;
}4. Organize by Prototype
Keep related utilities together:
utils/
├── array/ # Array.prototype extensions
├── string/ # String.prototype extensions
├── number/ # Number.prototype extensions
├── object/ # Object.prototype extensions
└── date/ # Date.prototype extensions🧪 Testing Your Utilities
Since utilities are pure functions, they're easy to test:
// utils/array/sum.test.js
import sum from './sum.js';
describe('Array.sum', () => {
it('should sum array elements', () => {
const arr = [1, 2, 3, 4, 5];
expect(sum.call(arr)).toBe(15);
});
it('should return 0 for empty array', () => {
const arr = [];
expect(sum.call(arr)).toBe(0);
});
});⚠️ Important Considerations
Prototype Pollution
Extending native prototypes can be controversial. Consider these points:
- ✅ Use in applications where you control the entire codebase
- ✅ Great for internal tools and company-wide utilities
- ⚠️ Be cautious in libraries that others will consume
- ⚠️ Avoid name conflicts with existing or future native methods
Performance
- Extensions are injected at build time, not runtime
- Zero overhead compared to importing utilities
- Functions are not tree-shakeable (all are included in bundle)
TypeScript Support
For TypeScript projects, you'll need to declare the extended prototypes:
// types/global.d.ts
interface Array<T> {
sum(): number;
average(): number;
unique(): T[];
}
interface String {
capitalize(): string;
truncate(length: number, suffix?: string): string;
}
interface Number {
square(): number;
clamp(min: number, max: number): number;
}🔧 Advanced Usage
Filtering Utilities
Include or exclude specific utilities:
protoGlobalPlugin({
utilsDir: './utils',
include: ['sum', 'average'], // Only include these
exclude: ['deprecated'], // Exclude these
});Multiple Prototype Types
The plugin supports extending any JavaScript prototype:
// utils/date/addDays.js
export default function addDays(days) {
const result = new Date(this);
result.setDate(result.getDate() + days);
return result;
}
// Usage
const tomorrow = new Date().addDays(1);Combining Manual and Auto-Import
You can't mix both in a single plugin instance, but you can use multiple instances:
export default defineConfig({
plugins: [
// Auto-import from utils
protoGlobalPlugin({
utilsDir: './utils',
}),
// Manual critical extensions
protoGlobalPlugin([
{
className: 'Array',
methods: {
customMethod: function () {
/* ... */
},
},
},
]),
],
});📊 Examples
Check out the demo folder for a complete working example with:
- ✅ Array utilities (sum, average, unique, reverseNumbers)
- ✅ String utilities (capitalize, reverse, truncate)
- ✅ Number utilities (square, isEven, clamp)
- ✅ Live demo page with tests
Run the demo:
cd demo
yarn install
yarn dev🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
Apache License 2.0 - see LICENSE file for details.
🙏 Support
If you find this plugin helpful:
- ⭐ Star the repository
- 🐛 Report bugs via GitHub Issues
- 💡 Suggest features
- 📖 Improve documentation
🔗 Links
Made with ❤️ by Vitaly Kuprin
