@kpsoftec/vite-copy-plugin
v1.0.3
Published
A Vite plugin to copy files with optional transformation and wildcard support
Downloads
260
Maintainers
Readme
@kpsoftec/vite-copy-plugin
A Vite plugin to copy files with optional transformation and wildcard support, similar to copy-webpack-plugin.
Features
- ✅ Copy files with wildcard patterns
- ✅ Transform file content during copy
- ✅ Development server support with live serving
- ✅ Production build integration
- ✅ Multiple wildcard types:
*,?,[abc],[a-z] - ✅ TypeScript support with type definitions
- ✅ Robust error handling for undefined URLs
- ✅ Force file watching in development mode
Installation
npm install @kpsoftec/vite-copy-pluginBasic Usage
import { defineConfig } from 'vite'
import { copyPlugin } from '@kpsoftec/vite-copy-plugin'
export default defineConfig(({ mode }) => ({
plugins: [
copyPlugin([
{
from: 'src/configs/app-config.json',
to: 'configs/app-config.json',
transform: (content) => {
if (mode === 'production') return content
const config = JSON.parse(content)
return JSON.stringify({
...config,
apiUrl: config.apiUrl.replace('prod', 'dev')
}, null, 2)
}
}
])
]
}))TypeScript Support
The plugin includes TypeScript definitions out of the box:
import { copyPlugin, CopyPattern } from '@kpsoftec/vite-copy-plugin'
const patterns: CopyPattern[] = [
{
from: 'src/config.json',
to: 'config.json',
transform: (content: string) => content.toUpperCase()
}
]
export default defineConfig({
plugins: [copyPlugin(patterns)]
})Error Handling
Version 1.0.1+ includes improved error handling:
- Handles undefined request URLs gracefully
- No more "Cannot read properties of undefined" errors
- Robust middleware implementation
Wildcard Patterns
Supported Wildcards
*- Matches any characters (zero or more)?- Matches single character[abc]- Matches any character in brackets[a-z]- Matches character range
Examples
import { copyPlugin } from '@kpsoftec/vite-copy-plugin'
copyPlugin([
// Copy single file
{
from: 'src/configs/app-config.json',
to: 'configs/app-config.json'
},
// Copy all JSON files ending with -config
{
from: 'src/configs/*-config.json',
to: 'configs/' // trailing slash = directory
},
// Copy all JSON files
{
from: 'src/configs/*.json',
to: 'configs/'
},
// Copy files with single character variation
{
from: 'src/data/file?.json', // file1.json, fileA.json
to: 'data/'
},
// Copy files matching character set
{
from: 'src/env/[123]-config.json', // 1-config.json, 2-config.json, 3-config.json
to: 'env/'
},
// Copy files matching character range
{
from: 'src/assets/[a-c]*.png', // a-logo.png, b-icon.png, c-banner.png
to: 'assets/'
}
])Force Property
Use the force property to enable file watching in development mode for real-time updates:
copyPlugin([
{
from: 'src/config.json',
to: 'config.json',
force: true, // Enable file watching
transform: (content) => {
const config = JSON.parse(content)
return JSON.stringify({ ...config, timestamp: Date.now() }, null, 2)
}
}
])When to use force: true:
- Files that change frequently during development
- Configuration files that need live updates
- Files with dynamic content that should reflect immediately
Performance note: Only enable force for files that actually need watching to avoid unnecessary file system overhead.
Transform Function
{
from: 'src/config.json',
to: 'config.json',
transform: (content) => {
// Access to mode via closure or environment
if (process.env.NODE_ENV === 'production') {
return content // No transformation in production
}
// Transform for development
const config = JSON.parse(content)
return JSON.stringify({
...config,
debug: true,
apiUrl: 'http://localhost:3000'
}, null, 2)
}
}Output Paths
// Specific filename
{ from: 'src/file.json', to: 'output.json' }
// Directory (keeps original filenames)
{ from: 'src/*.json', to: 'configs/' }
// Nested directory
{ from: 'src/data/*.json', to: 'api/data/' }Development vs Production
- Development: Files are served dynamically via middleware
- Production: Files are copied to
distfolder during build - Transform: Applied in both modes (use mode check to skip in production)
Real-world Example
import { copyPlugin } from '@kpsoftec/vite-copy-plugin'
export default defineConfig(({ mode }) => ({
plugins: [
copyPlugin([
// Main app config with environment-specific transforms
{
from: 'src/configs/app-config.json',
to: 'configs/app-config.json',
transform: (content) => {
if (mode === 'production') return content
const config = JSON.parse(content)
return JSON.stringify({
...config,
clientId: config.clientId.replace('#client_id#', 'dev-client'),
env: config.env.replace('#client_env#', 'development'),
apiUrl: config.apiUrl.replace('prod-api', 'dev-api')
}, null, 2)
}
},
// Copy all environment-specific configs
{
from: 'src/configs/*-configs.json',
to: 'configs/'
},
// Copy locale files
{
from: 'src/locales/[a-z][a-z].json', // en.json, fr.json, etc.
to: 'locales/'
}
])
]
}))API Reference
copyPlugin(patterns)
- patterns:
Array<Pattern>- Array of copy patterns
Pattern
- from:
string- Source file path (supports wildcards) - to:
string- Destination path (file or directory) - transform:
(content: string) => string- Optional transform function - force:
boolean- Enable file watching in development mode (default: false)
Wildcard Support
| Pattern | Description | Example Matches |
|---------|-------------|----------------|
| *.json | Any JSON file | config.json, data.json |
| *-config.json | Files ending with -config | app-config.json, db-config.json |
| file?.txt | Single character variation | file1.txt, fileA.txt |
| [123].json | Character set | 1.json, 2.json, 3.json |
| [a-z]*.js | Character range + wildcard | a-script.js, b-module.js |
License
MIT
