公司最近的一个开发项目使用nodejs作为后端。这两天需要打包给客户演示,于是请了公司的小哥把之前3D机房的打包工具移植过来。打包后发现在开发环境中运行良好的项目无法访问。出现项目首页无法访问的问题:cannotgetfileindex.htmlexpress.static问题出在哪里?nodejs后端使用express,index.html是静态文件。我们知道Express内置的express.static可以很方便的承载静态文件,比如图片、CSS、JavaScript文件等,将静态资源文件所在的目录作为参数传递给express.static中间件,提供对静态资源文件的访问静态资源文件。例如,假设图片、CSS和JavaScript文件放在public目录下,可以使用如下代码:app.use(express.static('public'));于是,找到项目中的代码,查看调用static的地方,和上面一行代码是一样的:app.use(express.static('public'));至此,我已经发现了问题所在,并告诉朋友,这个地方不用相对路径就可以解决这个问题。由于打包时间有限,就托朋友们先处理了。打包之后整理思路:app.use(express.static('resource/public'));当然,最重要的是,这个问题其实并不难,自己研究一下,很容易找到问题所在,也不会有这个问题,那就自己动手吧。嗯,你没看错,这个地方还是一个相对目录。在后续产品中会改成更好的情况。express.static方法分析其实,express.static方法如果传入的是相对路径,express会将其转为绝对路径。我们可以查看源码,在express.js中找到如下代码:exports.static=require('serve-static');表示static调用serve-static包,直接找到这个包,查看index.js,可以看到代码,下面列出重要的两行...varresolve=require('path').resolve...opts.root=resolve(root)...这两行是表示将相对目录转换为绝对目录的代码。可以看出最终使用了内置对象路径的resolve方法。继续往下看。path对象的resolve方法直接查看该方法的api文档,如下:https://nodejs.org/api/path.h...下面是该方法的解释:path.resolve()方法将一系列路径或路径段解析为绝对路径。你是什??么意思?就是这个方法将一系列的路径或者路径段组织成一个绝对路径,比如path.resolve('/foo','bar');//return/foo/bar详细说明可以参考文档你自己,这里有一句话需要特别注意:如果在处理完所有给定的路径段后还没有生成绝对路径,则使用当前工作目录。什么意思,就是如果所有的路径段都处理完了,还没有生成绝对路径,那么就使用当前工作目录。例如:path.resolve('bar');//加上/Users/terry是当前工作目录,return/Users/terry/barapi是文档中比较复杂的例子(这里注意解析的时候,从右到left,详见文档):path.resolve('wwwroot','static_files/png/','../gif/image.gif');//如果当前工作目录是/home/myself/node,//这返回'/home/myself/node/wwwroot/static_files/gif/image.gif'现在的问题是,当前工作目录是什么。nodejs当前工作目录currentworkingdirectorynodejs当前工作目录是Node启动的目录。也就是说从哪个目录开始节点,返回哪个目录。注意这个目录不是指js文件所在的目录。当前工作目录可以通过process.cwd()方法获取。下面举例介绍当前工作目录。如果在/Users/terry/Documents/JSWorkspace目录下写一个js文件,test.js,代码只有一行:console.log(process.cwd());这时候如果,在/Users/terry/Documents/JSWorkspace目录下执行命令:nodetest.js输出结果如下:/Users/terry/Documents/JSWorkspace但是如果在/Users目录下执行命令/terry/Documents/:node./JSWorkspace/test.js,输出结果为:/Users/terry/Documents所以可以看到在那个目录下执行了node命令,当前目录就是那个目录。回到之前的打包问题,因为在开发阶段,一般直接在js文件所在目录下执行node命令,所以相对于当前js文件所在目录写相对目录是没有问题的.但是打包之后,node的执行放在了js目录的上层。此时的相对目录“public”并不是相对于js文件的相对目录,而是相对于上层的。自然找不到这个文件夹,也就找不到这个文件夹下的index.html文件。.解决方法:前面说了,改这个相对目录。但这种方法是蹩脚的。因为,启动节点命令的目录可能会改变;但如果应该的话,开发阶段node命令的执行也需要做相应的改变。简而言之,它不是一种非常兼容的方法。直接使用绝对路径。但是这个绝对路径在不同的机器上是不一样的,怎么解决呢?您可以考虑使用全局变量__dirname。全局变量__dirname看api文档https://nodejs.org/api/module...看解释如下:当前模块的目录名。这与路径相同。__filename的dirname()。啥意思,及时回到nodejs的js文件所在目录。有了这个变量,我们就可以用下面的代码来解决这个问题了。app.use(express.static(__dirname+'/public'));更多精彩内容,请关注公众号。
