next.js将客户端的静态文件(.js,.css)放在s3

设置next.config.js, 生产环境设置assetPrefix 为s3连接

const isDev = process.env.NODE_ENV !== 'production';
const version = require('./package.json').version;

assetPrefix: isDev ? '' : `https://${process.env.AWS_REGION}.amazonaws.com/${process.env.AWS_S3_BUCKET_NAME}/${version}`

upload.js

// 当使用的CI/Pipeline(例如: jenkins) 构建完成之后,运行这个脚本。
// 它会去读已经构建好的静态文件目录,并且上传到s3
// 每个部署都是immutable的。每次部署时,缓存都会失效。.

require('dotenv').config();
const fs = require('fs');
const readDir = require('recursive-readdir');
const path = require('path');
const AWS = require('aws-sdk');
const mime = require('mime-types');
const version = require('./package.json').version;

AWS.config.update({
  region: process.env.AWS_S3_REGION,
  accessKeyId: process.env.AWS_S3_ACCESS_KEY,
  secretAccessKey: process.env.AWS_S3_SECRET_KEY,
  maxRetries: 3
});

// Retrive all the files path in the build directory
const getDirectoryFilesRecursive = (dir, ignores = []) => {
  return new Promise((resolve, reject) => {
    readDir(dir, ignores, (err, files) => (err ? reject(err) : resolve(files)));
  });
};

// key看起来会像这样: _next/public/<buildid>/pages/index.js
// <buildid> 是每次nextJS 部署时生成的unique id
// 参考: [https://nextjs.org/blog/next-7/#static-cdn-support](https://nextjs.org/blog/next-7/#static-cdn-support)
const generateFileKey = (fileName, toReplace, replaced) => {
  const S3objectPath = fileName.split(toReplace)[1];
  return version + replaced + S3objectPath;
};

const s3 = new AWS.S3();

const uploadToS3 = async (fileArray, toReplace, replaced) => {
  try {
    fileArray.map(file => {
      // 配置s3对象参数
      const S3params = {
        Bucket: process.env.AWS_S3_BUCKET_NAME,
        Body: fs.createReadStream(file),
        Key: generateFileKey(file, toReplace, replaced),
        ACL: 'public-read',
        ContentType: String(mime.lookup(file)),
        ContentEncoding: 'utf-8',
        CacheControl: 'immutable,max-age=31536000,public'
      };

      s3.upload(S3params, function(err, data) {
        if (err) {
          // 设置退出代码
          console.error(err);
          process.exitCode = 1;
        } else {
          console.log(`Assets uploaded to S3:`, data.key);
        }
      });
    });
  } catch (error) {
    console.error(error);
  }
};

//递归获取文件
const start = async function(dict) {
  for (var i = 0; i < dict.length; i++) {
    const files = await getDirectoryFilesRecursive(path.resolve(__dirname, dict[i].filePath), ['.DS_Store', 'BUILD_ID']);
    uploadToS3(files, dict[i].toReplace, dict[i].replaced);
  }
}

// 调用 start 方法
start([
  {
    filePath: '.next',
    toReplace: '.next/',
    replaced: '/_next/'
  }
]);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值