As of Shakapacker v9 (and continuing in v10), all peer dependencies are marked as optional via peerDependenciesMeta. This design provides maximum flexibility while maintaining clear version constraints.
- No Installation Warnings - Package managers (npm, yarn, pnpm) won't warn about missing peer dependencies
- Install Only What You Need - Users only install packages for their chosen configuration
- Clear Version Constraints - When packages are installed, version compatibility is still enforced
- Smaller Node Modules - Reduced disk usage by not installing unnecessary packages
{
"dependencies": {
"js-yaml": "^4.1.0",
"path-complete-extname": "^1.0.0",
"webpack-merge": "^5.8.0" // Direct dependency - always available
},
"peerDependencies": {
"webpack": "^5.101.0",
"@rspack/core": "^1.0.0 || ^2.0.0-0"
// ... all build tools
},
"peerDependenciesMeta": {
"webpack": { "optional": true },
"@rspack/core": { "optional": true }
// ... all marked as optional
}
}To prevent runtime errors when optional packages aren't installed, all webpack imports use type-only syntax:
// @ts-ignore: webpack is an optional peer dependency (using type-only import)
import type { Configuration } from "webpack"Type-only imports are erased during compilation and don't trigger module resolution at runtime.
{
"dependencies": {
"shakapacker": "^10.0.0",
"webpack": "^5.101.0",
"webpack-cli": "^6.0.0",
"babel-loader": "^8.2.4",
"@babel/core": "^7.17.9",
"@babel/preset-env": "^7.16.11"
}
}{
"dependencies": {
"shakapacker": "^10.0.0",
"webpack": "^5.101.0",
"webpack-cli": "^6.0.0",
"@swc/core": "^1.3.0",
"swc-loader": "^0.2.0"
}
}Note:
webpack-cliv7 is also supported but requires Node.js >= 20.9.0. If your project meets that requirement, you can use"webpack-cli": "^7.0.0"instead.
{
"dependencies": {
"shakapacker": "^10.0.0",
"@rspack/core": "^2.0.0-0",
"@rspack/cli": "^2.0.0-0",
"rspack-manifest-plugin": "^5.0.0"
}
}If upgrading from Shakapacker v8:
- No action required - Your existing dependencies will continue to work
- No more warnings - Peer dependency warnings will disappear after upgrading
- Option to optimize - You can now remove unused dependencies (e.g., remove Babel if using SWC)
The installer (bundle exec rake shakapacker:install) only adds packages needed for your configuration:
- Detects your preferred bundler (webpack/rspack)
- Installs appropriate JavaScript transpiler (babel/swc/esbuild)
- Adds only required dependencies
Version ranges are carefully chosen for compatibility:
- Broader ranges for peer deps - Allows flexibility (e.g.,
^5.101.0for webpack) - Specific versions in devDeps - Ensures testing against known versions
- Forward compatibility - Ranges include future minor versions (e.g.,
^5.0.0 || ^6.0.0)
Test that no warnings appear during installation:
# Test script available at test/peer-dependencies.sh
./test/peer-dependencies.shVerify Shakapacker loads without optional dependencies:
// This works even without webpack installed (when using rspack)
const shakapacker = require("shakapacker")The test suite includes:
spec/shakapacker/optional_dependencies_spec.rb- Package.json structure validationspec/shakapacker/doctor_optional_peer_spec.rb- Doctor command validationtest/peer-dependencies.sh- Installation warning tests
- Ensure you're using Shakapacker v9.0.0 or later
- Clear your package manager cache:
- npm:
npm cache clean --force - yarn:
yarn cache clean - pnpm:
pnpm store prune
- npm:
- Reinstall dependencies
- Check you've installed required dependencies for your configuration
- Refer to the configuration examples above
- Run
bundle exec rake shakapacker:doctorfor diagnostics
The @ts-ignore comments are intentional and necessary for optional dependencies.
They prevent TypeScript errors when optional packages aren't installed.
When adding new dependencies:
- Add to
peerDependencieswith appropriate version range - Mark as optional in
peerDependenciesMeta - Use type-only imports in TypeScript:
import type { ... } - Test with all package managers (npm, yarn, pnpm)
- Update this documentation if needed
This approach balances several concerns:
- User Experience - No confusing warnings during installation
- Flexibility - Support multiple configurations without forcing unnecessary installs
- Compatibility - Maintain version constraints for safety
- Performance - Reduce installation time and disk usage
- Type Safety - TypeScript support without runtime dependencies
Potential enhancements for future versions:
- Conditional exports - Use package.json exports field for better tree-shaking
- Dynamic imports - Load bundler-specific code only when needed
- Doctor updates - Enhance doctor command to better understand optional dependencies
- Automated testing - Add CI jobs testing each configuration combination