const { Client } = require('ssh2'); const fs = require('fs'); const path = require('path'); const conn = new Client(); const localStaticDir = path.join(__dirname, 'dist', 'build', 'h5', 'static'); const remoteStaticDir = '/www/huishou/dist/build/h5/static'; function uploadDir(sftp, localDir, remoteDir, callback) { fs.readdir(localDir, { withFileTypes: true }, (err, entries) => { if (err) { callback(err); return; } let done = 0; let hasErr = false; if (entries.length === 0) { callback(null); return; } entries.forEach(entry => { const localPath = path.join(localDir, entry.name); const remotePath = remoteDir + '/' + entry.name; if (entry.isDirectory()) { sftp.mkdir(remotePath, { recursive: true }, (mkdirErr) => { if (mkdirErr && mkdirErr.code !== 4) { console.log('mkdir err:', mkdirErr); } uploadDir(sftp, localPath, remotePath, (dirErr) => { if (dirErr) { hasErr = true; callback(dirErr); } done++; if (done === entries.length && !hasErr) callback(null); }); }); } else { fs.readFile(localPath, (readErr, content) => { if (readErr) { console.log('read err:', readErr); hasErr = true; callback(readErr); return; } const ws = sftp.createWriteStream(remotePath); ws.on('close', () => { console.log('uploaded:', remotePath); done++; if (done === entries.length && !hasErr) callback(null); }); ws.on('error', (e) => { console.log('write err:', e); hasErr = true; callback(e); }); ws.end(content); }); } }); }); } conn.on('ready', () => { console.log('=== 上传static目录 ==='); conn.sftp((err, sftp) => { if (err) { console.log('SFTP err:', err); conn.end(); return; } uploadDir(sftp, localStaticDir, remoteStaticDir, (err2) => { if (err2) { console.log('上传失败:', err2); } else { console.log('\n=== 验证 ==='); conn.exec('ls -la /www/huishou/dist/build/h5/static/icons/', (err3, stream) => { if (err3) { console.log('验证失败:', err3); } else { stream.on('data', (d) => console.log(d.toString())); } stream.on('close', () => { conn.exec('curl -s -I https://hs.yifenbao.cn/static/icons/home.png', (err4, stream2) => { if (err4) { console.log('测试失败:', err4); } else { stream2.on('data', (d2) => console.log('\n测试:\n', d2.toString())); } stream2.on('close', () => { sftp.end(); conn.end(); }); }); }); }); } }); }); }); conn.connect({ host: 'hs.yifenbao.cn', port: 22, username: 'root', password: 'Torch1112' });