chore: consolidate new foundation and archive v1 (#1495)

This commit is contained in:
2026-09-07 12:32:57 -05:00
3511 changed files with 727899 additions and 10 deletions
@@ -0,0 +1,210 @@
# Plugin Structure: Install Method Requirements
## Rule
A Vue plugin must be either an object with an `install()` method, or a function that serves as the install function. The install function receives the app instance and optional user-provided options.
## Why This Matters
1. **API contract**: Vue's `app.use()` expects a specific interface. Incorrect structure causes silent failures or errors.
2. **Options passing**: The install method receives options that users pass to `app.use()`, enabling plugin configuration.
3. **App access**: The install method receives the app instance, providing access to `app.component()`, `app.directive()`, `app.provide()`, etc.
## Plugin Structures
### Object with install method (recommended)
```typescript
// plugins/myPlugin.ts
import type { App } from 'vue';
interface PluginOptions {
prefix?: string;
debug?: boolean;
}
const myPlugin = {
install(app: App, options: PluginOptions = {}) {
const { prefix = 'my', debug = false } = options;
if (debug) {
console.log('Installing myPlugin with prefix:', prefix);
}
app.provide('myPlugin', { prefix });
},
};
export default myPlugin;
// Usage
app.use(myPlugin, { prefix: 'custom', debug: true });
```
### Function as install (alternative)
```typescript
// plugins/simplePlugin.ts
import type { App } from 'vue';
function simplePlugin(app: App, options?: { message: string }) {
app.config.globalProperties.$greet = () => {
return options?.message ?? 'Hello!';
};
}
export default simplePlugin;
// Usage
app.use(simplePlugin, { message: 'Welcome!' });
```
### Factory function pattern (most flexible)
```typescript
// plugins/configuredPlugin.ts
import type { App, Plugin } from 'vue';
interface I18nOptions {
locale: string;
messages: Record<string, Record<string, string>>;
fallbackLocale?: string;
}
export function createI18n(options: I18nOptions): Plugin {
return {
install(app: App) {
// Options are captured in closure - no need to pass through app.use()
const { locale, messages, fallbackLocale = 'en' } = options;
const translate = (key: string): string => {
return messages[locale]?.[key] ?? messages[fallbackLocale]?.[key] ?? key;
};
app.provide('i18n', { translate, locale });
},
};
}
// Usage - options passed to factory, not app.use()
const i18n = createI18n({
locale: 'fr',
messages: {
en: { hello: 'Hello' },
fr: { hello: 'Bonjour' },
},
});
app.use(i18n); // No second argument needed
```
## Common Plugin Capabilities
```typescript
const fullFeaturedPlugin = {
install(app: App, options: PluginOptions) {
// 1. Register global components
app.component('MyButton', MyButtonComponent);
app.component('MyInput', MyInputComponent);
// 2. Register global directives
app.directive('focus', focusDirective);
// 3. Provide injectable values (recommended)
app.provide('pluginConfig', options);
// 4. Add global properties (use sparingly)
app.config.globalProperties.$myHelper = helperFunction;
// 5. Add global mixins (avoid if possible)
app.mixin({
created() {
// Runs for every component
},
});
// 6. Custom error handling
app.config.errorHandler = (err, vm, info) => {
// Handle errors
};
},
};
```
## TypeScript: Plugin Type
Use the `Plugin` type for proper typing:
```typescript
import type { App, Plugin } from 'vue';
// With options type parameter
interface MyOptions {
apiKey: string;
}
const myPlugin: Plugin<[MyOptions]> = {
install(app: App, options: MyOptions) {
// options is typed as MyOptions
},
};
// Without options
const simplePlugin: Plugin = {
install(app: App) {
// No options expected
},
};
```
## Common Mistakes
### Missing install method
```typescript
// BAD - This is just an object, not a plugin
const notAPlugin = {
doSomething() {
/* ... */
},
};
app.use(notAPlugin); // Error or silent failure
// GOOD
const actualPlugin = {
install(app) {
app.provide('service', {
doSomething() {
/* ... */
},
});
},
};
```
### Forgetting to use the app parameter
```typescript
// BAD - Does nothing
const uselessPlugin = {
install(app, options) {
const service = createService(options);
// Forgot to register anything with app!
},
};
// GOOD
const usefulPlugin = {
install(app, options) {
const service = createService(options);
app.provide('service', service); // Actually makes it available
},
};
```
## References
- [Vue.js Plugins Documentation](https://vuejs.org/guide/reusability/plugins.html)
- [Vue.js Application API](https://vuejs.org/api/application.html)