您的位置:首页 > Web前端 > Node.js

node.js模块,require,underscore

2017-11-29 17:09 302 查看

node.js 模块

在 node.js 开发中一个文件就可以认为是一个模块。

一、node.js 模块分类

核心模块 Core Module、内置模块、原生模块

fs

http

path

url



所有内置模块在安装node.js的时候就已经编译成 二进制文件,可以直接加载运行(速度较快)

部分内置模块,在 node.exe 这个进程启动的时候就已经默认加载了,所以可以直接使用。

文件模块

按文件后缀来分

如果加载时,没有指定后缀名,那么就按照如下顺序依次加载相应模块

1. .js

2. .json

3. .node(C/C++编写的模块)

自定义模块(第三方模块)

mime

cheerio

moment

mongo



二、require 加载模块顺序

看 require() 加载模块时传入的参数是否以 ‘./’ 或 ‘../’ 或 ‘/’ 等等这样的路径方式开头(相对路径或绝对路径都可以)

是,那么会按照传入的路径直接去查询对应的模块。

传入的是否为具体的文件名

require(‘./test.js’) 是具体的文件名

直接根据给定的路径去加载模块,找到了加载成功,找不到加载失败

require(‘./test’); 不是具体的文件名、

第一步:根据给定的路径,依次添加文件后缀 .js、.json、.node进行匹配,如果找不到匹配执行第二步

第二步:查找是否有 test 目录(尝试找 test 包)

找不到:加载失败

找到了:依次在 test 目录下查找 package.json 文件(找到该文件后尝试找 main 字段中的入口文件)、index.js、index.json、index.node,找不到则加载失败

不是,那么就认为传入的是 “模块名称”(比如:require(‘http’)、require(‘mime’))

是核心模块:直接加载核心模块

不是核心模块

依次递归查找 node_modules 目录中是否有相应的包

从当前目录开始,依次递归查找所有父目录下的 node_modules 目录中是否包含相应的包

如果查找完毕磁盘根目录依然没有则加载失败

打印输入 module.paths 查看

// require('http')
// require('mime')

// 情况一:require() 的参数是一个路径
require('./index2.js')

// index2.js
// index2.json
// index2.node
// index2 文件夹 -> package.json -> main(入口文件 app.js -> index.js/index.json/index.node) -> 加载失败
require('ndex2')

// 情况二: require() 的参数不是路径,直接就是一个模块名称
// 1. 先在核心模块中查找,是否有和给定的名字一样的模块。如果有,则直接加载该核心模块。
// require('http')

// 2. 如果核心模块中没有该模块那么就会认为这个模块是一个第三方模块(自定义模块)
// 先会去当前js文件所在的目录下去找是否一个一个 node_modules 文件夹
// require('mime')


require 加载模块注意点

所有模块第一次加载完毕后都会有 缓存,二次加载直接读取缓存,避免了二次开销

因为有 缓存,所以模块中的代码只在第一次加载的时候执行一次

每次加载模块的时候都优先从缓存中加载,缓存中没有的情况下才会按照 node.js 加载模块的规则去查找

核心模块在 Node.js 源码编译的时候,都已经编译为二进制执行文件,所以加载速度较快(核心模块加载的优先级仅次于 缓存加载)

核心模块都保存在 lib 目录下

试图加载一个和 核心模块 同名的 自定义模块(第三方模块)是不会成功的

自定义模块要么名字不要与核心模块同名

要么使用路径的方式加载

核心模块 只能通过 模块名称 来加载(错误示例:require(‘./http’); 这样是无法加载 核心模块 http的 )

require() 加载模块使用 ./ 相对路径时,相对路径是相对当前模块,不受执行 node 命令的路径影响

建议加载文件模块的时候始终添加文件后缀名,不要省略。

三、补充 CommonJS 规范

CommonJS 规范

模块的定义

总结:CommonJS 是为 JavaScript 语言制定的一种 模块规范、编程 API规范

node.js 遵循了 CommonJS规范

关于 node.js 中 Module 详细介绍

Module

underscore模块介绍

文档

官方文档

中文文档

在npm中搜索underscore

参考描述

1、Underscore is a JavaScript library that provides a whole mess of useful functional programming helpers without extending any built-in objects.

2、Underscore 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象。 他解决了这个问题:“如果我面对一个空白的 HTML 页面,并希望立即开始工作,我需要什么?” 他弥补了 jQuery 没有实现的功能,同时又是 Backbone 必不可少的部分。

Underscore 提供了100多个函数,包括常用的:map、filter、invoke — 当然还有更多专业的辅助函数,如:函数绑定、JavaScript 模板功能、创建快速索引、强类型相等测试等等。


模板语法介绍:

<%= %>
, 中间写表达式

<%    %>
, 中间写语句

参考写法

提示:underscore库建议使用’_’来命名对象,类似于jQuery使用$来命名

// 案例一:
var html = '<h1><%= name %></h1>';
var compiled = _.template(html);
var result = compiled({name: 'aaaa'});
console.log(compiled);

// 案例二:
// 构建模板字符串
var html = '<%for (var i = 0; i < 5; i++) { %><h1><%= name %></h1><% }%>';

// 编译模板
var compiled = _.template(html);

// 进行模板字符串替换
var result = compiled({name: '张三'});

// 输出后的结果
console.log(result);


underscore中_.template()函数返回值其实就是一个函数:

function(obj){
var __t;
var __p = '';
var __j = Array.prototype.join,print = function () {
__p += __j.call(arguments,'');
};

with(obj||{}) {
__p += '<h1>' + ((__t = (name)) == null ? '' : __t) + '</h1>';
}
return __p;
}


url模块介绍

当服务器处理 get 请求时,用户请求的参数是在 request 的 url 属性中,纯字符串,使用起来并不方便

url 模块可以更方便地解析用户 get 请求提交上来的参数

具体使用

加载模块
var url = require('url');


调用
parse()
方法解析

url.parse(urlString[, parseQueryString[, slashesDenoteHost]]);
var urlObj = url.parse(reqUrl, true);

// url对象的pathname属性,获取不包含查询字符串的url
// url对象的query属性中包含的就是请求字符串的键值对对象


模块化

什么是模块?

每个.js文件就是一个模块

从npm上下载的一个包(可能是由多个文件组成的一个实现特定功能的包)也是一个模块

任何文件或目录只要可以被Node.js通过
require()
函数加载的都是模块

每个模块就是一个独立的作用域,模块和模块之间不会互相”污染”

我们可以通过编程的方式,指定某个模块要对外暴露的内容(其实就是指定require的返回值,通过require的返回值对外暴露指定内容)。这个对外暴露内容的过程也叫”导出”
module.exports


为什么要进行模块化

方便代码管理、项目维护

有助于分工协同开发

模块和模块之间不会出现变量”污染”,一个模块就是一个作用域。

模块化可以做到职责分离,每个模块实现一个独立的功能

补充:面向对象编程的5(6)大原则:

- 开放封闭原则

- 里氏替换原则

- 依赖倒置原则

- 单一职责原则

- 接口隔离原则

什么是包?

通过package.json描述的一个文件或目录(可以理解成一个实现某个功能的1个文件或多个文件,通过package.json组织起来)

包不一定能被Node.js通过
require()
来加载,那么就不就叫模块。比如有些包中没有设置启动文件(package.json中的main字段),就不是模块。

package 和 module 参考链接

在Node.js中模主要分为:核心模块 和 文件模块

核心模块

http、fs、path、url、net、os、readline、……

核心模块在Node.js自身源码编译时,已经编译成二进制文件

部分核心模块在Node.js进程启动的时候已经默认加载到缓存里面了

文件模块(包含独立文件模块和第三方模块)

文件模块可以是:.js 模块、.node模块、*.json模块,这些都是文件模块

无论从npm上下载的第三方模块还是我们自己编写的模块都是文件模块

module.exports 和 exports

在每个模块中module表示当前模块对象, 里面保存了当前模块对象的各种信息

module.exports 其实就是 require()加载模块时的返回值

exports 就是module.exports的一个引用

exports = module.exports;


特别注意:最终暴露给require的返回值的是:module.exports, 而不是exports

“`javascript

// To illustrate(说明) the behavior, imagine this hypothetical implementation of require(), which is quite similar to what is actually done by require():

function require(…) {

var module = { exports: {} };

((module, exports) => {

// Your module code here. In this example, define a function.

function some_func() {};

exports = some_func;

// At this point, exports is no longer a shortcut to module.exports, and

// this module will still export an empty default object.

module.exports = some_func;

// At this point, the module will now export some_func, instead of the

// default object.

})(module, module.exports);

return module.exports;

}

“`

require 加载模块时做了2件事

执行了模块中的代码

返回了模块中对外暴露的内容(可能是对象、函数等等)

JavaScript 的严格模式——
"use strict";
'use strict';

参考链接:

http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  node.js url path