nodejs 模块以及加载机制,主要讨论找不到模块的问题
最主要的一个思想,加载模块无非就是找到模块在哪,只要清楚了模块的位置以及模块加载的逻辑那么找不到模块的问题就迎刃而解了。本文只是综合了自己所学的知识点进行总结,难免出现理解错误的地方,请见谅。
nodejs的模块分类
1、原生模块:http fs path等,这些模块都在源码包的lib目录下面,nodejs安装好之后是找不到这些模块的,都作为node.exe的一部分了,require这些模块永远没问题的,如果哪天出现问题了,直接重启电脑或者重装node。有什么疑问可以通过下载源码对这些原生模块的功能进行查看。地址:https://nodejs.org/download/
2、文件模块:第三方模块,例如express等,通过npm安装的模块都是第三方模块。经常找不到的也是这些个模块了。
3、文件模块:我们自己写的模块,之所以独立出来是因为其加载和另两种模块有区别。
怎样定义模块
nodejs声明一个模块有2中做法
exports.module_name
module.exports
关于这两个的区别也很简单,不过要讲明白很费劲,关键点在于知道有 module 这个全局变量的存在,打印出来并做几次尝试,就完全明白了,这里有一篇非常精彩 的关于这两者异同的文章:http://www.cnblogs.com/kongxianghai/p/3936197.html
第三方模块安装在哪(NPM)
几条命令
npm config get/set prefix //查看设置全局安装目录,全局安装的模块就安装该目录下面的node_modules目录下 npm install [-g] // -g 全局安装,模块将会安装到全局目录下。不带 -g 则直接安装在当前所在目录下,即为本地安装
模块的存在形式
1、文件包含,这个比较直观,直接指定到文件名(去掉 .js 后缀),就可以得到文件里面所有导出的模块。
2、文件夹包含,通过npm安装的第三方模块都是这种方式,指定到模块所在的文件夹,该文件夹就是模块名,以express为例:
加载代码:var ex = require(‘express‘)
加载机制:
首先搜索当前目录下的 package.json 文件,查找里面的mian属性,如果存在,则加载该属性所指定的的文件。
如果不存在 package.json 或者该文件里面没有main字段,nodejs将试图加载 index.js
都不存在那么就只有说一声Cannot find module了。
模块在哪些地方搜索(针对第三方模块)
1、逐级往上查找
在此介绍一个全局变量 process 里面包含了nodejs进程运行的所有信息,在此打印一下 process.mianModule
很明显,nodejs会从当前目录开始逐级往上搜索node_modules,找得到当然最好,找不到那么就会继续找node_path这个环境变量了。
2、环境变量node_path
如果环境变量中有node_path的存在,并且该变量的值为全局安装的目录,那么也不会出现找不到模块的错。
关于eclipse、sublime等IDE的node_path没有问题,如果遇到的话,可以给它们单独配置。当然,插件得先装好啊。
eclipse
右键 -> Run As -> Run Configurations... 找到下面的界面
Sublime
Preferences -> Package Settings -> Nodejs -> Settings-Default
填一下node_path
require(‘这里应该怎么填‘)
1、相对路径指定模块,一般用于加载自己的模块。
必须用到的符号: ./ 表示当前目录,相对路径所相对的就是当前的目录
../ 表示上一级模块,可以无限使用直到跳转到根目录
这两个符号必须以其中一个开头,比如想加载当前目录下的另一模块,假设文件名为 hello.js 当前所在文件为 hi.js 我们需要在hi.js文件中这样写:
var hello = require(‘./hello‘)//变量名随意,一般惯用文件名
在此基础上,再加入文件夹的名字,我们就可以加载到我们自己所写的任意模块了。
2、绝对路径指定模块地址,除了原生模块之外,任何文件模块都可以加载到,除非路径出错了。比如我们可以这样子加载express模块,以我的express模块所在路径为例。
这种情况下,还可以给express随便改名字,比如我把express的文件夹名改为ex
var ex = require(‘F:\\nodejs\\node_modules\\ex‘)
也是可以的。
3、直接使用 require(‘xxx‘) 那么所加载的模块要么是原生模块,要么该模块在某个node_modules目录下面
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。