这两行代码的目的是以前我们写 var xxx = require("…/…/lib/aa.js"); 可以直接写 var xxx = require(“lib/js”);
1231<br/><br/><a class=“form” href=“https://github.com/shinygang/Vue-cnodejs”>I‘m webapp-cnodejs-vue</a>
这样hack代码,要将自己玩坏 自豪地采用 CNodeJS ionic
要消灭dot hell,可以搞一个process.cwd() + path呀
process.cwd() + path
不明白 好处在哪里
将
require("./lib/foo");
可以以
require("lib/foo");
的形式出现。
我的项目里面也有这种 hack,只不过方式不一样。
Module._resolveFilename = function(request, parent) { if(!request.startsWith('./') && !request.startsWith('../')) { if(cache[request]) { request = cache[request]; } else if(undefined === cache[request]) { // that is $PROJ_ROOT/src/ var testRequest = path.resolve(SRC_PATH, request); var names = [ testRequest + '.js', testRequest + '.json', testRequest + '/index.js', testRequest + '/index.json' ]; /** * because * * > Stability: 0 - Deprecated: Use fs.statSync or fs.accessSync instead. * * so we use try...catch and statSync instead * * see https://nodejs.org/api/fs.html#fs_fs_existssync_path */ cache[request] = false; for(var i = 0; i < names.length; i++) { try { if(fs.statSync(names[i]).isFile()) { request = cache[request] = testRequest; break; } } catch(e) { // ignore... } } } } return _resolveFilename(request, parent); };
这个框架已经弃坑了,不推荐这样hack的方式。
挖坟啊,这什么时候的视频。。。
@xinyu198736 为啥不推荐,我翻了下lib/modules.js的源码,貌似逻辑没啥问题 对于require的路径,依旧是先匹配内建模块——不成功匹配各个node_modules目录——不成功匹配process.env.NODE_PATH——不成功throw error 我觉得逻辑上没啥问题啊
@xinyu198736 这个process.env.NODE_PATH应该是用来替换最早的require.paths方法的
我觉得完全没有必要这样hack,反而不利于寻找代码
@captainblue2013 在写代码时已规定了结构。不需要去找。
@hyj1991 源码在哪?? 能粘出主要代码吗??
@mrlong
Module._initPaths = function () { var paths = [path.resolve(process.execPath, '..', '..', 'lib', 'node')]; var nodePath = process.env['NODE_PATH']; if (nodePath) { paths = nodePath.split(path.delimiter).filter(function (path) { return !!path; }).concat(paths); } //如果process.env['NODE_PATH']有值,modulePaths里面添加用户设置的path,用作匹配 modulePaths = paths; };
//最终require模块匹配是在_resolveFilename函数里面完成的,但是匹配的前缀path,是由_resolveLookupPaths提供的 Module.prototype.require—>Module._load—>Module._resolveFilename—>Module._resolveLookupPaths
Module._resolveLookupPaths = function (request, parent) { var start = request.substring(0, 2); if (start !== './' && start !== '..') { //首先将paths赋值成为上述的modulePaths var paths = modulePaths; if (parent) { if (!parent.paths) parent.paths = []; //parent.paths里面包含的内容是[当前绝对路径/node_modules,当前上一级绝对路径/node_modules,...,/node_modules],这里讲parent.paths和paths做了一次concat paths = parent.paths.concat(paths); } //返回参数形式为[原始require方法内填写的内容(比如'lib/js'),第二个参数是用来组装匹配的路径数组] return [request, paths]; }
Module._findPath = function (request, paths) { //此处request为用户require的内容,比如:'lib/js', //此处paths为上述返回的数组,内容为:[当前路径/node_modules,当前路径上一级/node_modules,...,一直到根路径/node_modules,process.env.NODE_PATH] for (var i = 0, PL = paths.length; i < PL; i++) { if (paths[i] && internalModuleStat(path._makeLong(paths[i])) < 1) continue; var basePath = path.resolve(paths[i], request); //下面是对basePath进行验证处理的逻辑 } //如果一直没匹配到,返回false return false };
可以看到,上述代码中的循环所操作的就是调用path.resolve方法,对paths数组里面的每一个内容和’lib/js’进行匹配,匹配到就返回成功 所以呢,如果你不添加process.env.NODE_PATH参数,则只会寻找各级目录下的node_modules文件夹,如果添加了process.env.NODE_PATH,则会在寻找完各级路径下的node_modules文件夹后,再去匹配下process.env.NODE_PATH的路径 这就是大搜车内部两行代码的作用,需要注意到是,这两行代码需要放到启动js文件的顶部,才会生效
并且这不算什么hack方法,看懂源码,其实对原始require流程没有什么影响,因为requrie加载非相对路径和绝对路径modules的优先级依旧是: 1.从当前目录开始各级目录下的node_modules目录寻找 2.各级目录下的node_modules文件夹匹配不到寻找process.env.NODE_PATH目录下对应内容 3.以上都匹配不到返回false,throw 未找到module的异常
会不会影响编辑器的代码跳转和路径联想功能?
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
这两行代码的目的是以前我们写 var xxx = require("…/…/lib/aa.js"); 可以直接写 var xxx = require(“lib/js”);
1231<br/><br/><a class=“form” href=“https://github.com/shinygang/Vue-cnodejs”>I‘m webapp-cnodejs-vue</a>
这样hack代码,要将自己玩坏 自豪地采用 CNodeJS ionic
要消灭dot hell,可以搞一个
process.cwd() + path呀不明白 好处在哪里
将
可以以
的形式出现。
我的项目里面也有这种 hack,只不过方式不一样。
这个框架已经弃坑了,不推荐这样hack的方式。
挖坟啊,这什么时候的视频。。。
@xinyu198736 为啥不推荐,我翻了下lib/modules.js的源码,貌似逻辑没啥问题 对于require的路径,依旧是先匹配内建模块——不成功匹配各个node_modules目录——不成功匹配process.env.NODE_PATH——不成功throw error 我觉得逻辑上没啥问题啊
@xinyu198736 这个process.env.NODE_PATH应该是用来替换最早的require.paths方法的
我觉得完全没有必要这样hack,反而不利于寻找代码
@captainblue2013 在写代码时已规定了结构。不需要去找。
@hyj1991 源码在哪?? 能粘出主要代码吗??
@mrlong
_initPaths()主要向全局modulePaths数组变量中,添加了你设置的path,用来匹配,核心代码见下:
require的大致流程:
当requrie的内容最前面两位不带’./‘或者’…'时,匹配的方式是使用modulePaths里面的内容concat上parent里面的path参数
最后一步在_resolveFilename函数中调用Module._findPath(request, paths)进行最终的匹配,大致代码逻辑如下:
可以看到,上述代码中的循环所操作的就是调用path.resolve方法,对paths数组里面的每一个内容和’lib/js’进行匹配,匹配到就返回成功 所以呢,如果你不添加process.env.NODE_PATH参数,则只会寻找各级目录下的node_modules文件夹,如果添加了process.env.NODE_PATH,则会在寻找完各级路径下的node_modules文件夹后,再去匹配下process.env.NODE_PATH的路径 这就是大搜车内部两行代码的作用,需要注意到是,这两行代码需要放到启动js文件的顶部,才会生效
结论
并且这不算什么hack方法,看懂源码,其实对原始require流程没有什么影响,因为requrie加载非相对路径和绝对路径modules的优先级依旧是: 1.从当前目录开始各级目录下的node_modules目录寻找 2.各级目录下的node_modules文件夹匹配不到寻找process.env.NODE_PATH目录下对应内容 3.以上都匹配不到返回false,throw 未找到module的异常
会不会影响编辑器的代码跳转和路径联想功能?