pomelo-logger文件加载引发问题的解决

在使用pomelo 开发过程中碰到一个问题, 自定义的pomelo-logger 的配置文件是,无论我如何配置,都只会使用默认的控制台输出,而无法输出到指定文件。

问题排查

使用npm list 结果如下。

pomelo-logger文件加载引发问题的解决_第1张图片


pomelo-logger  被加载了两次。  只有[email protected]框架中输出的日志是按照,配置输出的。我的工程中使用,使用pomelo-logger始终为默认控制台数据。 难道pomelo-logger 类文件被加载了两次? debug 发现果然如此, v8 中存在两个pomelo-logger, 但名称空间却不相同:

  • 1个是:  /xxx/game/node_modules/pomelo-logger
  • 另外一个是: /xxx/game/node_modules/pomelo/pomelo-logger

在 pomelo 框架执行pomelo-logger 的configer 时,它只影响了 /xxx/game/node_modules/pomelo/pomelo-logger 对象。  找到问题,解决方案就很简单了,  在第一次引用 /xxx/game/node_modules/pomelo-logger的地方及 app.js 中,执行

require('pomelo-logger').configure("./config/log4js.json", {serverId : app.getServerId()});   及可。

思考1  :问题是解决了,但对比maven 对jar 的版本的冲突管理,难道npm 没有类似的机制吗。

进一步检查,这次pomelo-logger 包冲突的原因是我不正当安装导致。最初在我的项目中没有直接依赖pomelo-logger ,  我的项目是依赖于pomelo 的。 这是如果要部署应用,运行npm install , 会在 当前目录下生成 node_modules/pomelo/pomelo-logger 。 然后我觉得再我的项目中也使用pomelo-logger来管理日志, 这时我需要在当前项目的package.json 中加入对pomelo-logger的直接依赖。再次运行npm install 就会在node_modules 下产生两份 pomelo-logger.

晕,npm 没有类似maven的clean install 的命令。  这是只要把 当前应用的下的node_modules 全部删除,重新npm instatll ,这是发现 /xxx/game/node_modules/pomelo/pomelo-logger 将不再产生,问题结局。

思考2: v8加载相同模块是,为什么没有提示包冲突。

我们先看看v8的 包加载机制,

  1. 模块文件会在第一次被require到的时候,加载到内存。
  2. require 不会重复加载模块,也就是说无论调用多少次 require,获得的模块都是同一个
  3. 文件模块的加载有两种方式,一种是按路径加载,一种是查找 node_modules 文件夹。
    • 如果 require 参数以“ / ”开头,那么就以绝对路径的方式查找模块名称,例如 require("/aa/test")将会依次查找,/aa/test.js,   /aa/test.json,  /aa/test.node 查到一个立刻停止。
    • require 参数以相对路径开始,例如required("../test.js") 或 require("./test.js")表示以当前目录为相对地址查找文件。
    • 直接require 模块名, 例如pomelo 框架中引用pomelo-logger,    require("pomelo-logger"), 那么v8会首先在pomelo框架目录下的node_modules/ 下查找, 入轨查找不到那么就查找引用pomelo框架的父模块下的node_modules/ ,查找不到继续向上。
  4. 我们在通过引入require('heapdump'),    发送 kill -USR2  输出内存快照,heapdump**.heapsnapshot, 使用chrome 的 profile 来查看module 在 v8内存中的情况可以看到,每个文件就是一个module, module的ID为文件绝对路径的名称。 这里我们就明白了,为什么当通过npm list 发现有两个pomelo-logger 模块时候, node 启动后就会有两个 pomelo-logger对象。



pomelo-logger文件加载引发问题的解决_第2张图片

所以对于v8而已即使你使用的模块相同,但如果这个模块的文件在不同的目录下都存在,那么这个模块就有可能被加载对次,他们的对象互不影响。

对比npm同 maven 依赖的特点(这里定义当前应用未父节点,其依赖项为子节点。)

1、间接引用

nodejs 不可以直接required 依赖的依赖。如game  依赖 pomelo,  pomelo 依赖于pomelo-logger, 这时是不可以在game中使用pomelo-logger 的, 如果game需要使用pomelo-logger,需要在game 的package.json中直接依赖pomelo-logger。

2、兄弟项之间,依赖相同的包。

在nodejs 中,如果兄弟包中依赖相同的包,这是如果没有共同的父类节点最抉择。那么将会产生共同的依赖将会在内存在产生两份类文件对象,各自的属性可各不相同。  maven 则出现此类问题,将报错,版本冲突。

 

你可能感兴趣的:(pomelo-logger文件加载引发问题的解决)