最近公司的一个开发项目,后端用的是nodejs。这两天需要打包给客户演示,就让公司一个小伙把之前3D机房的打包工具移植过来。打包之后,发现原本在开发环境下的跑的好好的项目,不能访问了。出现项目的首页不能访问的问题:
can not get file index.html
express.static
问题出在哪儿?
nodejs后端的用了express,index.html是一个静态文件。我们知道,通过 Express 内置的 express.static 可以方便地托管静态文件,例如图片、CSS、JavaScript 文件等。
将静态资源文件所在的目录作为参数传递给 express.static 中间件就可以提供静态资源文件的访问了。例如,假设在 public 目录放置了图片、CSS 和 JavaScript 文件,可以使用如下代码:
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, 可以看到代码,下面列出重要的两行
... var resolve = require('path').resolve ... opts.root = resolve(root) ...
这两行就是,express把相对目录转换成绝对目录的代码,可以看出,最终使用的path这个内置对象的resolve方法,继续往下看。
path对象的resolve方法
直接查看这个方法的api文档,如下:https://nodejs.org/api/path.html#path_path_resolve_paths
下面是这个方法的解释:
The path.resolve() method resolves a sequence of paths or path segments into an absolute path.
啥意思呢? 就是这个方法把一系列的paths或者path segments 组织成一个绝对路径,比如
path.resolve('/foo','bar'); // return /foo/bar
详细的说明请自行参考文档,这个地方有一句话需要特别注意:
If after processing all given path segments an absolute path has not yet been generated, the current working directory is used.
啥意思,就是如果处理完了所有的path segments,也没有生成一个绝对路径, 就要使用 当前工作目录(current working directory)。比如:
path.resolve('bar'); // 加上 /Users/terry 是当前工作目录, return /Users/terry/bar
api文档中一个比较复杂的示例(此处注意resolve的时候,从右到左,参考文档了解详情):
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif'); // if the current working directory is /home/myself/node, // this returns '/home/myself/node/wwwroot/static_files/gif/image.gif'
现在的问题是,啥是当前工作目录。
nodejs 当前工作目录 current working directory
nodejs 当前工作目录是启动Node的目录。也就是说,从哪个目录进去启动node,就返回哪个目录。
注意,这个目录不是指js文件所在的目录
通过process.cwd()方法可以获取当前工作目录。
下面通过一个示例来介绍这个当前工作目录,假如在/Users/terry/Documents/JSWorkspace目录下写一个js文件,test.js,代码只有一行:
console.log(process.cwd());
此时如果,在目录/Users/terry/Documents/JSWorkspace下面执行命令 :node test.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文件。
如何解决
解决的方法:
1.在前面已经说过了,改这个相对目录。但这种方法很蹩脚。因为,启动node命令的目录可能会变;而是如果这应该,开发阶段的node命令执行也需要跟着改。 总之不是兼容性很好的方法。
2.直接使用绝对路径。 但是这个绝对路径在不同的机器上又不一样,该如何解决呢?可以考虑使用全局变量__dirname.
全局变量__dirname
查看api文档 https://nodejs.org/api/modules.html#modules_dirname
看到解释如下:
The directory name of the current module. This is the same as the path.dirname() of the __filename。
啥意思呢,及时返回nodejs 的js文件的所在目录。
有了这个变量之后,我们就可以用如下代码解决这个问题。
app.use(express.static(__dirname + '/public'));
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
问题内容: 从某人的项目中,我收到此错误: 我有最新的JDK(jdk1.6.0_25)。据我了解,我可以执行以下操作之一: 下载J2SE-1.5环境以匹配项目。 编辑项目以与最新的JDK保持一致。 我怎样才能做到这一点? 问题答案: 这是一个很好的讨论: 如何在1.5兼容模式下使用JDK 1.6 基本上你应该 下载并安装1.5 JDK。(下载链接) 在Eclipse中,转到 窗口 → 首选项 →
全部的我和你有一个很奇怪的问题https://github.com/json-path/JsonPath 其中一个问题似乎是实现中存在的重入问题:当执行路径时,每个片段返回一个字符串: 我通过将JSONObject/JSONArray传递给JsonPath.read()而不是JSON字符串来“黑客”。做完后,现在我得到了: 如您所见,这已经是一个数组。我在谷歌上搜索了很多次,但都找不到问题所在。
我在设置Java开发环境时遇到了一个问题。在过去,我安装了Java,然后安装了IDE,然后开始编写代码。我现在开始设置我的笔记本电脑,使用命令行编译和记事本作为我的代码编辑器。这是我第一次尝试纠正错误。 我运行javac,它创建了我的。类文件没有问题,但是我尝试用java A运行类文件,它抛出了一个错误: c:\工作区 我的类路径设置为C:\Program Files\Java\jdk-14.0.
并得到以下错误消息: 我找到了一个似乎可以解决我的问题的答案:使用Python-GeckoDriver可执行文件的Selenium需要在PATH中 但我不太明白如何操作计算机中的路径或如何以计算机工作的方式组织我的文件。
问题内容: 这似乎是一个直接的问题。但我无法破解。在helper1.js中,我想访问foobar.json(来自) 我无法使它正常工作fs:如何找到父文件夹? 这里的任何帮助将是巨大的。 问题答案: 您可以使用该模块将所在目录的路径连接到的相对路径。这将为您提供前往的绝对路径。 假设采用UTF8编码,则此方法应可在Linux,OSX和Windows上使用。
问题内容: 我正在尝试重新编译我一直在研究的项目,并且在尝试加载属性文件时始终收到错误消息: 我想这与类路径有关。但是我已经在Properties-> Java build path-> Libraries(外部类)中将路径添加到文件中。我还检查了eclipse生成的.classpath文件,该路径确实存在! 为什么Eclipse找不到正确的路径? 问题答案: 有2个不同的类路径,构建类路径和运行