我们写完一个项目之后都会打包部署到线上,如果打包以后的代码有问题的话就需要通过线上的代码去排查。这样会很麻烦而且效率不高。
代码打包完之后本质上就是一堆html、css、js的静态文件。我们可以在本地通过nginx去部署我们的代码,不过在我学习vite时看到一个命令"preview": "vite preview"就是本地显示打包好的代码。到这就来了兴趣,然后自己也在项目当中实现一个preview。
const express = require('express')
const app = express()
const os = require('os');
const path = require('path')
const fs = require('fs')
const {createProxyMiddleware} = require('http-proxy-middleware')
const shell = require('shelljs')
const c = require('child_process');
const net = require('net');
const port = 8888
const rootDir = path.join(__dirname, '../dist')
// 代理地址
const proxyTargetUrl = 'http://api接口地址'
// 检查dist目录
try {
fs.statSync(rootDir).isDirectory()
} catch (error) {
shell.exec('npm run dist')
}
app.use(express.static(rootDir))
app.use('/api/**', createProxyMiddleware({target: proxyTargetUrl, changeOrigin: true}));
app.get('*', (req, res) => {
res.sendFile(`${rootDir}/index.html`)
})
getAvailablePort(port, availablePort => {
app.listen(availablePort, () => {
shell.echo(`Local preview at: http://localhost:${availablePort}`)
shell.echo(`Ip preview at: http://${getIPAddress()}:${availablePort}`)
c.exec(`start http://localhost:${availablePort}`)
})
})
// 获取本地ip
function getIPAddress() {
const interfaces = os.networkInterfaces();
for (const devName in interfaces) {
const iface = interfaces[devName];
for (let i = 0; i < iface.length; i++) {
const alias = iface[i];
if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
return alias.address;
}
}
}
}
// 获取空闲端口
async function getAvailablePort(port, portAvailableCallback) {
const portUsed = port => {
const server = net.createServer().listen(port)
return new Promise((resolve, reject) => {
server.on('listening', () => {
server.close()
resolve(false)
})
server.on('error', err => {
if (err.code === 'EADDRINUSE') {
resolve(true)
}
})
})
}
const tryUsePort = async function (port, portAvailableCallback) {
const res = await portUsed(port)
if (res) {
port++
tryUsePort(port, portAvailableCallback)
} else {
portAvailableCallback(port)
return port
}
}
return new Promise((resolve, reject) => {
tryUsePort(port, portAvailableCallback)
})
}
为了防止端口冲突,还对端口进行了检查。package.json添加命令"preview":"node ./bin/preview.js",即可实现和vite preview一样的功能。美滋滋。