zoukankan      html  css  js  c++  java
  • node.js 包管理及模块-node.js 一

    node.js 原理剖析
    模块化概述

    js 不是模块化编程语言,它不支持class
    es6发布后 可以方便在js中使用类和模块了
    -> 模块化规范
    浏览器端规范
    AMD(require.js)遵循的AMD规范(同步执行)
    CMD(Sea.js) 遵循的CMD规范
    ES6
    服务器端规范
    CommonJS(Node.js是CommonJS的实现)
    Node的应用是由模块组成的
    CommonJS特点
    所有代码运行在当前模块作用域,不会污染全局作用域
    模块同步加载,根据代码执行顺序载入
    模块可多次加载,只会在第一次加载的时候运行一次,运行结果被缓存
    以后再次加载模块,会直接从缓存中读取数据
    module对象详解

    module001.js
    let name = 'eval'
    let getName = function (name) {
    console.log(name);
    }
    // 模块导出,暴露在外面
    module.exports = {
    name: name,
    getName: getName,
    }
    person.js
    // 引入 module001.js
    let person = require('./module001.js')
    console.log(person)
    
    // 终端中当前目录执行node person.js
    person.getName('study163')
    // 修改name的值
    person.name = 'updateName'
    console.log(person)
    // 终端中当前目录执行node person.js
    模块分类 
    module对象的属性
    id: 当前模块的id 唯一的;
    exports: 表示当前模块暴露给外部的值。
    parent: 是一个对象,表示调用当前模块的模块。
    children: 是一个对象,表示当前模块调用的模块。
    filename: 模块的绝对路径。
    paths: 从当前模块开始查找node_modules目录,然后依次进入到父目录,查找父目录下的node_modules目录;依次换代,直到根目录下的node_modules目录。
    loaded: 一个布尔值,表示当前模块是否完全加载。
    一直找,直到找到根目录
    03module.js
    // 直接导出一个对象
    module.exports = {
    name: 'evan',
    getName: function (name) {
    console.log(name)
    }
    }
    console.log(module)
    
    核心模块
    Node.js提供的模块,例如http模块,fs模块等,
    核心模块 -----通过编译------二进制文件----node启动时部分核心加载到内存中,因此部分模块不需要手动加载,加载的比较快;
    文件模块
    自己编辑的模块;文件模块是按需加载,加载比较慢。
    module.exports 与exports
    
    都是引用类型变量,指向同一个内存地址,在node中开始都指向空对象
    exports 通过形参的方式传入,直接赋值给形参引用,不能改变作用域外的值
    module.exports就是为了角色exports直接赋值的问题而产生的
    04.module.exports
    var module = {
    exports: {}
    }
    var exports = module.exports;
    function change(exports) {
    // 通过形参的方式传入的exports
    exports.name = 'evan';
    // 下面的直接赋值是错误的,exports的作用域只有这个作用域中,如果这样赋值的话,exports指向的地址(重新指向的新的地址)和module.exports的指向地址就不一样了。
    exports = {
    
    age: 18;
    }
    console.log(exports);
    }
    change(exports)
    
    console.log(module.exports)
    而module.exports 是可以直接赋值的,因为它是外部传进来,而exports则不可以。
    正确写法如下:
    let name = 'ab';
    let text = 'cd';
    module.exports = {
    name, text
    };
    require方法详解
    
    require方法传入的是模块标识符
    
    路径分析 -> 文件定位 -> 编译执行
    
    路径分析(模块标识符分析)
    1.核心模块。
    2. 以'.'或者'../'开始的相对路径文件模块,如果找不到在modules中找,不利于项目迁移。
    3. 以'/'开始的绝对路径模块。
    非路径形式的模块(直接字符串)
    
    文件定位
    
    扩展名分析 .js 、.node文件去找或java扩展
    目标文件和包分析
    o5-load.js
    找课程资料查询
    // 计算绝对路径 
    ...
    // 第一步 如果有缓存,取出缓存。
    ...
    // 第二步 是否为内置模块。
    ...
    // 第三步 生成模块实例,存入缓存(如果上面两步都没有找到,创建)
    ...
    // 第四步 加载模块
    ...
    // 第五步 输出模块的exports属性
    ...
    
    查询路径js 找课程资料查询,一个模块必须有个package.json 和入口文件 index.js
    // 列出所有可能的后缀名: .js 、 .json 、.node
    // 如果是绝对路径就不再搜索
    // 是否有后缀的目录斜杠
    // 第一步 如果当前路径已经缓存中,就直接返回缓存
    // 第二步 遍历所有路径
    // 第三步 是否存在该模块文件
    // 第四步 该模块文件加载后缀名,是否存在
    // 第五步 目录中是否存在package.json
    // 第六步 是否存在目录名+ index + 后缀名
    // 第七步 将找到的文件路径存入返回缓存,然后返回
    // 第八步 提示文件不存在
    
    // npm init 创建package.json 如果目录没有main字段且也没有index.js的话,就提示你什么也没有找到
    // node 运行js node .js文件
    var a = require('./module001.js')
    var b = require('./module001.js')
    console.log(a===b) true
    
    // 因为导出module.exports 多个同一个内容的话,第二次导出会读取缓存,所以是指向同一块地址
    
    node.js 原理剖析
    
    自定义模块和核心模块相同时,自定义模块加载失败

    require方法详解

  • 相关阅读:
    从原生web组件到框架组件源码(二)
    从原生web组件到框架组件源码(一)
    拖拽滚动视图(一)
    SVG研究之路(一)下
    运算符
    编码
    格式化输出
    循环语句
    条件语句
    Python基础
  • 原文地址:https://www.cnblogs.com/TheYouth/p/13953336.html
Copyright © 2011-2022 走看看