alicloud 의 oss (object storage service) 에 directory나 file을 upload 하려고 한다. 매번 수동으로 올릴 수는 없으니 ali-oss sdk
를 사용해서 명령어로 바로 배포할 수 있게 코드를 작성하였다.
물론 https://github.com/liuzhumin/ali-oss-deploy 을 보고 사용하긴했지만 현재 팀에서 사용하고 있는 node 20에서는 에러가 나는 부분이 있어서 수정하였다.
그리고 기존거는 dir 하나만 업로드 가능했는데, 여러 경로를 한번에 업로드 할 수 있게 조금 수정했다.
const fs = require('fs');
const OSS = require('ali-oss');
const refreshCache = require('./refreshCache.cjs');
module.exports = async function (config) {
const mode = process.argv[process.argv.length - 1];
const currentBucket = config.bucket[mode];
config.ossConfig.bucket = currentBucket.name;
const client = new OSS(config.ossConfig);
const files = [];
function readDirSync(dirPath) {
const pa = fs.readdirSync(dirPath);
pa.forEach((e) => {
const cur_path = `${dirPath}/${e}`;
const info = fs.statSync(cur_path);
if (info.isDirectory()) {
readDirSync(cur_path);
} else {
files.push(cur_path);
}
});
}
config.paths.forEach((item) => {
const currentPath = `${config.rootPath}${item.path}`;
if (item.isFile) {
files.push(currentPath);
return;
}
readDirSync(currentPath);
});
const uploadFile = async (file) => {
const projectRootPath = currentBucket.projectPath
? currentBucket.projectPath
: '';
const result = await client.put(
file.replace(config.rootPath, projectRootPath),
file,
);
console.log(result);
}
for(let i = 0; i < files.length; i++) {
const file = files[i];
await uploadFile(file);
}
if (currentBucket.refreshPath) {
refreshCache(
{
accessKeyId: config.ossConfig.accessKeyId,
secretAccessKey: config.ossConfig.accessKeySecret,
},
currentBucket.refreshPath,
);
}
}
refreshCache 는 원래 코드 그대로 사용하였다. co
와 generator로 돼있던 코드는, async await
으로 대체할 수 있기 때문에 변경하였고, path도 상위 directory하나만 넣을 수 있었는데, manifest.json
파일도 올려야했기에 여러가지 file or folder path를 넣을 수 있도록 변경하였다.
for 문 uploadFile 부분은 Promise all로 최적화 할 수 있을거 같지만, 호출이 제한이 1초에 1000번 정도로 있고, (그렇게 많은 파일을 올릴 일이 없을거 같긴하지만..) 충분히 빨랐기에 크게 필요없다는 생각이 들었다. 배포도 원할 때 한번씩만 누르면 되기 때문이다. (현재 배포 파일 10개 이하)
const path = require('path');
const deploy = require('./deploy.cjs');
const rootPath = path.resolve(__dirname, '../')
deploy({
rootPath,
paths: [
{
path: '/dist',
isFile: false,
},
{
path: '/manifest.json',
isFile: true,
}
],
ossConfig: {
region: 'regieon',
accessKeyId: 'acccessKey',
accessKeySecret: 'secret',
},
bucket: {
prod: {
name: 'bucket',
projectPath: 'projectPath',
},
dev: {
name: 'bucket',
projectPath: 'projectPath',
},
},
});