Package Exports
- @atomfe/oss-uploader
- @atomfe/oss-uploader/package.json
Readme
oss-uploader
đ A powerful OSS uploader for uploading files to Aliyun OSS đ
Simple, Fast, and Reliable - Perfect for your deployment workflow
English | įŽäŊ䏿
⨠Features
- đ Simple - One command to upload files
- đĻ Batch Upload - Support directory recursive upload
- đ Secure - Multiple config file formats, safe credential storage
- đ¯ Flexible - Glob pattern file filtering
- đ Progress - Real-time upload progress and statistics
- đēī¸ Mapping File - Auto-generate local-to-OSS URL mapping
- đ Content Hash - Automatic cache with 8-char content hash
- đ ī¸ Complete - Upload, list, delete, and more operations
- đĒ TypeScript - Written in TypeScript with full type safety
- ⥠Modern - Dual format (ESM/CJS) with latest toolchain
- đ Compatible - Works in both CommonJS and ES Module projects
đĻ Installation
npm install -g @atomfe/oss-uploader
# or
pnpm add -g @atomfe/oss-uploader
# or
yarn global add @atomfe/oss-uploaderđ Quick Start
Option 1: JSON Configuration
# 1. Initialize configuration (JSON)
oss-uploader init
# 2. Edit .ossrc.json with your credentials
{
"region": "YOUR_REGION",
"accessKeyId": "YOUR_ACCESS_KEY_ID",
"accessKeySecret": "YOUR_ACCESS_KEY_SECRET",
"bucket": "YOUR_BUCKET_NAME"
}
# 3. Upload files
oss-uploader upload ./file.txt
oss-uploader upload ./dist -t static/Option 2: JavaScript Configuration (Recommended)
# 1. Initialize JavaScript configuration
oss-uploader init -o oss.config.js
# 2. Set environment variables or edit oss.config.js
export OSS_REGION="oss-cn-hangzhou"
export OSS_ACCESS_KEY_ID="your-access-key-id"
export OSS_ACCESS_KEY_SECRET="your-access-key-secret"
export OSS_BUCKET="your-bucket-name"
# 3. Upload files
oss-uploader upload ./file.txt
oss-uploader upload ./dist -t static/đ Usage
Commands
# Upload file(s) or directory
oss-uploader upload <sources...> [options]
# List files in OSS bucket
oss-uploader list [prefix]
# Delete file from OSS
oss-uploader delete <path>
# Show bucket information
oss-uploader info
# Create sample configuration
oss-uploader init [options]
# Options for init command:
# -o, --output <path> Output path for configuration file (default: .ossrc.json)
# -t, --type <type> Configuration file type: json or jsUpload Options
| Option | Description |
|---|---|
-t, --target <path> |
Target path in OSS bucket |
-c, --config <path> |
Configuration file path |
-r, --recursive |
Upload directory recursively (default: true) |
-o, --overwrite |
Overwrite existing files (default: true) |
-i, --include <patterns...> |
Include file patterns (glob) |
-e, --exclude <patterns...> |
Exclude file patterns (glob) |
-v, --verbose |
Show verbose output |
-m, --mapping [path] |
Generate upload mapping file (default: .oss-uploader-mapping.json) |
--no-mapping |
Do not generate upload mapping file |
-h, --content-hash |
Add content hash to filename (default: true) |
--no-content-hash |
Do not add content hash to filename |
Examples
# Upload single file
oss-uploader upload ./image.png
# Upload multiple files (batch upload)
oss-uploader upload ./file1.js ./file2.css ./image.png
# Upload multiple files to specific directory
oss-uploader upload ./image1.png ./image2.jpg ./logo.svg -t images/2024/
# Upload to specific directory
oss-uploader upload ./image.png -t images/2024/
# Upload directory with patterns
oss-uploader upload ./dist -i "**/*.js" "**/*.css"
# Exclude files
oss-uploader upload ./dist -e "**/*.map" "**/test/**"
# Verbose mode
oss-uploader upload ./dist -v
# Generate custom mapping file
oss-uploader upload ./dist -m ./upload-map.json
# Don't generate mapping file
oss-uploader upload ./dist --no-mapping
# Upload with content hash (default behavior)
oss-uploader upload ./dist
# Result: file.js â file.a1b2c3d4.js
# Upload without content hash
oss-uploader upload ./dist --no-content-hash
# Result: file.js â file.js
# Mix files and directories (batch upload)
oss-uploader upload ./src/file1.js ./src/file2.css ./assetsđ Progress Display
The tool displays real-time progress during uploads with two modes:
Default Mode (Progress Bar)
For batch uploads, a beautiful progress bar is displayed showing:
- â Upload progress percentage
- đ Completed/Total file count
- đ Current file being uploaded
Upload Progress |ââââââââââââââââââââââââââ| 75% | 15/20 Files | src/components/Button.tsxVerbose Mode (-v)
Use -v or --verbose option to see detailed upload information for each file:
oss-uploader upload ./dist -vSample output:
â Uploaded: src/index.js â static/index.js (24.5 KB)
â Uploaded: src/styles.css â static/styles.css (12.3 KB)
...đ Content Hash Feature
By default, the uploader adds an 8-character content hash to filenames (similar to webpack's chunkhash), providing cache-busting capabilities for your assets.
How It Works
The tool generates an MD5 hash from the file content and appends the first 8 characters before the file extension:
Original: app.js
Uploaded: app.a1b2c3d4.js
Original: style.min.css
Uploaded: style.min.e5f6g7h8.cssBenefits
- â Cache Busting - Automatically invalidate browser cache when file content changes
- đ Version Control - Same content always generates the same hash
- đ CDN Friendly - Perfect for CDN cache management
- đĻ Build Pipeline - Works seamlessly with modern build tools
Usage
# Default: Content hash enabled
oss-uploader upload ./dist
# app.js â app.a1b2c3d4.js
# Disable content hash
oss-uploader upload ./dist --no-content-hash
# app.js â app.js
# With programmatic API
import { OSSUploader } from '@atomfe/oss-uploader';
const uploader = new OSSUploader(config);
// With content hash (default)
await uploader.upload({
source: './dist',
target: 'static/',
contentHash: true // default
});
// Without content hash
await uploader.upload({
source: './dist',
target: 'static/',
contentHash: false
});Use Cases
- đ Static Site Deployment - Ensure visitors get the latest version
- đą SPA Applications - Reliable asset updates for single-page apps
- đ§ Microservices - Consistent versioning across services
- đĻ Library Distribution - Track different versions of published assets
đēī¸ Upload Mapping File
After each upload, the tool automatically generates a .oss-uploader-mapping.json file in the current directory with detailed information about all uploaded files:
{
"uploadTime": "2025-10-18T10:30:00.000Z",
"bucket": "my-bucket",
"region": "YOUR_REGION",
"totalFiles": 10,
"totalSize": 1024000,
"files": [
{
"localPath": "/path/to/local/file.js",
"remotePath": "static/file.js",
"url": "https://my-bucket.YOUR_REGION.aliyuncs.com/static/file.js",
"size": 1024,
"uploadTime": "2025-10-18T10:30:00.000Z"
}
]
}Use Cases
- đ Record Keeping - Keep complete records of each upload
- đ Quick Access - Get URLs for all uploaded files
- đ Analytics - Analyze upload statistics
- đ CI/CD Integration - Use mapping info in build pipelines
- đą CDN Configuration - Configure CDN cache rules easily
âī¸ Configuration
The tool supports multiple configuration sources:
Priority Order: Config file first, fallback to Environment variables
Note: If a config file exists, it will be used exclusively. Environment variables are only used when no config file is found.
Configuration Sources
Config Files (searched in order):
.ossrc/.ossrc.json.ossrc.yaml/.ossrc.ymloss.config.js/oss.config.jsonossfield inpackage.json
Environment Variables:
OSS_REGIONOSS_ACCESS_KEY_IDOSS_ACCESS_KEY_SECRETOSS_BUCKETOSS_ENDPOINT(optional)OSS_INTERNAL(optional,true/false)OSS_SECURE(optional,true/false)OSS_TIMEOUT(optional, in milliseconds)
Configuration Fields
| Field | Required | Description |
|---|---|---|
region |
â | OSS region (e.g., oss-cn-hangzhou) |
accessKeyId |
â | AccessKey ID |
accessKeySecret |
â | AccessKey Secret |
bucket |
â | Bucket name |
endpoint |
â | Custom endpoint |
internal |
â | Use internal network |
secure |
â | Use HTTPS (default: true) |
timeout |
â | Timeout in ms (default: 60000) |
Example: .ossrc.json
{
"region": "YOUR_REGION",
"accessKeyId": "YOUR_ACCESS_KEY_ID",
"accessKeySecret": "YOUR_ACCESS_KEY_SECRET",
"bucket": "my-bucket"
}Example: oss.config.js
Generate JavaScript config with oss-uploader init -o oss.config.js
ESM format (with fallback values):
export default {
region: process.env.OSS_REGION || 'YOUR_REGION',
accessKeyId: process.env.OSS_ACCESS_KEY_ID || 'YOUR_ACCESS_KEY_ID',
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET || 'YOUR_ACCESS_KEY_SECRET',
bucket: process.env.OSS_BUCKET || 'YOUR_BUCKET_NAME',
// Optional fields
// endpoint: process.env.OSS_ENDPOINT,
// internal: process.env.OSS_INTERNAL === 'true',
secure: true,
timeout: 60000,
};CommonJS format:
module.exports = {
region: process.env.OSS_REGION || 'YOUR_REGION',
accessKeyId: process.env.OSS_ACCESS_KEY_ID || 'YOUR_ACCESS_KEY_ID',
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET || 'YOUR_ACCESS_KEY_SECRET',
bucket: process.env.OSS_BUCKET || 'YOUR_BUCKET_NAME',
secure: true,
timeout: 60000,
};Example: Using Environment Variables Only
# Set environment variables
export OSS_REGION="YOUR_REGION"
export OSS_ACCESS_KEY_ID="your-access-key-id"
export OSS_ACCESS_KEY_SECRET="your-access-key-secret"
export OSS_BUCKET="my-bucket"
# Optional environment variables
export OSS_SECURE="true"
export OSS_TIMEOUT="60000"
# Now you can use the CLI without a config file
oss-uploader upload ./dist -t static/
# Note: If a config file exists, it will be used instead of environment variablesđ§ Programmatic Usage
ESM (ES Modules)
import { OSSUploader, loadConfig } from 'oss-uploader';
const config = await loadConfig();
const uploader = new OSSUploader(config);
const results = await uploader.upload({
source: './dist',
target: 'static/',
recursive: true,
overwrite: true,
verbose: true,
generateMapping: true,
});
console.log('Upload results:', results);CommonJS
const { OSSUploader, loadConfig } = require('oss-uploader');
(async () => {
const config = await loadConfig();
const uploader = new OSSUploader(config);
const results = await uploader.upload({
source: './dist',
target: 'static/',
recursive: true,
overwrite: true,
verbose: true,
generateMapping: true,
});
console.log('Upload results:', results);
})();đ¯ Use Cases
Frontend Deployment
npm run build
oss-uploader upload ./dist -t static/my-app/CI/CD Integration
# GitHub Actions - Using environment variables (recommended)
- name: Upload to OSS
env:
OSS_REGION: ${{ secrets.OSS_REGION }}
OSS_ACCESS_KEY_ID: ${{ secrets.OSS_ACCESS_KEY_ID }}
OSS_ACCESS_KEY_SECRET: ${{ secrets.OSS_ACCESS_KEY_SECRET }}
OSS_BUCKET: ${{ secrets.OSS_BUCKET }}
run: |
npm install -g @atomfe/oss-uploader
oss-uploader upload ./dist -t static/
# Alternative: Using config file
- name: Upload to OSS
run: |
npm install -g @atomfe/oss-uploader
echo '{"region":"${{ secrets.OSS_REGION }}","accessKeyId":"${{ secrets.OSS_ACCESS_KEY_ID }}","accessKeySecret":"${{ secrets.OSS_ACCESS_KEY_SECRET }}","bucket":"${{ secrets.OSS_BUCKET }}"}' > .ossrc.json
oss-uploader upload ./dist -t static/Package.json Scripts
{
"scripts": {
"deploy": "npm run build && oss-uploader upload ./dist -t static/"
}
}Using Mapping File
// Read mapping file
import mapping from './.oss-uploader-mapping.json' assert { type: 'json' };
// Get all uploaded URLs
const urls = mapping.files.map(f => f.url);
// Update resource references in HTML
const updateHTML = html => {
mapping.files.forEach(file => {
html = html.replace(
new RegExp(file.localPath, 'g'),
file.url
);
});
return html;
};đ Security
- â
Add
.ossrc.jsonto.gitignore - â Use RAM sub-account instead of root account
- â Use environment variables in CI/CD
- â Rotate AccessKey regularly
- â Never hardcode credentials in code
đ¤ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
For bug reports or feature requests, please create an issue.
đ Development
# Install dependencies
pnpm install
# Development mode
pnpm run dev
# Build
pnpm run build
# Test
pnpm run test
pnpm run test:coverage
# Lint & Format
pnpm run lint
pnpm run formatđ Changelog
See CHANGELOG.md for version history.
đ License
MIT Š 2025
đ Core Features
Modern Technology Stack
- â Dual Module Format - Support both ESM and CommonJS
- â TypeScript 5.7 - Full type safety
- â tsup Build - Ultra-fast builds with esbuild
- â Vitest Testing - Modern test framework
- â npm Provenance - Supply chain security
Developer Experience
- đĨ Fast Build - Lightning-fast 0.05s builds
- đ¨ Code Quality - ESLint + Prettier
- đ Test Coverage - Unit tests + coverage reports
- đ Auto Release - Automated version management with Changesets
- đ Complete Docs - Bilingual documentation (EN/CN)
đĄ Tips & Tricks
1. Using Environment Variables
export OSS_ACCESS_KEY_ID="your-key"
export OSS_ACCESS_KEY_SECRET="your-secret"
export OSS_BUCKET="your-bucket"
export OSS_REGION="YOUR_REGION"2. Batch Process Mapping Files
# Merge multiple mapping files
cat .oss-uploader-mapping-*.json | jq -s 'map(.files) | add' > all-uploads.json3. Automated Deployment Script
#!/bin/bash
# deploy.sh
# Build project
npm run build
# Upload to OSS
oss-uploader upload ./dist -t "static/v$(date +%Y%m%d)/" -v
# Read mapping file and send notification
node -e "
const mapping = require('./.oss-uploader-mapping.json');
console.log(\`â
Upload complete! Total \${mapping.totalFiles} files\`);
console.log(\`đĻ Total size: \${(mapping.totalSize / 1024 / 1024).toFixed(2)} MB\`);
"đ Related Links
Made with â¤ī¸ by lorainwings