배포 스크립트

{
	"scripts": {
    "build": "react-scripts build",
    "build:staging": "env-cmd -f .env.staging react-scripts build",
    "zip": "node scripts/zip.js",
    "predeploy:staging": "npm run build:staging && npm run zip",
    "deploy:staging": "node scripts/deploy.js",
  },
	"devDependencies": {
    "@loadable/babel-plugin": "^5.11.0",
    "archiver": "^3.1.1",
    "prettier": "^1.19.1",
    "ssh2-promise": "^0.1.6"
  },
}

deploy.js

const SSH2Promise = require('ssh2-promise');
const path = require('path');
const remotePath = '/var/www/101phone_front';
const sshconfig = {
  host: '211.253.25.219',
  username: 'root',
  password: '#Dlfrhddlf72587',
  // identity: '/Users/cmlee/.ssh/LightsailDefaultPrivateKey-ap-northeast-2.pem'
};

const ssh = new SSH2Promise(sshconfig);

(async function(){
  try {
    await ssh.connect();
    const sftp = ssh.sftp();
    console.log('Connection established');

    await sftp.fastPut(path.resolve(__dirname, '../build.zip'), `${remotePath}/build.zip`);

    await ssh.exec(`rm -rf ${remotePath}/build`);
    await ssh.exec(`cd ${remotePath}; unzip -o build.zip`, { pty: true }, (err, stdio) => {
      stdio.on('exit', async () => {
        console.info(`* Complete unziping "build.zip" on the server`);

        await ssh.exec(`rm -rf ${remotePath}/build.zip`);
        console.info('* removed build.zip');
        console.info('* deploy succeeded!');

        ssh.close();
      });
    });

  } catch (e) {
    console.log(e);
  }
})();

zip.js

const fs = require('fs');
const archiver = require('archiver');

const output = fs.createWriteStream('./build.zip');
const archive = archiver('zip', {
  zlib: { level: 9 } // Sets the compression level.
});

output.on('close', function() {
  console.log(archive.pointer() + ' total bytes');
  console.log('archiver has been finalized and the output file descriptor has closed.');
});

output.on('end', function() {
  console.log('Data has been drained');
});

archive.on('warning', function(err) {
  if (err.code === 'ENOENT') {
    // log warning
  } else {
    // throw error
    throw err;
  }
});

// good practice to catch this error explicitly
archive.on('error', function(err) {
  throw err;
});

// pipe archive data to the file
archive.pipe(output);

// append files from a sub-directory, putting its contents at the root of archive
archive.directory('build/', 'build/');
// archive.directory('dist/', 'dist/');

// finalize the archive (ie we are done appending files but streams have to finish yet)
// 'close', 'end' or 'finish' may be fired right after calling this method so register to them beforehand
archive.finalize();