vite-plugin-electron-externals
v0.4.7
Published
Automatically detect and externalize dependencies for Electron apps in Vite
Maintainers
Readme
vite-plugin-electron-externals
Automatically detect and externalize dependencies for Electron apps in Vite, such as:
- Native modules (better-sqlite3, serialport, etc.)
- Electron itself
- Packages with dynamic requires or ESM/CJS incompatibilities
- Node.js built-in modules
Features
Smart Detection
- Auto-detects native modules with compiled bindings
- Recognizes packages with ESM/CJS incompatibilities
- Identifies Electron-specific modules
- Scans for binary files (.node, .dll, .so)
- Checks for native build scripts (node-gyp, prebuild)
Flexible Configuration
- Multiple presets (minimal, recommended, aggressive, safe, debug)
- Configuration file support (.externalrc, package.json)
- Custom rules with regex patterns
- Per-module overrides
Performance
- Built-in caching for fast repeated builds
- Configurable cache TTL
- Efficient file system scanning
Installation
npm install vite-plugin-electron-externals --save-devUsage
With vite-plugin-doubleshot
const { autoExternals } = require('vite-plugin-electron-externals');
const { VitePluginDoubleshot } = require('vite-plugin-doubleshot');
module.exports = defineConfig({
plugins: [
VitePluginDoubleshot({
type: 'electron',
main: 'dist/main/index.js',
entry: 'src/main/index.ts',
external: await autoExternals(), // ✨
}),
],
});As a standalone Vite plugin
const { VitePluginElectronExternals } = require('vite-plugin-electron-externals');
module.exports = defineConfig({
plugins: [
VitePluginElectronExternals(),
],
});Using presets
external: await autoExternals({
preset: 'aggressive' // minimal | recommended | aggressive | safe | debug
})Options
await autoExternals({
// Use a preset
preset: 'recommended', // minimal | recommended | aggressive | safe | debug
// Additional modules to mark as external
include: ['my-weird-module'],
// Modules to force bundle (not external)
exclude: ['some-native-module-i-want-bundled'],
// Custom project root (defaults to process.cwd())
projectRoot: '/path/to/project',
// Detection options
detectNative: true, // Detect native modules
scanNodeModules: true, // Scan node_modules for indicators
checkPostinstall: true, // Check for postinstall scripts
checkBinaryField: true, // Check for .node files
// Custom patterns
patterns: [
/^@mycompany\//, // Externalize scoped packages
],
// Custom rules
rules: [
{
pattern: /native/i,
reason: 'Contains "native" in name',
},
],
// Logging
verbose: false, // Detailed output
logLevel: 'info', // silent | error | warn | info | debug
// Cache
cache: {
enabled: true, // Enable caching
ttl: 1000 * 60 * 60, // Cache TTL (1 hour)
directory: '/custom/cache', // Custom cache directory
},
})Configuration File
Create .externalrc or .externalrc.json:
{
"preset": "recommended",
"include": ["my-custom-module"],
"exclude": ["electron"],
"verbose": true
}Or use .externalrc.js:
module.exports = {
preset: 'aggressive',
patterns: [/^@mycompany\//],
rules: [
{
pattern: /native/i,
reason: 'Package name suggests native code',
},
],
};Or in package.json:
{
"electronExternals": {
"preset": "recommended",
"verbose": true
}
}CLI Tool
Test detection without modifying your config:
# Basic detection
npx vite-plugin-electron-externals
# Verbose output with reasons
npx vite-plugin-electron-externals --verbose
# Use a preset
npx vite-plugin-electron-externals --preset aggressive
# JSON output for CI/CD
npx vite-plugin-electron-externals --json
# List available presets
npx vite-plugin-electron-externals --list-presets
# Clear detection cache
npx vite-plugin-electron-externals --clear-cache
# With custom options
npx vite-plugin-electron-externals \
--verbose \
--include my-module \
--exclude electron \
--project /path/to/projectPresets
minimal
Only externalizes Node.js built-ins and Electron modules. Fastest, but may miss native modules.
recommended (default)
Balanced approach. Detects native modules and known problematic packages.
aggressive
Externalizes everything that could potentially be problematic. Includes extra patterns and rules.
safe
Conservative approach. Only uses known lists, doesn't scan node_modules.
debug
Verbose logging for troubleshooting detection issues.
API Reference
autoExternals(options)
Returns a Promise resolving to an array of module names to externalize.
const externals = await autoExternals({ preset: 'recommended' });
// ['fs', 'path', 'electron', 'better-sqlite3', ...]detectExternals(options)
Returns a Promise resolving to detailed detection results.
const results = await detectExternals({ verbose: true });
// {
// externals: ['fs', 'electron', ...],
// reasons: {
// 'fs': 'Node.js built-in module',
// 'electron': 'Electron-specific module',
// 'better-sqlite3': 'Known native module with compiled bindings'
// },
// timestamp: 1234567890
// }createPreset(name)
Returns the configuration for a preset.
const config = createPreset('aggressive');
// { detectNative: true, scanNodeModules: true, ... }VitePluginElectronExternals(options)
Vite plugin for automatic detection.
export default defineConfig({
plugins: [
VitePluginElectronExternals({
preset: 'recommended',
verbose: true,
}),
],
});Module detection
The plugin uses multiple detection strategies:
1. Node.js Built-ins
Always externalized: fs, path, crypto, http, https, stream, etc.
Includes subpath imports: fs/promises, stream/promises, etc.
2. Electron Modules
electronelectron-updaterelectron-storeelectron-log
3. Native Modules
Detected by:
- Checking for known native packages (better-sqlite3, sqlite3, canvas, sharp, serialport, etc.)
- Scanning
package.jsonforgypfile,binaryfields - Checking for postinstall scripts with node-gyp
- Looking for dependencies on native build tools
- Scanning for
.node,.dll,.sobinary files
4. Problematic Packages
Known packages with bundling issues:
dockerode,sql.js,tar-fsexpress,fastify,koaws,socket.iopuppeteer,playwrightprisma,sequelize,typeorm- And many more...
5. Pattern Matches
Scoped packages often need externalization:
@grpc/*@nestjs/*@tensorflow/*@serialport/*- Custom patterns you define
Examples
Basic Electron + Vue
// vite.config.js
const { defineConfig } = require('vite');
const { autoExternals } = require('vite-plugin-electron-externals');
export default defineConfig({
plugins: [
// ... other plugins
],
build: {
rollupOptions: {
external: await autoExternals(),
},
},
});With Custom Rules
external: await autoExternals({
preset: 'recommended',
// Your company's internal native modules
patterns: [/^@mycompany\/native-/],
// Specific detection rules
rules: [
{
pattern: /binding/i,
reason: 'Likely contains native bindings',
},
],
// Always externalize these
include: ['my-special-module'],
// Force bundle these (override detection)
exclude: ['some-false-positive'],
})Debugging Issues
// Use debug preset to see what's being detected
external: await autoExternals({
preset: 'debug'
})
// Or run the CLI
// npx vite-plugin-electron-externals --verboseCI/CD Integration
# In your CI pipeline, verify externals
npx vite-plugin-electron-externals --json > externals.json
# Parse and validate in your scripts
node scripts/validate-externals.jsTroubleshooting
Module not detected
Run with verbose output:
npx vite-plugin-electron-externals --verboseIf a module isn't detected, add it manually:
external: await autoExternals({
include: ['missing-module'],
})False positives
If a module is incorrectly externalized:
external: await autoExternals({
exclude: ['false-positive-module'],
})Performance issues
Disable expensive scans:
external: await autoExternals({
scanNodeModules: false, // Don't scan node_modules
checkBinaryField: false, // Don't look for .node files
})Or use the safe preset:
external: await autoExternals({ preset: 'safe' })Cache issues
Clear the cache:
npx vite-plugin-electron-externals --clear-cacheOr disable caching:
external: await autoExternals({
cache: { enabled: false },
})License
MIT
