01-node.js基础
nodejs基础
一、nodejs介绍
1、简介
在我们此时的认知中,js是一门客户端语言,且是一门脚本语言,也就是说只能在浏览器上运行,且只能依赖HTML才能运行。
为了提高js的逼格,让js脱离浏览器和HTML也能运行,一代大神Ryan Dahl在2009年,通过分析将谷歌浏览器中V8引擎(即谷歌浏览器中的js解析器),分离出来,进行了二次封装,做出了一款软件,叫nodejs。
这个软件中可以运行js代码,且不需要依赖浏览器和HTML。
所以说,nodejs本质上是一个js除了浏览器之外的运行环境,使得js除了是一门客户端语言外,还是一门和java、php、ruby平起平坐的服务器端语言。
2、nodejs使用注意事项
- nodejs实现了js代码在浏览器外执行,所以在nodejs中无法运行DOM和BOM的代码
- nodejs中除了ECMAScript代码外,还内置了很多其他API
- nodejs让js在写前端代码的基础上,可以写后端代码,因为nodejs可以构建服务器
相关网址:
3、下载安装
下载安装:http://nodejs.cn/download/
安装.msi文件,傻瓜式下一步安装
安装完成后,没有桌面快捷方式,也不需要有。
安装.zip文件,需要手动配置环境变量
解压zip安装包
将解压后的文件夹改名,并放在指定的安装目录下:
复制当前文件夹路径,配置在系统环境变量中
安装完成。
安装完成测试,打开命令行,输入下列指令:
1 | node -v |
4、nodejs运行
nodejs是执行js代码的环境,执行方式有两种:
在nodejs中直接执行代码(类似于在浏览器控制台执行写js代码并执行)
在命令行中输入node,敲回车,就进入了nodejs的控制台,操作跟浏览器的控制台一样
1
2
3node
console.log(111)
1+2退出这个控制台,通过两次
ctrl+c
或.exit
命令。这种方式无法用来开发代码,因为我们也从来不在浏览器的控制台开发代码,这样的代码只能运行这么一次,下次重新打开就丢失了。
使用nodejs执行js文件
新建js文件,书写规范的js代码,通过命令行的node命令执行这个文件。
执行的文件有两种方式:
当前命令行不在文件所在文件夹下,此时需要将文件的绝对路径 - 不常用
当前命令行在文件所在的文件夹下,此时使用文件的相对路径即可 - 常用
二、简单的命令
打开命令行窗口的方式:
- win+r
- 地址栏输入cmd
- shift+鼠标右击
- vscode中ctrl+反引号
- 开始菜单中输入cmd,点击
命令提示符
或打开
。最万能是选择以管理员身份运行
1 | 盘符: # 进入某个盘符 |
三、模块化开发
1、介绍
因为node命令执行js文件的时候,只能指定一个js文件,所以我们在开发的时候只能将项目所有代码写在一个文件中,可是这样不利于我们进行分工合作,也不利于后期项目的维护,所以需要对js代码进行模块化管理。
所有前端的模块化,都是将一个js文件当做是一个模块,多个模块之间可以互相导入使用。
2、分类
其实在很早之前就有了模块化开发的概念了,前端的模块化开发规范共有以下几种:
IIFE(Immediately Invoked Function Expression)立即调用函数表达式
通过自调用函数模拟模块化,解决了全局变量污染问题。
例:b文件依赖a文件
a文件
1
2
3
4
5
6(function(){
var a = 1
window.moduleA = {
a
}
})()b文件
1
2
3
4
5(function(moduleA){
var b = 2
console.log("导入的模块数据是:", moduleA);
console.log("当前模块数据是" + b);
})(moduleA)最后在html文档中需要导入这两个文件:
1
2
3
4
5
6
7
8
9
10
11
12
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
</body>
<script src="a.js"></script>
<script src="b.js"></script>
</html>结果:
AMD(Asynchronous Module Definition)异步模块定义
由于这个规范不是原生
js
支持的,所以要先引入第三方库文件(RequireJS)才能实现。解决了多个js
文件之间的依赖关系问题。也遗留了一个问题:js
加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间。例:c文件依赖a文件/c文件依赖a文件和b文件/c文件依赖b文件,b文件依赖a文件
a.js文件
1
2
3
4define(function(){
var a = 1
return {a}
})define函数用来定义模块,被别的模块导入。
其中define的参数1表示当前模块的名称,别的模块导入当前模块的时候使用这个名称代表当前模块
b.js文件
1
2
3
4define(['./a.js'], function(moduleA){
var b = 2
return {b,moduleA}
})define函数在定义模块的同时也可以依赖别的模块,如上代码,参数2表示依赖的模块。回调函数中的参数,是在回调函数中使用依赖模块中数据时对别的模块起的别名,或可理解为将别模块使用这个参数接收
c.js文件
1
2
3require(['./b.js'], function(moduleB){
console.log(moduleB)
})require函数作为最终的处理函数,参数1是依赖的模块,参数2是对所有逻辑的处理。
最后在html中运行,首先引入require.js,然后引入c.js即可
1
2<script src="https://cdn.bootcdn.net/ajax/libs/require.js/2.3.6/require.js"></script>
<script src="c.js"></script>最终结果:
最终,c文件要运行,就必须先加载a文件和b文件。如果被依赖的文件中,需要很长时间才能运行结束,后面的文件也需要等待很长时间。所以首屏加载很慢。
CMD(Common Module Definition)通用模块定义
同样不是原生js支持的,所以需要先引入第三方库文件(SeaJS)才能实现。他解决的问题跟AMD是一样的,但他的文件加载时机跟AMD是不一样的,AMD是所有依赖的文件提前加载,CMD是什么需要什么时候加载。
例:
a文件
1
2
3
4define(function(require, exports, module){
var a = 1
exports.a = a
})回调函数中的require是一个函数,用来引入别的模块,exports和module用来导出,其中exports就是module.exports。
b文件
1
2
3
4
5
6
7
8define(function(require, exports, module){
let moduleA = require('./a.js')
var b = 2
module.exports = {
moduleA,
b
}
})require导入别的模块时,使用模块名称导入
c文件
1
2
3seajs.use(['./b.js'], function(module){
console.log(module);
})seajs.use方法表示要使用哪个模块,module是给使用的模块起的别名。
最后在html中先导入sea.js,然后按照依赖顺序导入其他文件:
1
2<script src="https://cdn.bootcdn.net/ajax/libs/seajs/3.0.3/sea.js"></script>
<script src="c.js"></script>最终结果:
因为在seajs中提供了require,所以什么需要时,什么时候调用导入即可,实现了按需导入。
es6的模块化规范
原生js支持,导出用export关键字,导入用import关键字。但必须在服务器环境中才能用,且html使用必须添加:
type="module"
属性。导出语法:
1
2
3export 数据的定义
// 或
export default 数据导入语法:
1
2
3
4import {解构} from '文件'
import * as 对象 from '文件'
import 对象 form '文件'
import 对象, {解构} from '文件'例:
a文件
1
2
3var a = 1
export default a
export var a1 = 11导出时使用default关键字的,当导入时,直接接收到的就是这个数据,如果还有别导出数据,必须解构,否则接收不到。
b文件
1
2export var b = 2
export var b1 = 22没有加default的,表示可以导出多个数据
c文件
1
2export var c1 = 3
export var c2 = 33在html中的使用:
1
2
3
4
5
6
7
8
9
10
11<script type="module">
import moduleA,{a1} from './a.js'
import {b, b1} from './b.js'
import * as obj from './c.js'
import {a1} from './a.js'
console.log(moduleA, a1);
console.log(b, b1);
console.log(obj);
console.log(a1);
</script>导入可以直接将导出数据接收到,并起别名。也可以将导入的所有内容解构。也可以将所有数据组成一个对象
最终结果:
总结:
1
2
3export default {a: 1, b: 2} // 导入可以有 import obj from 文件/import * as obj from 文件
多个export导出的 // 导入可以使用import {结构} from 文件/import * as obj from 文件
export和export default一起导出的 // import XX和import {XX}都只能得到一个数据,要得到所有数据可以使用import * as obj或import obj,{b} from 文件CommonJS - nodejs自带的模块化规范
nodejs中自带的模块化规范,只能在nodejs中使用,导出使用
module.exports
关键字,导入使用require
关键字。
3、CommonJS规范
使用commonjs规范导入导出模块:
导入:
1 | // 导入 |
导出:
1 | // 导出 |
一个文件就是独立的模块,可以理解为是一个独立的作用域,别的模块要用到这个作用域中的数据,就需要将这个作用域中的数据导出,可以理解为函数返回数据的意思。
a.js导出:
1 | let a = 10 |
为了让导出变的更简单,commonjs规范中,在每个模块中定义了一个变量exports,并将module.exports赋值给了exports,导出时可以使用exports:
1 | exports = {a} |
注意:使用exports导出的时候,千万不能直接给exports赋值,因为导出功能是由module.exports提供的,如果直接给exports赋值,就将exports的内存空间换成了另外一个数据空间了,将失去导出功能。
b.js导入:
1 | let data = require('./a.js') |
导入的就是导出的数据,导出数据就接收到数据,导出对象就接收到对象。
注意:导入的文件是自定义的,那路径中的./
是不能被省略的。导入文件的后缀可以省略,因为nodejs中能被导入的只能是js文件。
在nodejs中能被导入的模块分3种:
- 自定义模块 - 文件路径中的
./
不能省略 - 内置模块 - 只需要导入模块名称,不需要路径,因为默认会在系统中找这个文件
- 第三方模块 - 别人写好的js文件,我们需要导入使用,所以必须提前下载好才能被导入使用
四、内置模块
1、fs
fs(file system)模块提供了用于与文件进行交互相关方法。
1 | const fs = require('fs') |
2、os
os(operation system
)模块提供了与操作系统相关的实用方法和属性。
1 | const os = require('os') |
3、path
path模块用于处理文件和目录(文件夹)的路径。
1 | const path = require('path') |
__dirname:是nodejs提供的一个内置变量,代表当前文件所在位置的绝对路径
斜杠和反斜杠:通常用来分割路径,”某个文件夹下”的意思,在windows系统中,斜杠和反斜杠的意义是一样的,但是建议大家写斜杠,反斜杠用在代码中,有特殊含义,转义的意思,在服务器系统中,默认路径就使用斜杠
4、url
url的完整形态:
URL字符串是结构化的字符串,包含多个含义不同的组成部分。 解析字符串后返回的 URL 对象,每个属性对应字符串的各个组成部分。
1 | const url = require('url'); |
例:
1 | const url = require('url') |
5、querystring
用于解析和格式化 URL 查询字符串(URL地址的get形式传参)的实用工具。
1 | const querystring = require('querystring') |
6、http
6.1、服务器介绍
我们做好网页后,为了能让别人访问,需要在计算机上开启一个能被别人访问的服务,这个功能是由web服务器提供的。
web服务器,指的是能提供网站访问服务的软件或代码程序,让别人可以通过ip地址来访问自己计算内部的某些文件。目前最主流的三个Web服务器软件是Apache、 Nginx 、IIS、tomcat。 代码可以有nodejs代码、go语言代码。
软件其实也是由代码组成的,我们要学习的就是用nodejs的代码创建一个web服务器。
6.2、前后端介绍
前端开发是面对用户的客户端上运行的代码,后端开发是面对数据库和前端的开发。
网页中所使用的数据都是存储在数据库中的,但前端无法直接操作到数据库,只有web服务器才能操作到数据库,web服务器中执行的代码开发叫后端开发。
在工作中通常是前端和后端一起开发,前端需要数据,就跟后端交互,后端连接数据库,将数据发送给前端。
6.3、http介绍
nodejs可以通过代码创建web服务器,让js可以是前端语言,也可以是后端语言。
http模块就是nodejs封装在内部专门用于创建服务器的。
6.4、创建服务器
1 | // 导入http模块 |
通常在访问服务器的时候,默认会有一个网站图标的请求,要求服务器提供网站图标。
简写:
1 | require('http').createServer((req, res) => { |
6.5、请求对象
通过请求对象req,可以获取请求的相关信息,例如:请求的客户端ip、请求方式、请求路径。。。
1 | require('http').createServer((req, res) => { |
6.6、响应对象
响应对象可以给客户端响应内容,结束响应、响应状态码、状态描述、响应头等信息
1 | require('http').createServer((req, res) => { |
注意:每次响应一定要结束响应,否则客户端的请求会一直转,请求不到内容。响应结束后就不允许再响应内容了。
6.7、静态资源服务器
假设我们已经写好了一套静态页面,但是需要让别人访问,就需要提供一个服务器,且别人来访问的时候还要能访问到对应的静态页面。这种服务器被称之为静态资源服务器,目的是只为了提供访问静态资源。
1 | const path = require('path') |