从Go工具到Vite插件:参考esbuild案例打造前端自动化部署神器

在前端工程化的现在,自动化的构建与部署直接决定了开发效率,常规生产环境有CI/CD流水线,而测试环境使用CI/CD流水线存在一下问题

  1. 因为CI/CD是服务端构建,而服务器的cpu能力相对较弱,打包速度也相对较慢。
  2. 因为测试环境存在频繁的bug发现、代码修改部署上传再到发现,短时间内可能存在高频次代码提交。

因此以上两点问题照旧在测试阶段存在效率问题

因此我使用go开发了一个自动压缩上传的程序

整体思路

程序整体思路并不难,就是使用go对打包后的产物进行代码压缩,然后以sftp上传至服务器,而这只需要在vite构建后自动执行既可,或者webpack构建完成后。

而js与go的交互只需通过node调用spawnapi启动go的进程既可,二者进程互相独立。

开发过程问题详细解

问题一:ESM与CommonJS

在package.json上这俩个个模式只是一行配置

json 复制代码
    {
     "type": "module",//commonjs
    }

默认不填写为commonjs

  1. 二者语法
js 复制代码
//commonjs
const os = require('os')
//esm
import os from 'os'
  1. comonjs 为动态执行,esm为静态执行
  2. Tree‑Shaking优化,由于esm为静态执行,可以支持,但commonjs不支持
  3. commonjs是值拷贝,如果导出是对象,那么a模块修改后b模块并不会动,esm相反

问题二:require.resolve

在将我开发的功能转为npm插件中,阅读esbuild源码当中发现大量使用require.resolve。 常规cjs当中使用require('xx')导入node_modules里面的包 而require.resolve就是解析该包的路径

js 复制代码
console.log(require.resolve('axios)) /xxx/xxx/项目名/node_modules/axios/xxx

后面的会为package.json里面配置的main 这是这个包的入口文件。 在esm当中也有推荐使用 createRequire

js 复制代码
import { createRequire } from "module";
const require = createRequire(import.meta.url);

问题三:关于package当中各种dependencies

在package当中dependencies有很多种,以esbuild当中的dependencies看

json 复制代码
 {
  "optionalDependencies": {
    "@esbuild/aix-ppc64": "0.28.0",
    ...xx
  },
 }

这个optionalDependencies是可安装依赖。

当执行npm i的时候,你下载的依赖内存会有一个package记录他这个包所需要的依赖这个是走dependencies与devDependencies,当报错的时候npm i就会失败。

而optionalDependencies下载失败是不会停止,这就为esbuild配置实现了自动根据用户操作系统与cpu架构自行从npm仓库拉去自己想要的esbuild程序

而go开发的原生二进制程序只需要在package上写入os与cpu俩个属性就能让npm匹配当前用户的操作系统与cpu架构是否符合

json 复制代码
"os": [
    "linux"
  ],
  "cpu": [
    "arm"
  ]
  //限制为linux的arm架构可以安装成功

问题四:关于下载失败的保底机制

在esbuild当中,存在一个如果你npm i执行后esbuild的二进制包没有下载失败的保底程序,就从新下载

js 复制代码
async function checkAndPreparePackage() {

  const { pkg, subpath, isWASM } = pkgAndSubpathForCurrentPlatform(); //获取你电脑的操作系统与架构
  let binPath;
  try {
    binPath = require.resolve(`${pkg}/${subpath}`); 
    //如果npm i下载成功后,node_modules里这一段代码就会解析成功不会报错
  } catch (e) {
  
    binPath = downloadedBinPath(pkg, subpath); 
    //解析失败,准备下载二进制文件,这是获取需要放入的文件地址
    try {
      installUsingNPM(pkg, subpath, binPath);
    } catch (e2) {
      
      try {
        await downloadDirectlyFromNPM(pkg, subpath, binPath); //下载
      } catch (e3) {
        throw new Error(`Failed to install package "${pkg}"`);
      }
    }
  }
}
//检查
checkAndPreparePackage().then(() => {
  if (isToPathJS) {
    validateBinaryVersion(process.execPath, toPath);
  } else {
    validateBinaryVersion(toPath);
  }
});

而想让这个代码在npm i后执行只需要在package.json当中配置

json 复制代码
 "scripts": {
    "postinstall": "node install.js"
  },

以上就是个人目前总结的东西!

也欢迎使用本人用go开发的sftp压缩上传的vite插件

www.npmjs.com/package/vit...

目前没有像esbuild那样存在如果在npm i下载失败的保底机制,正在深入研究

相关推荐
__zRainy__12 小时前
React开始:直接在网站中使用React.js
前端·react.js·前端框架
码林鼠13 小时前
webpack的基本配置
前端·webpack·node.js
yiqiefeimeng13 小时前
Rust还是Go?编程语言的未来之争
rust·go·编程语言·技术社区·未来之争
唐青枫15 小时前
别把 GORM 当 SQL 生成器:Go GORM 从模型映射到事务实战详解
go
小林ixn16 小时前
React Router 从入门到实战:一篇搞定路由配置、懒加载与嵌套路由
前端·react.js·前端框架
FeelTouch Labs16 小时前
Node.js 中的 spawn 和 exec:子进程执行的不同方式对比
node.js·编辑器·vue·vim
妙码生花16 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(五十四):管理员个人资料页面、管理员日志优化
前端·后端·go
会飞的喵17 小时前
我给 AI Agent 做了个 UI 渲染 SDK:基于 Google A2UI 协议,让 Agent 不再只会发文字
前端框架·aigc
先吃饱再说17 小时前
从多页到单页:前端路由的演进与 React Router
前端·react.js·前端框架