Node中的模块系统(art-template)

Node中的模块系统

使用Node编写应用程序主要就是在使用:

  • EcmaScript语言

    • 和浏览器一样,在Node中没有Bom和Dom
  • 核心模块

    • 文件操作的fs
    • http服务操作的http
    • url路径操作模块
    • path路径处理模块
    • os操作系统信息
  • 第三方模块

    • art-template
    • 必须通过npm来下载才可以使用
  • 自己写的模块

    • 自己创建的文件

什么是模块化

  • 文件作用域(模块是独立的,在不同的文件使用必须要重新引用)【在node中没有全局作用域,它是文件模块作用域】
  • 通信规则
    • 加载require
    • 导出exports

CommonJS模块规范

在Node中的JavaScript还有一个重要的概念,模块系统。

  • 模块作用域

  • 使用require方法来加载模块

  • 使用exports接口对象来导出模板中的成员

    加载require

    语法:

    var 自定义变量名 = require('模块')
    
    // 用来获取机器信息
    var os = require('os');
    // 用来操作路径
    var path = require('path');
    
    // 获取当前机器的CPU信息
    // console.log(os.cpus());
    
    // memory内存
    // console.log(os.totalmem());
    // 获取一个路径中的扩展部分
    // extname extension name
    console.log(path.extname('c:/a/b/c/d/hello.md'));
    
    
    a.js
    // require 是一个方法
    // 它的作用就是用来加载模块的
    // 在 Node 中,模块有三种:
    //    具名的核心模块,例如 fs、http
    //    用户自己编写的文件模块
    //      相对路径必须加 ./
    //      可以省略后缀名
    //      相对路径中的 ./ 不能省略,否则报错
    //    在 Node 中,没有全局作用域,只有模块作用域
    //      外部访问不到内部
    //      内部也访问不到外部
    //      默认都是封闭的
    //    既然是模块作用域,那如何让模块与模块之间进行通信
    //   有时候,我们加载文件模块的目的不是为了简简单单的执行里面的代码,更重要是为了使用里面的某个成员
    var foo = 'aaa';
    console.log('a start');
    
    function add(x, y) {
        return x + y;
    }
    // Error: Cannot find module 'b'
    // require('b')
    
    
    // 可以
    // require('./b.js');
    // 推荐:可以省略后缀名
    require('./b');
    console.log('foo的值是:', foo);
    
    b.js
    console.log('b start');
    var foo = 'bbb';
    require('./c')
    console.log('b end');
    
    
    c.js
    console.log('ccc');
    

    作用:

    • 执行被加载模块中的代码
    • 得到被加载模块中的exports导出接口对象

    导出exports

    • Node中是模块作用域,默认文件中所有的成员只在当前模块有效

    • 对于希望可以被其他模块访问到的成员,我们需要把这些公开的成员都挂载到exports接口对象中就可以了

      导出多个成员(必须在对象中):

      exports.a = 123;
      exports.b = function(){
          console.log('bbb')
      };
      exports.c = {
          foo:"bar"
      };
      exports.d = 'hello';
      

      导出单个成员(拿到的就是函数,字符串):

      module.exports = 'hello';
      

      以下情况会覆盖:

      module.exports = 'hello';
      //后者会覆盖前者
      module.exports = function add(x,y) {
          return x+y;
      }
      

      也可以通过以下方法来导出多个成员:

      module.exports = {
          foo = 'hello',
          add:function(){
              return x+y;
          }
      };
      

模块原理

exports和module.exports的一个引用:

console.log(exports === module.exports);	//true

exports.foo = 'bar';

//等价于
module.exports.foo = 'bar';

当给exports重新赋值后,exports!= module.exports.

最终return的是module.exports,无论exports中的成员是什么都没用。

真正去使用的时候:
	导出单个成员:exports.xxx = xxx;
	导出多个成员:module.exports 或者 modeule.exports = {};

总结

// 引用服务
var http = require('http');
var fs = require('fs');
// 引用模板
var template = require('art-template');
// 创建服务
var server = http.createServer();
// 公共路径
var wwwDir = 'D:/app/www';
server.on('request', function (req, res) {
    var url = req.url;
    // 读取文件
    fs.readFile('./template-apche.html', function (err, data) {
        if (err) {
            return res.end('404 Not Found');
        }
        fs.readdir(wwwDir, function (err, files) {
            if (err) {
                return res.end('Can not find www Dir.')
            }
            // 使用模板引擎解析替换data中的模板字符串
            // 去xmpTempleteList.html中编写模板语法
            var htmlStr = template.render(data.toString(), { 
                title: 'D:/app/www/ 的索引',
                files:files 
            });
            // 发送响应数据
            res.end(htmlStr);
        })
    })
});
server.listen(3000, function () {
    console.log('running....');
})
1.jQuery中的each 和 原生JavaScript方法forEach的区别:
	提供源头:
    	原生js是es5提供的(不兼容IE8),
        jQuery的each是jQuery第三方库提供的(如果要使用需要用2以下的版本也就是1.版本),它的each方法主要用来遍历jQuery实例对象(伪数组),同时也可以做低版本forEach的替代品,jQuery的实例对象不能使用forEach方法,如果想要使用必须转为数组([].slice.call(jQuery实例对象))才能使用
2.模块中导出多个成员和导出单个成员
3.301和302的区别:
	301永久重定向,浏览器会记住
    302临时重定向
4.exports和module.exports的区别:
	每个模块中都有一个module对象
    module对象中有一个exports对象
    我们可以把需要导出的成员都挂载到module.exports接口对象中
	也就是`module.exports.xxx = xxx`的方式
    但是每次写太多了就很麻烦,所以Node为了简化代码,就在每一个模块中都提供了一个成员叫`exports`
    `exports === module.exports`结果为true,所以完全可以`exports.xxx = xxx`
    当一个模块需要导出单个成员的时候必须使用`module.exports = xxx`的方式,=,使用`exports = xxx`不管用,因为每个模块最终return的是module.exports,而exports只是module.exports的一个引用,所以`exports`即使重新赋值,也不会影响`module.exports`。
    有一种赋值方式比较特殊:`exports = module.exports`这个用来新建立引用关系的。
    
posted @ 2021-05-08 22:32  .爬行的蜗牛  阅读(159)  评论(0编辑  收藏  举报
Document