以前简单说明过基于fastify-autoload 的插件化加载fastify插件,方便实现开发,但是对于实际生产环境我们可以需要频繁的模块修改,发布以及构建,所以需要我们需要频繁的调整,不是很方便,我们可以基于ncc 进行入口的打包,同时对于每个插件也基于ncc 打包为独立的文件,这样我们开发的插件只需要基于ci/cd 构建之后放到s3中,然后reload 服务就可以了
参考集成
简单说明: 基于fastify-autoload 加载插件,但是存储的存储基于ci/cd 直接可以存储到s3 中,对于运行示例基于juicefs 或者mountpoint-s3 进行
s3 数据的挂载,这样数据就是动态的
项目结构
- 参考结构
├── Dockerfile
├── README.md
├── app-restart.js
├── app.js
├── config.js
├── docker-compose.yaml
├── package.json
├── plugins
│ ├── apps
│ │ └── app.js
│ ├── home
│ │ └── app.js
│ ├── init
│ │ └── app.js
│ ├── login
│ │ └── app.js
│ └── users
│ └── app.js
├── tsup.config.js
└── yarn.lock
代码简单说明
- pacakge.json
{
"name": "fastify-autoload-app",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"@fastify/autoload": "^5.7.1",
"@fastify/restartable": "^2.1.1",
"dotenv": "^16.3.1",
"fastify": "^4.24.0",
"fastify-plugin": "^4.5.1",
"hashids": "^2.3.0"
},
"scripts": {
"plugin-build": "ncc build app.js -o dist ",
"plugin-app": "ncc build plugins/apps/app.js -o distapp/plugins/apps",
"plugin-init": "ncc build plugins/init/app.js -o distapp/plugins/init",
"plugin-home": "ncc build plugins/home/app.js -o distapp/plugins/home",
"plugin-users": "ncc build plugins/users/app.js -o distapp/plugins/users",
"plugin-login": "ncc build plugins/login/app.js -o distapp/plugins/login",
"tsup": "tsup app.js -d distv2",
"myplugin-build": "concurrently 'yarn:plugin-*'"
},
"devDependencies": {
"@vercel/ncc": "^0.38.0",
"concurrently": "^8.2.1",
"tsup": "^7.2.0"
}
}
- app.js
应用的入口
require('dotenv').config()
const Fastify = require('fastify')
const path = require("path")
const autoLoad = require('@fastify/autoload');
const config = require('./config')
const app = Fastify({
logger: true,
ignoreDuplicateSlashes: true,
}
);
// 加载插件
app.register(autoLoad, {
dir: path.join(__dirname, config.pluginPath)
})
app.listen({
port: 3000,
host: '0.0.0.0',
backlog: 511
}, (err, address) => {
if (err) {
console.log(err)
process.exit(1)
} else {
console.log(`Server listening on ${address}`)
}
})
- 插件开发
就是一个标注的基于fastify-plugin的包装,主要说明一个简单的login,其他的类似
const fp = require('fastify-plugin')
function login(fastify, opts, done) {
fastify.get("/login", async (req, res) => {
res.send({
version:"v3333",
login:"login"
})
})
done()
}
module.exports = fp(login, {
name: "login"
})
- docker 运行
Dockerfile 主要包含了入口
FROM node:18.18.2-buster-slim
WORKDIR /app
ENTRYPOINT [ "node","index.js" ]
docker-compose 文件
version: "3"
services:
app:
build: ./
volumes:
- ./dist:/app/
- ./distapp:/app/plugins
env_file:
- ./.env
ports:
- "3000:3000"
构建之后的效果
对于多个插件的构建基于了concurrently,当然基于tsup 也是一种可选的方式,基本上类似
说明
此处基于s3 的插件加载实际上可以使用类似文件系统扩展的包,目前已经有一些底层使用s3 但是可以暴露为标注node fs 操作的包
但是比较稳定的似乎不是很好,对于我们新开发的插件直接基于标准开发,然后使用ncc 包装为一个单一文件,之后reload 服务就
可以生效了,还是很方便的,至少对于很多环境我们需要使用npm 包,但是网络不是很方便的是否很简单了不少,目前此方式是有
一些缺陷,相同的npm 包会有多个,同时可能会造成文件比较大,当然基于ncc 的集成模式实际上也是实现了一种简单的多版本包
如果能实现类似webpack module federation 的能力,就更加方便了
参考资料
https://github.com/vercel/ncc
https://github.com/fastify/fastify-autoload
https://github.com/fastify/fastify-plugin
https://github.com/awslabs/mountpoint-s3
https://github.com/juicedata/juicefs
https://github.com/rongfengliang/fastify-autoload_ncc_pacakge