近期一直在对公司的项目做优化,其中一环是将项目部署方式由Nginx改为OSS部署。需要将打包好的项目文件目录上传到阿里云OSS。
项目原先是VUE2+TS开发的,打包工具用的也是webpack。将webpack打包好的文件目录上传到OSS的webpack插件社区很容易就找到了。比如webpack-aliyun-oss,这里不做赘述,需要的小伙伴自行搜索。
一、开发Vite插件的初衷
由于这项目原先是VUE2+TS+webpack开发的。现在我已经重构了一个VUE3+TS+Vite的新项目。
好家伙!!?在社区溜了一圈,发现“将项目打包好的文件目录上传到OSS”的Vite插件不超过5个?相关MD文档不完善,且只有最基本的上传更新功能,与本人项目的需要不是很符合。
一直想参与开源,或是自己写点东西发布到NPM上去,可惜没有找到合适的需求去做。
正好。VUE3、Vite的生态相对而言还是有所欠缺,蹭波热度?造个轮子试试~~
二、明确需求
- 将Vite打包好的文件目录上传到阿里云OSS
- 如何读取需要上传的文件目录?(glob)
- 如何上传到阿里OSS?(ali-oss)
- 何时上传?(打包完成,输出bundle完成后)
- 显示上传进度,文件路径、链接等?
- 上传之后文件目录是否需要清空等。
三、准备工作
1、注册NPM账号,绑定邮箱。
这个我之前有注册过,但是没有绑定邮箱。这给我在后面进行npm publish发布的时候埋了一个坑。一直没能顺利发布,找了好长时间的问题。。。一直给我报NPM 403错误。
各位小伙伴注册完一定要记得绑定验证邮箱!!!
2、查阅Vite插件API的相关文档
由于是第一次接触Vite插件的开发,并不了解它的相关API和生命周期钩子函数等,完全不知道从哪开始入手(emo...)。只能去Git上面翻阅人家的源码,看下入口文件如何编写,这里不做赘述,下面会有写到。 Vite插件API官方文档
四、正文
1、开发工作
新建一个文件夹,文件夹名称为你的要发布的包名。取名的时候最好是去NPM官网搜一下你要发布的包名,因为包名是唯一性的。
1.1、初始化package.json
npm init
1.2、安装相关依赖库
有幸之前学习和使用过node.js。知道一些基本常用工具库。这里简单介绍一下各个依赖的作用。
- glob 获取目录下文件路径,返回一个路径数组。
- colors 控制台输入文案样式库。
- ali-oss 阿里OSS SDK。
- vite 用于引入Vite插件API 在对node工具库的选择的时候,最初我是用globby(glob的加强版)、kolorist(与colors类似)、ora(进度条)这些库,发现与Vite并不兼容,引入打包过程中会报错,原因是:Vite只允许使用import的方式引入对象,而globby、kolorist似乎并不是ESM模块,也可能是我使用的版本不对,或是没有配置balel,欢迎各位大佬指点~~
具体配置如下:
{
"name": "vite-plugin-oss",
"version": "1.1.2",
"description": "将打包好的文件目录上传到阿里云OSS",
"author": "jae <494595074@qq.com>",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/jaelam0214/vite-plugin-oss.git"
},
"scripts": {
"dev": "vite",
"build": "node_modules/.bin/tsc --newLine lf -d"
},
"keywords": [
"vite",
"plugin",
"oss"
],
"engines": {
"node": ">=14"
},
"license": "MIT",
"devDependencies": {
"@types/ali-oss": "^6.16.2",
"@types/glob": "^7.2.0",
"@types/node": "^16.11.7",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"typescript": "^4.4.4",
"vite-plugin-inspect": "^0.3.10"
},
"dependencies": {
"ali-oss": "^6.16.0",
"colors": "^1.4.0",
"glob": "^7.2.0",
"vite": "^2.6.14"
}
}
1.3、入口文件index.ts
由于排版问题,这部分代码做了删减,文末有git地址~
const assetUploaderPlugin = (options: PluginOptions): Plugin => {
const oss = new OSS({
region: options.region,
accessKeyId: options.accessKeyId,
accessKeySecret: options.accessKeySecret,
bucket: options.bucket
})
return {
name: 'vite-plugin-oss',
// 在解析 Vite 配置后调用。使用这个钩子读取和存储最终解析的配置。当插件需要根据运行的命令做一些不同的事情时,它也很有用。
configResolved: async (config) => {
// 获取需要上传的文件目录路径
outputPath = path.resolve(slash(config.build.outDir))
},
// 打包完成后执行上传
closeBundle: async () => {
// 获取需要上传的文件目录路径的所有文件的路径列表
const files = await glob.sync(from)
console.log(`需要更新上传的文件目录${files}`)
if (files.length) {
try {
await upload(files, true, outputPath)
} catch (err: any) {
console.log(red(err))
}
} else {
verbose && console.log(red(`no files to be uploaded`))
}
}
}
}
export default assetUploaderPlugin
这里最初遇到了一个问题,最开始把 upload() 更新方法放到了 configResolved() 钩子中,发现:此时打包构建工作还未完成,获取不到指定的文件目录。查阅Rollup文档,又尝试了 buildEnd() 钩子,发现还是一样的问题。最终实验 closeBundle() 钩子可行。
2、源码打包
执行
npm run build
将src下的文件编译打包输出到dist目录。目的:使外部项目能顺利通过import引入该插件。
这里遇到一个坑,使用tsup插件进行打包输出时,.dist/index.js并没有导出assetUploaderPlugin对象,导致外部安装该插件后无法顺利使用。 最后还是选用了tsc命令进行编译。
3、NPM发布
登录NPM
npm login
输入账号,密码、邮箱后,执行
npm pubilsh
记得一定要去NPM官网看下邮箱是否验证成功。登录后,如果没绑定验证邮箱,在网站页面顶部会有黄色警告框!
五、总结
vite-plugin-oss插件的使用配置说明 git源码、 npm地址
vite-plugin-oss
一个可以将打包好的文件目录上传到阿里OSS的vite(version>=2.6.0)插件。
Install 安装
npm i vite-plugin-oss -D
Options 配置参数
- region: 必传。阿里云上传区域
- accessKeyId: 必传。阿里云的授权accessKeyId
- accessKeySecret: 必传。阿里云的授权accessKeySecret
- bucket: 必传。上传到哪个bucket
- from: 必传。上传哪些文件,支持类似gulp.src的glob方法,如'./build/**', 为glob字符串。
- dist: 上传到oss哪个目录下,默认为oss根目录。可作为路径前缀使用。
- timeout: oss超时设置,默认为30秒(30000)
- overwrite: 是否覆盖oss同名文件。默认true。
- verbose: 是否显示上传日志,默认为true。
- deletOrigin: 上传完成是否删除原文件,默认false。
- deleteEmptyDir: 如果某个目录下的文件都上传过了,是否删除此目录。deleteOrigin为true时候生效。默认false。
- setOssPath: 自定义每个文件上传路径。接收参数为当前文件路径。不传,或者所传函数返回false则按默认方式上传。
- test: 测试,仅查看文件和上传路径,但是不执行上传操作。默认false。
- quitWpOnError: 出错是否中断打包。默认false。
- version: 版本号。默认为''。
- setVersion: 设置线上的版本号的方法。一般为axios请求方法,需同时配置version。
注意: accessKeyId, accessKeySecret 很重要,注意保密!!!
Basic Exapmle 基本例子
// vite.config.js
import { defineConfig } from 'vite'
import VitePluginOss from 'vite-plugin-oss'
export default defineConfig({
plugins: [
VitePluginOss({
from: './dist/**', // 上传那个文件或文件夹
dist: "/test", // 需要上传到oss上的给定文件目录
region: 'oss-xx-xx-1',
accessKeyId: 'xxxxxxxxxxxx',
accessKeySecret: 'xxxxxxxxxxxx',
bucket: 'xxxxxxxxx',
test: true, // 测试,可以在进行测试看上传路径是否正确, 打开后只会显示上传路径并不会真正上传。默认false
// 因为文件标识符 "\" 和 "/" 的区别 不进行 setOssPath配置,上传的文件夹就会拼到文件名上, 丢失了文件目录,所以需要对setOssPath 配置。
setOssPath: filePath => {
let index = filePath.lastIndexOf("dist")
let Path = filePath.substring(index + 4, filePath.length)
return Path.replace(/\\/g, "/")
},
})
],
});
Custom Exapmle 指定环境(模式)下使用例子
该例子为在执行 npm run build:oss 时引入插件
1.在项目根目录下增加环境配置文件 .env.oss
NODE_ENV = oss
2.package.json 增加打包命令-oss模式。
"build:oss": "vue-tsc --noEmit && vite build --mode oss"
{
"scripts": {
"dev": "vite",
"build:prod": "vue-tsc --noEmit && vite build",
"build:oss": "vue-tsc --noEmit && vite build --mode oss",
},
}
vite.config.js 按需引入
import { defineConfig } from 'vite'
import VitePluginOss from 'vite-plugin-oss'
export default ({ mode }) => {
const plugins = [] // 可将其他插件放入该数组
if (mode === 'oss') { // 仅oss模式下引入
plugins.push(VitePluginOss({
from: './dist/**', // 上传那个文件或文件夹
dist: "/test", // 需要上传到oss上的给定文件目录
region: 'oss-xx-xx-1',
accessKeyId: 'xxxxxxxxxxxx',
accessKeySecret: 'xxxxxxxxxxxx',
bucket: 'xxxxxxxxx',
test: true, // 测试,可以在进行测试看上传路径是否正确, 打开后只会显示上传路径并不会真正上传。默认false
// 因为文件标识符 "\" 和 "/" 的区别 不进行 setOssPath配置,上传的文件夹就会拼到文件名上, 丢失了文件目录,所以需要对setOssPath 配置。
setOssPath: filePath => {
// some operations to filePath
let index = filePath.lastIndexOf("dist")
let Path = filePath.substring(index + 4, filePath.length)
return Path.replace(/\\/g, "/")
},
}))
}
return defineConfig({
base: mode === 'oss' ? './' : '/',
plugins: plugins,
}
后续计划
- 优化代码结构
- 集成七牛云OSS等其他SDK
- 优化控制台输出日志
- ...