几十行代码实现打包代码preview

169 阅读1分钟

我们写完一个项目之后都会打包部署到线上,如果打包以后的代码有问题的话就需要通过线上的代码去排查。这样会很麻烦而且效率不高。 代码打包完之后本质上就是一堆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一样的功能。美滋滋。