如何使用Gulp从SFTP下载文件?gulp-sftp仅支持上传
Hey there! I totally get the frustration—gulp-sftp is great for pushing files up to your server, but it doesn’t handle downloads out of the box. Let’s cover two reliable ways to add SFTP download functionality to your Gulp workflow.
Option 1: Use a Dedicated Download Plugin (gulp-sftp-download)
If you want a straightforward, plugin-based solution, gulp-sftp-download is built specifically for this use case. It works similarly to gulp-sftp but focuses on pulling files down.
Step 1: Install the Plugin
First, add it to your dev dependencies:
npm install gulp-sftp-download --save-dev
Step 2: Create a Gulp Task
Add this to your gulpfile.js (adjust the config values to match your SFTP server):
const gulp = require('gulp'); const sftpDownload = require('gulp-sftp-download'); gulp.task('sftp-download', () => { return gulp.src('*') // Placeholder; the plugin uses remote paths instead .pipe(sftpDownload({ host: 'your-sftp-server.com', user: 'your-username', pass: 'your-password', // Or use privateKey for key-based auth remotePath: '/path/to/remote/files/', // Folder or file path on the server localPath: './local-destination-folder/', // Where to save files locally // Optional: Filter files (e.g., only .js files) filter: (file) => file.name.endsWith('.js') })); });
Quick Notes:
- For key-based authentication, replace
passwithprivateKey: require('fs').readFileSync('/path/to/your/private-key.pem') - The
gulp.src('*')is just a placeholder—this plugin doesn’t rely on local source files like typical Gulp tasks
Option 2: Build a Custom Task with ssh2 (More Flexible)
If you need more control (like handling complex directory structures, conditional downloads, or custom error handling), use the ssh2 library directly. It’s the underlying library many SFTP plugins use, so you can build exactly what you need.
Step 1: Install Dependencies
You’ll need ssh2 and vinyl-fs (to integrate with Gulp’s stream system):
npm install ssh2 vinyl-fs --save-dev
Step 2: Write a Custom Download Task
Here’s an example that downloads a single file, plus a snippet for recursive directory downloads:
const gulp = require('gulp'); const Client = require('ssh2').Client; const vfs = require('vinyl-fs'); const path = require('path'); // Download a single file gulp.task('sftp-download-single', (done) => { const conn = new Client(); const remoteFilePath = '/remote/path/to/file.css'; const localSavePath = path.join(__dirname, './src/styles/file.css'); conn.on('ready', () => { conn.sftp((err, sftp) => { if (err) { console.error('SFTP connection error:', err); conn.end(); done(err); return; } sftp.get(remoteFilePath, (err, stream) => { if (err) { console.error('File download error:', err); conn.end(); done(err); return; } // Pipe the stream to a local file stream.pipe(vfs.dest(path.dirname(localSavePath))) .on('finish', () => { console.log(`Successfully downloaded ${remoteFilePath} to ${localSavePath}`); conn.end(); done(); }); }); }); }).connect({ host: 'your-sftp-server.com', port: 22, username: 'your-username', privateKey: require('fs').readFileSync('/path/to/private-key.pem') // Or password: 'your-password' }); }); // Bonus: Recursive directory download (simplified example) function downloadRemoteDir(sftp, remoteDir, localDir) { sftp.readdir(remoteDir, (err, items) => { if (err) throw err; items.forEach(item => { const remotePath = `${remoteDir}/${item.filename}`; const localPath = path.join(localDir, item.filename); if (item.attrs.isDirectory()) { // Create local directory if it doesn't exist require('fs').mkdirSync(localPath, { recursive: true }); downloadRemoteDir(sftp, remotePath, localPath); } else { sftp.get(remotePath).pipe(vfs.dest(localDir)); } }); }); } // Use the recursive function in a Gulp task gulp.task('sftp-download-dir', (done) => { const conn = new Client(); conn.on('ready', () => { conn.sftp((err, sftp) => { if (err) { console.error('SFTP connection error:', err); conn.end(); done(err); return; } downloadRemoteDir(sftp, '/remote/directory', './local/directory'); console.log('Recursive download started'); conn.end(); done(); }); }).connect({ /* Your SFTP config here */ }); });
Quick Notes:
- This approach gives you full control over error handling, file filtering, and directory structure
- For Gulp 4+, you might want to use
exports.sftpDownload = () => { ... }instead ofgulp.task()for newer syntax
Final Pro Tips
- Always test with a small file first to ensure your SFTP credentials and paths are correct
- For production, avoid hardcoding credentials—use environment variables or a config file that’s excluded from version control
内容的提问来源于stack exchange,提问作者josias

