NOde.js/Express 应用找不到一些 node_modules

NOde.js/Express App can't find some node_modules

我在我的应用程序中使用了几个 Node/Express 模块,只要我使用 const module = require('module');,每个模块都可以正常工作。我不需要为这些模块定义静态路径 app.use(express.static(path.join(__dirname, 'public')));.

但是,对于 sweetalert 模块,如果我在我的 layout.pug(基本 pug 文件)中定义 script(src="/node_modules/sweetalert/dist/sweetalert.min.js"),我收到 404 错误(未找到),除非我在 app.js 中包含以下静态路径:app.use("/node_modules", express.static(__dirname + "/node_modules"));.

我的问题是:这是正常行为还是我做错了什么? (我有点困惑为什么我必须只为我使用的几个模块之一定义一个静态路径。

这是怎么回事:

app.use(express.static(path.join(__dirname, 'public'))); 声明浏览器可以访问 public 目录。您应该将所有前端资源放在该文件夹中。这将有助于区分可以从服务器访问的内容和可以从客户端访问的内容。

当您引用 script(src="/node_modules/sweetalert/dist/sweetalert.min.js") 时,浏览器会抛出 404,因为该文件不在 public 目录中,因此浏览器无法访问。

添加这一行 app.use("/node_modules", express.static(__dirname + "/node_modules")); "fixes" 你的问题,但现在将你的所有 node_modules 暴露给浏览器。这可能不是一个好主意,我相信安全专家可以详细说明为什么不应该这样做。

我将如何解决此问题:检查您的 .pug 代码并查看您的前端所需的任何资源。然后将它们复制到 public 文件夹并修复您的引用以使用资源的副本。

这是我用来将资源从 node_module 目录移动到 public/assets 目录的脚本示例:

build.js:

const path = require('path');
var fs = require('fs');

const ASSETS = [
    'jquery/dist/jquery.min.js',
    'sweetalert/dist/sweetalert.min.js'
];

if (!fs.existsSync('./public/assets')){
    fs.mkdirSync('./public/assets');
}

ASSETS.map(asset => {
    let filename = asset.substring(asset.lastIndexOf("/") + 1);
    let from = path.resolve(__dirname, `./node_modules/${asset}`)
    let to = path.resolve(__dirname, `./public/assets/${filename}`)
    if (fs.existsSync(from)) {
        fs.createReadStream(from).pipe(fs.createWriteStream(to));
     } else {
        console.log(`${from} does not exist.\nUpdate the build.js script with the correct file paths.`)
        process.exit(1)
    }
});

然后我更新我的 package.json 以将其包含在脚本中:

package.json:

"scripts": {
    "build": "node ./build.js || true",
    "start": "node ./bin/www"
}

然后在我的任何视图页面中,我使用新路径引用资源

random.pug:

script(src="/assets/jquery.min.js")
script(src="/assets/sweetalert.min.js")

最后,在部署应用程序之前,您现在必须 运行 以下命令: npm run build 然后 npm start

如果您的前端资源发生变化,您只需要运行构建命令。因此,如果您只使用 sweetalert.min.js,则只需要在第一次 运行 您的应用程序时 运行 进行构建。如果稍后添加另一个资源 aNewResource.js,您将需要再次更新 build.js 文件和 运行 npm run build