手写webpack插件上传前端spa文件到腾讯云cdn
前端spa静态文件上传腾讯云COS,从单点服务器分散到多点cdn,减轻服务器压力,加快加载速度。
1、commonjs格式导出插件webpack-cos-done-plugin,添加到webpack配置plugins
2、插件中提供apply方法,注册DonePlugin事件,当打包完成执行回调函数
class WebpackCosDonePlugin {
//打包完done插件
apply(compiler: any) {
compiler.hooks.done.tap('DonePlugin', () => {
uploadToCosFn(APP_NAME, appVersion, REACT_APP_ENV, 'dist');
});
}
}
3、使用fs.createReadStream读取每个文件流,使用腾讯云cos-nodejs-sdk-v5中的cos.putObject方法上传到cdn
function uploadToCos() {
console.log(`==========> 开始上传静态资源到 CDN`);
dir.files(path.join(process.cwd(), distDir), (err, files) => {
if (err) {
if (err.code === 'ENOENT') {
console.log(`${distDir} 目录不存在`);
} else {
console.log(`dir.files error: ${err}`);
}
process.exit(1);
}
Promise.all(
files.map((filePath) => {
return new Promise((resolve, reject) => {
const readableStream = fs.createReadStream(filePath);
const uploadFilePath = filePath.match(
new RegExp(fileRegExpPattern),
)[1];
const key = `apps/${appName}/${appVersion}/${uploadFilePath}`;
console.log('开始上传:' + key);
cos.putObject(
{
Bucket: cosCfg[appEnv].bucketName,
Region: cosCfg[appEnv].region,
Key: key,
StorageClass: 'STANDARD',
Body: readableStream,
},
(err, data) => {
if (err) {
console.log(
`${key} 上传失败!? statusCode: ${err.statusCode}`,
);
process.exit(1);
}
if (data.statusCode === 200) {
console.log(`==========> ${key} 上传成功~ ??`);
resolve(data);
} else {
console.log(
`${key} 上传失败!? statusCode: ${data.statusCode}`,
);
process.exit(1);
}
},
);
});
}),
).then((result) => {
replaceIndexFile();
});
});
}
4、当全部文件上传完毕,替换index.html文件到原来位置,nginx指向原来index.html文件
function replaceIndexFile() {
console.log(`==========> 开始替换入口文件`);
const indexFileReadableStream = fs.createReadStream(
path.join(process.cwd(), `${distDir}/${indexFile}`),
);
const indexFileKey = `apps/${appName}/latest/${indexFile}`;
console.log('开始上传:' + indexFileKey);
cos.putObject(
{
Bucket: cosCfg[appEnv].bucketName,
Region: cosCfg[appEnv].region,
Key: indexFileKey,
StorageClass: 'STANDARD',
Body: indexFileReadableStream,
},
(err, data) => {
if (err) {
console.log(
`${indexFileKey} 上传失败!? statusCode: ${err.statusCode}`,
);
process.exit(1);
}
if (data.statusCode === 200) {
console.log(`==========> ${indexFileKey} 上传成功~ ??`);
} else {
console.log(
`${indexFileKey} 上传失败!? statusCode: ${data.statusCode}`,
);
process.exit(1);
}
},
);
}