zoukankan      html  css  js  c++  java
  • node 学习笔记

    本文同步自我的个人博客:http://www.52cik.com/2015/12/11/learn-node-modules-path.html

    用了这么久的 require,但却没有系统的学习过 node 的模块系统,今天就翻官方文档系统的学习下。

    循环引用

    node 对模块循环引用做了相应的处理,防止无尽的循环。

    官方例子:

    a.js:

    console.log('a starting');
    exports.done = false;
    var b = require('./b.js');
    console.log('in a, b.done = %j', b.done);
    exports.done = true;
    console.log('a done');
    

    b.js:

    console.log('b starting');
    exports.done = false;
    var a = require('./a.js');
    console.log('in b, a.done = %j', a.done);
    exports.done = true;
    console.log('b done');
    

    main.js:

    console.log('main starting');
    var a = require('./a.js');
    var b = require('./b.js');
    console.log('in main, a.done=%j, b.done=%j', a.done, b.done);
    

    执行结果:

    $ node main.js
    main starting
    a starting
    b starting
    in b, a.done = false
    b done
    in a, b.done = true
    a done
    in main, a.done=true, b.done=true
    

    在结果中可以看到,b 里引用 a 的时候结果是 a.done = false,这就算文档里说的 unfinished copy,这样就避免了程序的死循环。

    核心模块

    其实就是被编译到 node 内部的一些模块,在源码的 lib 目录下可以找到。例如 require('http') 的时候不论是否有其他同名模块,都直接返回 node 的核心模块,也就算最高优先级。

    这些模块就是 node 官网文档目录列表里的那些模块。

    文件模块

    这个花样就多了,慢慢说吧。

    模块后缀

    node 默认支持 .js .json .node 后缀的模块,也就是说 require 的时候不需要写后缀名。例如 require('./a'),node 会先尝试当前目录下的 a.js 文件,如果有,就载入否则继续尝试 a.json, a.node 这些文件,如果都不存在,就会抛出模块未找到的错误。

    当然这些模块后缀都是可以自己定义拓展的,比如 ejs 就拓展了个 .ejs 的后缀,支持直接 require 就得到了编译好的模块引擎了。

    模块路径

    以 '/', './' 或 '../' 开头的,都是指定路径加载。

    模块以 '/' 为前缀,则表示绝对路径。例如,require('/home/marco/foo.js') 加载的是 /home/marco/foo.js 这个文件。

    模块以 './' 为前缀,则路径是相对于当前文件的。也就是说,circle.js 必须和 foo.js 在同一目录下,require('./circle') 才能找到。

    其实还一个特殊路径的模块加载,就是 node_modules 文件夹,这个要单独说了。

    从 node_modules 目录中加载

    如果模块不是以 '/', './' 或 '../' 开头的,那么 node 会从当前模块的父目录开始,尝试在它的 node_modules 文件夹里加载相应模块。如果没有找到,那么就再向上移动到父目录,直到到达顶层目录位置。

    假如 /home/ry/projects/foo.js 调用了 require('bar.js') 那么node查找的位置依次为:

    • /home/ry/projects/node_modules/bar.js
    • /home/ry/node_modules/bar.js
    • /home/node_modules/bar.js
    • /node_modules/bar.js

    如果都找不到,会去全局模块路径找,还找不到就会抛出模块未找到的错误。

    目录模块

    当一个模块功能多代码多的时候,不合适写到一个文件里,那这个时候就可以用目录当作模块使用了。有两种方法可以让一个目录作为 require 方式引入。官网说三种,其实吧 .js .node 看做两种了。

    index.js 入口

    例如在 some-library 目录里有 index.js 或者 index.node 文件,那么 require('./some-library') 就将尝试加载下面的文件:

    • ./some-library/index.js
    • ./some-library/index.node

    非常简单方便。

    package.json

    还有一种方式可以指定入口文件,就是通过 package.json,下面是一个 package.json 文件的示例。

    {
      "name" : "some-library",
      "main" : "./src/some-library.js"
    }
    

    那么 require('./some-library') 就将会去加载 ./some-library/src/some-library.js。

    全局模块

    当以上方法找不到模块时,node 会去全局配置下寻找全局模块:

    • $HOME/.node_modules
    • $HOME/.node_libraries
    • $PREFIX/lib/node

    以及

    • /usr/lib/node_modules

    或者

    • /usr/local/lib/node_modules

    这些都没测试,我只知道我本地的全局模块路径是 /usr/local/lib/node_modules,是我本机 npm 安装的全局模块路径。

    官网里还有一些奇葩的全局目录,我都没见过,算了不研究了。

  • 相关阅读:
    lombok 异常:Lombok needs a default constructor in the base class less... (Ctrl+F1) Inspe
    kinaba 安装踩坑: FATAL Error: [elasticsearch.url]: definition for this key is missing
    使用Java将搜狗词库文件(文件后缀为.scel)转为.txt文件
    RedHat linux服务器安装elasticsearch且设置公网访问
    return array 评论添加状态和提示信息
    .保护Express应用程序
    SQL Injection(SQL注入漏洞)
    POST在发送数据的时候使用的是HTTP命令
    assert_option()可以用来对assert()进行一些约束和控制
    supercool.sh文件里,有哪些恶意的命令
  • 原文地址:https://www.cnblogs.com/52cik/p/modules-path.html
Copyright © 2011-2022 走看看