是否可以使用 express.js 清除 node.js 需要缓存?

Is it possible to clear node.js require cache using express.js?

我为自己编写了 node.js 小应用程序,它使用小的 js 代码在处理请求之前清除 require 缓存:

let clearCache
if (process.env.NODE_ENV === 'development') {
  const {cache} = require
  clearCache = (except) => {
    for (let key in cache)
      if (!except.includes(key) && key.indexOf('/node_modules/') === -1)
        delete cache[key]
  }
} else {
  clearCache = () => {}
}

const { createServer } = require('http')
const persistentPaths = ['/path/to/my/db/file']
createServer((req, res) => {
  clearCache(persistentPaths)
  require('./handleRequest')(req, res)
}).listen(3000, () => {})

我相信这是在开发中使用应用程序的最有效方式。

当我更改代码时,它会立即应用,这对我来说效果很好。

现在我想使用 express.js,但似乎无法使用这种方法。

好吧,好像是自答题,需要用到nodemon。

但我真的不想使用将监视所有文件并重新启动整个服务器的工具。恐怕会慢很多。

在我的示例中,您可以看到我重新加载了除 db 文件之外的文件,因此我的开发中的应用程序仅连接到数据库一次并保持该连接。如果使用 nodemon 应用程序还需要加载所有 node_modules 代码,每次更改代码时都会与数据库建立新连接,也许每次都会连接到 postgres 和 redis。

问题是:我不会是这样做的人,有没有为 express.js 重新加载模块的解决方案?

做到了!如果您能分享您的想法,我们将很高兴。

因为我只能 google nodemon 和 chokidar 解决方案,也许我在做一些奇怪的事情,这是我的解决方案:

server.ts:

import express from 'express'
const app = express()
const port = 3000

app.listen(port, () =>
  console.log(`Example app listening at http://localhost:${port}`)
)

if (process.env.NODE_ENV === 'development') {
  const {cache} = require
  const persistentFiles: string[] = []
  const clearCache = (except: string[]) => {
    for (let key in cache)
      if (!except.includes(key) && key.indexOf('/node_modules/') === -1)
        delete cache[key]
  }
  app.use((req, res, next) => {
    clearCache(persistentFiles)
    const {router} = require('config/routes')
    router.handle(req, res, next)
  })
} else {
  const router = require('config/routes')
  app.use(router.handle)
}

和routes.ts:

import {Router, Request, Response} from 'express'
export const router = Router()

router.get('/', function (req: Request, res: Response) {
  res.send('Hello world')
})

用法:NODE_ENV=开发NODE_PATH=src节点src/server.js

(我的IDE边编辑边把ts编译成js放在那里,如果你用的是VS code可能会更复杂,我猜)

您不需要编写一个实用程序。你可以使用像 chokidar 这样的模块。可以指定目录,同时忽略。

您可以在手表回调时重新加载。

维基百科示例:https://github.com/paulmillr/chokidar

const chokidar = require("chokidar");

// Full list of options. See below for descriptions.
// Do not use this example!
chokidar.watch("file", {
  persistent: true,

  ignored: "*.txt",
  ignoreInitial: false,
  followSymlinks: true,
  cwd: ".",
  disableGlobbing: false,
  awaitWriteFinish: {
    stabilityThreshold: 2000,
    pollInterval: 100,
  },

  ignorePermissionErrors: false,
  atomic: true, // or a custom 'atomicity delay', in milliseconds (default 100)
});
// One-liner for current directory
chokidar.watch(".").on("all", (event, path) => {
  // Reload module here.
});