Node.js(day3)
一、模块系统
1.什么是模块
Node.js中常用的核心模块有:
- http模块
- fs文件系统模块
- url模块
- path模块
- os系统模块
在使用Node.js中我们发现每个js之间是没有联系的,都是单独的一个作用域,这就是模块系统的设计。(相关概念请参考CommonJs规范)
简言之,Node.js中的js不像普通的js具有全局变量,而是以模块(文件)为作用域,不会污染其他文件。而用户书写的js就是自定义模块,下载安装的就是第三方模块,自带的js就是核心模块。
既然模块没有了全局作用域,那么我们需要使用模块就需要进行加载和导出通信规则。 - 加载:
require() - 导出:
exports | module.exports
2.exports和module.exports的区别
首先两者都是js文件(模块)用于导出变量的对象,如果你执行这样的语句:
console.log(exports === module.exports);
你会发现结果为true。也就是说这两个变量其实是指向同一个对象的引用。
底层源码类似这样:
var module = {
exports:{}
}
var exports = module.exports;
所以我们可以使用exports或module.exports来导出变量。其实exports的作用就是简化module.exports的书写而已。
但是需要注意的是,不能对exports直接赋值,类似exports = function(...);这样就切断了var exports = module.exports;这一关系。而底层最后执行的是return module.exports,所以使用exports时注意不能进行赋值操作即可。
3.require加载规则
直接说结论:
require加载本质上都是在加载文件来实现模块功能
- 加载自定义模块
我们在加载自定义文件时只需要写明文件路径即可(基本都会使用相对路径)。
比如在我们需要在a.js中价值b.js。(假设在同一级目录),我们只需要写:
var bExports = require('./b');//后缀可省略
另外,require有一个加载机制就是:优先从缓存加载。
比如现在同级目录下还有一个c.js,且b.js和a.js中都有require('./c')这样的语句。
结果就是:执行a.js --> 加载b.js -->加载c.js -->结束。
注意,这里c.js并不会加载两次,这是require得优先从缓存加载机制决定的,第一次加载c.js之后会将导出的变量保存到缓存中,下次需要加载c.js时直接从缓存中取出使用即可。这样的机制提高了加载效率。
- 加载核心模块
对于核心模块的加载,我们可能没有见到什么js文件,这其实是Node.js为了用户方便使用直接为我们提供了模块对于的名称,比如http就代表http模块,require('http')其实也是加载了文件的,只是不是直接加载js文件,而是编译后的二进制文件。 - 加载第三方模块
首先要使用第三方模块必须使用npm下载安装。
比如加载art-template模块,我们只需要:
var template = require('art-template');
第三方模块最终也是加在执行js文件,寻找需要加载文件的步骤为(以require(art-template)):
- 在执行的js文件的同级文件目录下寻找
node_modules文件夹(npm安装的时候会自动创建) - 在node_modules下找到art-template目录
- 找到package.json文件,读取键为
main的值,一般为index.js。 - 加载找到的js文件。
- 以上情况为正常情况,也可能出现node_modules、art-template、package.json文件、main值找不到的情况,如果是art-template能找到,后面的文件找不到会默认执行index.js,如果index.js也不存在这是会
向上一级查找node_modules目录,然后重复以上查找规则,直到找到或查找值磁盘根目录,如果最终都没有找到可以执行的文件会报cannot find module 'art-template'的错误信息。
二、包说明文件
上面说到require()在加载第三方模块时会使用到package.json文件,这个文件就是包说明文件。包说明文件中包含了关于包(模块)的相关信息,比如入口main、依赖dependencies等。
当我们使用npm install art-template安装art-template模块时,发现生成的node_module文件目录下除了art-template还有许多其他模块,这是因为art-template模块本身也依赖了其他的一些模块,所以也需要安装,以此类推依赖包的依赖包也需要安装。
但是这样会存在一个问题,当我们的项目很大,使用的模块也变多的时候,我们可能会忘记我们使用了哪些依赖包,所以我们希望在某个文件下将依赖包的信息记录下来,这是package.json包说明文件的另一个作用。
在安装目录下新建一个package.json文件,内容为{}(必需),我们安装模块时常用下面语句(--save)
npm install art-template --save
然后打开package.json文件,发现多了依赖信息:

这样,我们就能记录项目的依赖包信息。(高版本的npm无论有没有--save都会产生一个package-lock.json文件,里面记录的是本次下载安装所有依赖包信息)
我们不必每次都手动创建package.json文件,而是使用npm init来创建。
然后会出现一步一步让我们填写关于本项目的基本信息,可一路回车,使用默认设置。另:npm init --y可跳过设置,直接初始化完成。然后我们发现目录下创建了一个package.json文件,并写入了相关信息:

三、npm常用命令
- 版本查看
npm --version
npm -v
- 更新npm
npm insatll npm --global
- 安装包
npm install
npm install 包名
npm intsall 包名 --save
- 卸载包
npm uninstall
npm uninstall 包名
npm uninstall 包名 --save
- 使用帮助
npm help
npm 命令 --help
- 简写形式
--version 简写为 -v
install 简写为 i
uninstall 简写为 un
--save 简写为 -S
--help 简写为 -h
--global 简写为 -g
四、解决npm被墙的问题
某些npm包资源需属于境外资源,可能被墙,这种时候可能出现安装较慢或失败的情况,为了解决这个问题可以安装npm的国内镜像:cnpm
cnpm是淘宝团队对npm在国内的备份,官网地址:点这里
安装很简单:
//必需安装到全局
npm insatll cnpm -g
然后使用cnpm进行包安装即可,例如:
cnpm install art-template
五、初体验:第三方模块Express
Express是高度集成的http模块,提高了我们直接使用http模块进行开发web服务器的效率。
相关介绍及使用可参考官网Express。
1.安装
npm install express --save
2.helloWorld
var express = require('express');
//创建web服务
var app = express();
//创建服务器窗口
app.listen(8000,function(){
console.log('server running...');
});
//get请求事件
//当以get方式请求为'/'时触发
app.get('/',function(req,res){
res.send('hello express.你好express!');
});
//当以get方式请求为'/about'时触发
app.get('/about',(req,res) => {
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>About me</title>
<meta charset="utf-8">
</head>
<body>
<h1>我是Express...</h1>
</body>
</html>
`
);
});
访问情况:



我们发现express相比http简化了一些,首先是api比较简单,其次是对请求的url进行了处理,我们不用再使用request.url来注意判断,,然后是访问不到的路径也进行了处理,最后就是Conten-Type也不需要我们手动设置了。当然express的优点不止这些,后续会逐渐用到。
3.express处理静态资源文件
在之前的http核心模块中我们如果要访问某个目录下的资源文件,需要进行统一处理,然后再根据request.url来判断并使用fs文件系统模块来读取文件并输出到页面,但在express中,我们只需要对目录进行简单的静态处理即可(首先创建一个public目录,里面放置一些资源文件方便试验),我们只需要在刚才的文件中使用这个一个api即可:
//对目录进行静态资源处理,并使用
app.use('/public',express.static('./public'));
访问结果:


相关说明
- express仅用了一个api就完成了http中需要进行相关判断的操作,且不需要手动创建fs模块来读取文件。
express.static('路径')可以将路径转换为可通过url直接访问的静态资源文件。app.use('url访问路径',静态资源文件)是设置静态资源访问的路径,如果不设置默认为/。
更多有关Express的使用请参考下一篇文章。
Node.js(day3)的更多相关文章
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- 利用Node.js的Net模块实现一个命令行多人聊天室
1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...
- Node.js:进程、子进程与cluster多核处理模块
1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...
- Node.js:理解stream
Stream在node.js中是一个抽象的接口,基于EventEmitter,也是一种Buffer的高级封装,用来处理流数据.流模块便是提供各种API让我们可以很简单的使用Stream. 流分为四种类 ...
- Node.js:Buffer浅谈
Javascript在客户端对于unicode编码的数据操作支持非常友好,但是对二进制数据的处理就不尽人意.Node.js为了能够处理二进制数据或非unicode编码的数据,便设计了Buffer类,该 ...
- node.js学习(二)--Node.js控制台(REPL)&&Node.js的基础和语法
1.1.2 Node.js控制台(REPL) Node.js也有自己的虚拟的运行环境:REPL. 我们可以使用它来执行任何的Node.js或者javascript代码.还可以引入模块和使用文件系统. ...
- Node.js npm 详解
一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...
- Node.js入门(一)
一.Node.js本质上是js的运行环境. 二.可以解析js代码(没有浏览器安全级的限制): 提供系统级的API:1.文件的读写 2.进程的管理 3.网络通信 三.可以关注的四个网站: 1.https ...
- Node.js学习笔记——Node.js开发Web后台服务
一.简介 Node.js 是一个基于Google Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效.Node.j ...
随机推荐
- Revit二次开发 推荐
学习revit二次开发,建议还是先把revit熟悉一下,去建立一下模型,亲自感受一下是如何创建模型的流程,其中会遇到什么问题.这样在自己做二次开发的时候,一些问题自己就能提前想到,规避掉.我大概用了半 ...
- Springboot 打jar包分离lib,配置文件正确方式
文章来源:https://my.oschina.net/xiaozhutefannao/blog/1932764 POM.xml <?xml version="1.0" en ...
- Redis的n种妙用,分布式锁,分布式唯一id,消息队列,抽奖……
介绍 redis是键值对的数据库,常用的五种数据类型为字符串类型(string),散列类型(hash),列表类型(list),集合类型(set),有序集合类型(zset) Redis用作缓存,主要两个 ...
- syslog-ng源码安装问题
title: 2019-4-22 tags: 新建 author:yangxiaoyi --- 问题:在源码安装syslog-ng软件时执行./configure遇到如下报错, require eve ...
- VIM系统复制粘贴
1 需求 系统复制粘贴主要是满足下面两个需求. 在多个对象之间复制粘贴 vim窗口与vim窗口之间 外部界面与vim窗口之间 不变复制粘贴.从外部界面复制粘贴到vim窗口时,文本不发生任何变化. 2 ...
- MongoDb安装和快速入门
1.Mongodb安装 2.mongodb的增删改查 3.MongoDB数据类型 4.Mongodb $关键字 $修改器 5.MongoDB 之 "$" 的奇妙用法 6.Mongo ...
- oracle主键和索引
主键:能够唯一标识一条记录的字段为主键(亦或主码),不能重复的,不允许为空.作用:用来保证数据完整性个数:主键只能有一个 索引:作用:是提高查询排序的速度个数:一个表可以有多个索引 常用索引类型:No ...
- C# 神奇的Web services 请求超时问题 排查分析
服务器上有两个接口,一个是Web Services(asmx文件)接口,一个是MVC API (普通的GET请求接口) 神奇的事情是这样的,只要我使用WebRequest请求两次,再使用Web Ser ...
- 如何优化UI布局?
Android系统中填充布局是一个开销巨大的过程,每一个额外的嵌套布局和包含的View,都直接影响到应用程序的性能和响应能力.为了使应用程序流畅地运行和快速地响应,重要的是尽可能地保持布局的简单和避免 ...
- [CF1093G]Multidimensional Queries
[CF1093G]Multidimensional Queries 题目大意: \(k(k\le5)\)维空间中有\(n(n\le2\times10^5)\)个点.\(m\)次操作,操作包含一下两种: ...