基于webpack或者rollup打包后的map文件的上传以及删除

发布时间:2024年01月16日

????????之前公司要求对于前端项目打包后的map文件需要提取出来,上传到oss服务器,并且不能将map文件暴露在生产环境。

????????公司项目众多,有基于webpack的各种版本构建的项目,也有vite生成的项目,所以就要求我写的打包plugin能尽可能的适配各个前端项目。

????????在历尽千辛万苦之后,终于初步实现了基于webapck各个版本的plugin,以及基于rollup版本的插件。

基于webpack的plugin。

  1. 首先需要校验参数格式以及必传项目。我的项目里面是要求object格式,以及三个参数的入参。
    // 校验参数格式
    if (Object.prototype.toString.call(options) !== "[object Object]") {
      throw new Error(`配置信息应该是Object`);
    }
    this.params = Object.assign(
      {
        sourceFileNames: []
      },
      options
    );
    // 校验必传参数
    if (
      ["projectCode", "serviceCode", "environment"].some(
        key => !options[key]
      )
    ) {
      throw new Error(
        `请填写正确的projectCode、serviceCode和environment`
      );
    }
  }
????????2.其次筛选打包后文件中的map文件
 // 校验打包后的文件中的map文件
  checkSuffix(fileName, suf) {
    var fileNameRegex = new RegExp(
      "\\" + ".(" + suf.split(",").join("|") + ")$"
    );
    if (fileNameRegex.test(fileName.toLowerCase())) {
      return true;
    } else {
      return false;
    }
  }
????????3.接下来上传map文件至oss(需要校验webpack打包时是否开启source-map配置)
  //   上传map文件
  upload(compilation, callback) {
    this.assets = compilation.assets;
    const keys = Object.keys(this.assets);
    this.fileName = keys.filter(item => this.checkSuffix(item, "map"));
    if (this.fileName && this.fileName.length !== 0) {
      this.createClient();
    } else {
      log(colors.red(`请检查是否开启webpack打包source-map配置`));
    }
    if (typeof callback === "function") {
      callback();
    }
  }

  //  创建oss请求
  async createClient() {
    this.getOssConfig()
      .then(res => {
        if (+res.code !== 200) {
          return log(colors.red(res.message));
        }
        this.fullFileNames = res.data.fullFileNames;
        const ossConfig = {
          // yourRegion填写Bucket所在地域。以华东1(杭州)为例,yourRegion填写为oss-cn-hangzhou。
          region: res.data.f2eRegion,
          accessKeyId: res.data.accessKey,
          accessKeySecret: res.data.accessSecret,
          stsToken: res.data.securityToken,
          // 填写Bucket名称。
          bucket: res.data.bucket
        };
        this.client = new OSS({
          ...ossConfig,
          // 刷新临时访问凭证。
          refreshSTSToken: async () => {
            const refreshToken = await _this.getOssConfig();
            return {
              accessKeyId: refreshToken.accessKey,
              accessKeySecret: refreshToken.accessSecret,
              stsToken: refreshToken.securityToken
            };
          }
        });
        this.uploadOss();
      })
      .catch(e => log(colors.red(e)));
  }
  // 将map文件上传到oss
  async uploadOss() {
    await this.fullFileNames.forEach(async (item, index) => {
      const name = this.params.sourceFileNames[index];
      try {
        const result = await this.client.put(
          item,
          Buffer.from(this.assets[name].source(), "utf8")
        );
        if (+result.res.statusCode === 200) {
          log(colors.green(`${name}上传成功!`));
        } else {
          log(colors.red(`${name}上传失败!`));
        }
      } catch (error) {
        console.log(error, "OSS上传错误");
        log(colors.red(`${name}上传失败!`));
      }
      this.deleteMap(name);
    });
  }
????????4.最后删除打包资源中的map文件
  //   删除map文件
  deleteMap(name) {
    const outPath = path.resolve(this.output, name);
    fs.unlink(outPath, function(error) {
      log(colors.green(`${name}删除成功!`));
      if (error) {
        log(colors.red(`${name}删除失败!`));
        return false;
      }
    });
  }

????????至此,webpack的插件就结束了。

基于rollup打包的plugin

步骤跟webpack的差不太多,唯一有区别的就是获取map文件的方式以及构建plugin的方式。

? ? ? ? 1.获取map文件的方式
// 读取根文件夹下的所有文件和子文件夹,获取map文件
const readFolder = async (folderPath, fileCallback) => {
  const fileType = ".map";
  const files = fs.readdirSync(folderPath);
  files.forEach(async file => {
    const filePath = path.join(folderPath, file);
    const isDirectory = fs.lstatSync(filePath);
    if (isDirectory.isDirectory()) {
      readFolder(filePath, fileCallback);
    } else {
      // 过滤指定类型的文件
      if (path.extname(file) === fileType) {
        fileCallback(file, filePath);
      }
    }
  });
};

// 处理每个指定类型文件的回调函数
const fileCallback = (file, filePath) => {
  fileName.push(file);
  fileNamePath.push(filePath);
  // console.log("fileCallback");
};
? ? ? ? 2.构建plugin
function RollupOSSPlugin(userOptions = {}) {
  // 校验参数格式
  if (Object.prototype.toString.call(userOptions) !== "[object Object]") {
    throw new Error(`配置信息应该是Object`);
  }
  params = Object.assign(
    {
      sourceFileNames: []
    },
    userOptions
  );
  // 校验必传参数
  if (
    ["projectCode", "serviceCode", "environment"].some(
      key => !userOptions[key]
    )
  ) {
    throw new Error(`请填写正确的projectCode、serviceCode和environment`);
  }
  return {
    name: "RollupOSSPlugin",
    async writeBundle(options, bundle) {
      output = options.dir || path.dirname(options.file || "");
      if (options.sourcemap) {
        createClient();
      } else {
        // 校验是否开启map打包
        log(colors.red(`请检查是否开启vite.config.js打包source-map配置`));
      }
    }
  };
}

exports.RollupOSSPlugin = RollupOSSPlugin;

其他步骤跟webpack的几乎相同。

最后附上项目的源码https://github.com/wntree/ossPlugin

文章来源:https://blog.csdn.net/qq_51156678/article/details/135603934
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。