在前端工程化的现在,自动化的构建与部署直接决定了开发效率,常规生产环境有CI/CD流水线,而测试环境使用CI/CD流水线存在一下问题
- 因为CI/CD是服务端构建,而服务器的cpu能力相对较弱,打包速度也相对较慢。
- 因为测试环境存在频繁的bug发现、代码修改部署上传再到发现,短时间内可能存在高频次代码提交。
因此以上两点问题照旧在测试阶段存在效率问题
因此我使用go开发了一个自动压缩上传的程序
整体思路
程序整体思路并不难,就是使用go对打包后的产物进行代码压缩,然后以sftp上传至服务器,而这只需要在vite构建后自动执行既可,或者webpack构建完成后。
而js与go的交互只需通过node调用spawnapi启动go的进程既可,二者进程互相独立。
开发过程问题详细解
问题一:ESM与CommonJS
在package.json上这俩个个模式只是一行配置
{
"type": "module",//commonjs
}
默认不填写为commonjs
- 二者语法
//commonjs
const os = require('os')
//esm
import os from 'os'
- comonjs 为动态执行,esm为静态执行
- Tree‑Shaking优化,由于esm为静态执行,可以支持,但commonjs不支持
- commonjs是值拷贝,如果导出是对象,那么a模块修改后b模块并不会动,esm相反
问题二:require.resolve
在将我开发的功能转为npm插件中,阅读esbuild源码当中发现大量使用require.resolve。 常规cjs当中使用require('xx')导入node_modules里面的包 而require.resolve就是解析该包的路径
console.log(require.resolve('axios)) /xxx/xxx/项目名/node_modules/axios/xxx
后面的会为package.json里面配置的main 这是这个包的入口文件。 在esm当中也有推荐使用 createRequire
import { createRequire } from "module";
const require = createRequire(import.meta.url);
问题三:关于package当中各种dependencies
在package当中dependencies有很多种,以esbuild当中的dependencies看
{
"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架构是否符合
"os": [
"linux"
],
"cpu": [
"arm"
]
//限制为linux的arm架构可以安装成功
问题四:关于下载失败的保底机制
在esbuild当中,存在一个如果你npm i执行后esbuild的二进制包没有下载失败的保底程序,就从新下载
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当中配置
"scripts": {
"postinstall": "node install.js"
},
以上就是个人目前总结的东西!
也欢迎使用本人用go开发的sftp压缩上传的vite插件
目前没有像esbuild那样存在如果在npm i下载失败的保底机制,正在深入研究