es-guard
Version:
A tool to check JavaScript compatibility with target environments
368 lines (260 loc) • 9.27 kB
Markdown
# ES-Guard
[](https://codecov.io/gh/mkayander/es-guard)
A powerful TypeScript-based tool that ensures your JavaScript code is compatible with target environments using ESLint.
## Features
- 🔍 **ES Version Validation**: Verify your JavaScript code compatibility with specific ES versions (ES2015, ES2016, ES2017, and beyond)
- 🌐 **Browser Support Verification**: Validate browser compatibility using eslint-plugin-compat
- 🎯 **Smart Browser Detection**: Automatically determine browser targets from ES version (optional)
- 📁 **Comprehensive Directory Scanning**: Effortlessly scan directories for JavaScript files
- 🚀 **GitHub Actions Integration**: Seamlessly integrate with GitHub Actions workflows
- 📦 **Flexible Installation**: Install globally or use as a project dependency
## Installation
### Global Installation
```bash
npm install -g es-guard
```
### Local Installation
```bash
npm install --save-dev es-guard
```
### From Source
```bash
git clone https://github.com/mkayander/es-guard.git
cd es-guard
npm install
npm run build
```
## Usage
### Command Line Interface
```bash
# Basic usage with auto-detected browsers
es-guard
# Validate specific directory
es-guard build
# Specify target ES version (year format)
es-guard -t 2020 build
# Specify target ES version (numeric format)
es-guard -t 11 build
# Use latest ES version
es-guard -t latest build
# Specify custom browser targets
es-guard --browsers "> 0.5%, last 2 versions, Firefox ESR, not dead" dist
# Display help information
es-guard --help
# Show version information
es-guard --version
```
### Programmatic Usage
ES-Guard provides a comprehensive programmatic API for integration into your build tools, CI/CD pipelines, or custom scripts.
#### Basic Usage
```typescript
import { checkCompatibility } from "es-guard";
// Basic compatibility check
const result = await checkCompatibility({
dir: "dist",
target: "2020",
});
console.log(`Found ${result.errors.length} errors and ${result.warnings.length} warnings`);
```
#### Auto-detection
```typescript
import { checkCompatibility, detectProjectConfig } from "es-guard";
// Auto-detect project configuration
const config = detectProjectConfig(process.cwd());
if (config.target && config.outputDir) {
const result = await checkCompatibility({
dir: config.outputDir,
target: config.target,
browsers: config.browserslist?.join(", "),
});
}
```
#### CI/CD Pipeline Usage
```typescript
import { checkCompatibility, detectProjectConfig } from "es-guard";
// Running in CI where working directory might be different
const projectRoot = process.env.PROJECT_ROOT || process.cwd();
const buildDir = process.env.BUILD_DIR || "dist";
// Detect configuration from project root
const config = detectProjectConfig(projectRoot);
if (config.target) {
const scanDir = config.outputDir || buildDir;
const fullScanPath = path.isAbsolute(scanDir) ? scanDir : path.join(projectRoot, scanDir);
const result = await checkCompatibility({
dir: fullScanPath,
target: config.target,
browsers: config.browserslist?.join(", "),
});
// In CI, exit with error code if issues found
if (result.errors.length > 0) {
process.exit(1);
}
}
```
#### Advanced Usage
```typescript
import { checkCompatibility, getBrowserTargetsFromString, setVerboseMode, validateConfig } from "es-guard";
// Validate configuration
validateConfig({
dir: "dist",
target: "2020",
});
// Get browser targets for specific ES version
const browsers = getBrowserTargetsFromString("2015");
// Enable verbose mode for detailed output
setVerboseMode(true);
// Run compatibility check
const result = await checkCompatibility({
dir: "dist",
target: "2020",
browsers: "> 1%, last 2 versions, not dead, ie 11",
});
// Process results
result.errors.forEach((violation) => {
console.log(`Error in ${violation.file}:`);
violation.messages.forEach((message) => {
console.log(` Line ${message.line}: ${message.message}`);
});
});
```
#### TypeScript Support
ES-Guard includes full TypeScript support with proper type definitions:
```typescript
import type { CompatibilityResult, Config, Violation } from "es-guard";
const config: Config = {
dir: "dist",
target: "2020",
browsers: "> 1%, last 2 versions, not dead",
};
const result: CompatibilityResult = await checkCompatibility(config);
```
See the [examples](./examples/) directory for more comprehensive usage examples.
### GitHub Actions Integration
```yaml
name: Validate Compatibility
on: [push, pull_request]
jobs:
compatibility:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: "18"
- run: npm install
- run: npm run build
- run: npx es-guard -t 2015 dist
```
## Configuration
### Parameters
| Parameter | Description | Default | Required |
| ---------- | ------------------------------------------ | ------------------------- | -------- |
| `path` | Directory to scan for JavaScript files | `dist` | No |
| `target` | Target ES version | `2015` | Yes |
| `browsers` | Browser targets for compatibility checking | Auto-detected from target | No |
### CLI Options
| Option | Description | Default |
| -------------------------- | ----------------- | ------------- |
| `-t, --target <version>` | Target ES version | Auto-detected |
| `-b, --browsers <targets>` | Browser targets | Auto-detected |
| `-v, --verbose` | Enable verbose output | `false` |
| `--skip` | Continue on compatibility errors | `false` |
| `--no-compat` | Disable compat/compat rule - only report syntax errors | `false` |
### ES Target Versions
The `target` parameter supports multiple formats:
- **Year format**: `2015`, `2016`, `2017`, etc.
- **Numeric format**: `6` (ES2015), `7` (ES2016), `11` (ES2020), etc.
- **Latest**: `latest` for the most recent ES version
### Browser Targets
The `browsers` parameter follows the Browserslist format. When not specified, browsers are automatically determined based on the ES target:
- **ES2015/ES6**: `> 1%, last 2 versions, not dead, ie 11`
- **ES2016-2017/ES7-8**: `> 1%, last 2 versions, not dead, not ie 11`
- **ES2018-2019/ES9-10**: `> 1%, last 2 versions, not dead, not ie 11, not op_mini all`
- **ES2020+/ES11+**: `> 1%, last 2 versions, not dead, not ie 11, not op_mini all, not android < 67`
Custom browser target examples:
- `> 1%, last 2 versions, not dead, ie 11` - Modern browsers with IE11 support
- `> 0.5%, last 2 versions, Firefox ESR, not dead` - Broader browser support
- `defaults` - Default Browserslist targets
- `last 1 version` - Latest version of each browser
## CI/CD Integration
### Test Output in CI
When running tests in CI environments, you may see error messages like:
```
Error: Directory "/path/to/nonexistent-directory" does not exist
Error: Invalid ES target: "invalid"
Warning: Could not lint directory
Error [BrowserslistError]: Unknown browser query
```
**These are NOT test failures!** These are expected outputs from tests that are designed to test error handling scenarios. The tests are actually passing successfully.
### CI Configuration
To properly handle test output in CI, configure your CI system to:
1. **Only fail on test exit codes** (not on stderr output)
2. **Use the JUnit reporter** for structured test results
3. **Check the JUnit XML file** for actual test failures
### Example CI Commands
```bash
# Run tests with JUnit output (recommended for CI)
pnpm run test:junit
# Run tests with coverage and JUnit output
pnpm run test:junit:coverage
# Check test results
cat test-report.junit.xml
```
### GitHub Actions Example
```yaml
- name: Run Tests
run: pnpm run test:junit:coverage
- name: Upload Test Results
uses: actions/upload-artifact@v3
with:
name: test-results
path: test-report.junit.xml
retention-days: 30
```
## Development
### Setup
```bash
npm install
```
### Build
```bash
npm run build
```
### Development Mode
```bash
npm run dev
```
### Testing
```bash
# Run all tests
pnpm run test
# Run tests in watch mode
pnpm run test:dev
# Run a specific test file
pnpm run build && pnpm run test:only src/path/to/test.ts
# Run a specific test by name
pnpm run build && pnpm run test:only -t "test name"
# Run tests without building first (requires previous build)
pnpm run test:only -t "test name"
```
### Linting
```bash
npm run lint
```
## Publishing to NPM
1. Update the version in `package.json`
2. Update the repository URL in `package.json`
3. Build the project: `npm run build`
4. Publish: `npm publish`
## License
MIT License - see [LICENSE](LICENSE) file for details.
## Contributing
1. Fork the repository
2. Create a feature branch
3. Implement your changes
4. Add tests where applicable
5. Run the linter: `npm run lint`
6. Submit a pull request
## Support
- 🐛 [Issues](https://github.com/mkayander/es-guard/issues)
- 💬 [Discussions](https://github.com/mkayander/es-guard/discussions)