一、nodejs创建服务器
index.js文件
// require是node内置的方法
const http = require('http')
const server = http.createServer((req, res) => {
res.write('hello world111222')
res.end()
})
// 设置端口号
server.listen(3000)
命令行⇒ node index.js
打开localhost:3000即可访问
或者下载nodemon可以热重载,直接更新,不需要开关服务器
npm i nodemon -g ⇒ 全局安装nodemon
二、nodejs的模块化
方法一:创建任意目录
- 创建文件,任意命名
- 创建index.js,在index.js里面引入其它文件
- 当引入该文件时,node会自动寻找index.js文件
./home/index.js
require('./a')
// 获取的是module.exports的对象
let P = require('./b')
// 获取P对象里面的Person函数,并且实例化
let person = new P.Person()
console.log('我是index')
// 就可以使用实例对象的方法了
person.hobby()
./home/b.js
console.log('模块b')
let a = 10
class Person{
constructor() {
this.name = 'tom'
}
hobby(){
console.log('swim')
}
}
// 模块导出方法一
// module.exports = {
// a,
// Person
// }
// 模块导出方法二
exports.a = a
exports.Person = Person
命令行 ⇒ nodemon index.js
终端执行结果
方法二:创建node_modules
创建node_modules
里面创建自定义文件,例如 mytest
./node_modules/mytest/index.js
require('./a')
require('./b')
module.exports = {
a : 10,
fn: () => {
console.log('我是fn')
}
}
./index.js
// 因为在node_modules里面,node会做解析,直接写mytest即可
// 或者 ./node_modules/mytest 也可以
let {a, fn} = require('mytest')
console.log(a)
fn()
结果:
如果增加一个package.json,这是一个功能性描述文件
package.json
{
"name": "mytest",
"version": "1.0",
"main": "main.js"
}
当require(‘mytest’)的时候,它首先会解析package.json,然后找到main.js开始解析
tips:实际工作中,如果是我们自己写的模块,就会用方法一,如果是第三方调用的模块,就会放在node_modules里面
三、npm管理包
npm是在下载node的时候就给一并下载的,所以不需要额外下载
当我们需要下载某些好用的模块的时候,就可以通过指令下载
-
cd 当前项目文件
-
npm install jquery
npm i jquery 也一样,i是install的简写 通过npm下载的包会自动放在node_modules里面
- 每一个模块都有一个package.json文件,可以自定义创建,也可以通过指令创建 =>npm init
- 可以对package进行设置,或者不设置,直接enter到底。
- 最后生成一个package.json文件,里面有相关描述
- npm uninstall jquery ⇒ 删除该模块,一并删除package.json文件里面的相关描述
四、npm常用指令
1. npm i module_name
当我们下载一些模块的时候,该模块信息会自动加入到package.json里面
npm i cookie
npm i cookie --save
npm i cookie -S
这三个命令都是同一个功能
当删除模块的时候,该模块信息会自动从package.json里面去除
npm i cookie --save-dev
或者 npm i cookie -D
模块信息会被写道devDependencies里面
dependencies 和 devDependencies的区别:
前者是运行依赖,不仅开发环境会用到,真实环境也需要被用到,例如: jquery,vue,react等
后者是开发依赖,只有在开发的时候会用到,真实运行环境不需要被用到,例如:less,sass
2. npm i
下载所有所需模块
为什么需要package.json?
当项目转移的时候,不需要把node_modules里面的模块一并转移
只需要转移其它部分,当转移之后
- cd 当前项目文件
- npm i
这样就会根据package.json里面的描述,下载对应的模块,可以减少转移项目的包裹容量,提高效率
3. npm root -g
查找全局安装的目录
**node_modules的特性:**当引入node_modules里面的文件时,会依次向上级目录查找node_modules文件,查看里面是不是有对应的文件名。最终会找到node 根目录里面的node_modules
4. npm root
查找当前安装的目录在哪里
5. npm i module_name -g
npm i gulp -g vs npm i gulp
加不加-g的区别
如果这个工具是所有项目都要用到的,就加-g,如果只是当前项目需要用到,就不要加-g,如果加了-g,该工具就会被下载到node根目录里,当前例子就是下载到\nodejs\node_global\node_modules里面
6. npm update module_name
更新对应的模块
7. npm i jquery@3.4.1
如果对版本有需求,可以在后面@版本号,就会下载对应版本
向上箭头表示,当npm i 的时候,这个版本以上的版本都可以使用
- 内置模块如下
8. npm init: 引导创建一个package.json文件
9. npm help(npm -h): 查看npm帮助信息
10. npm version(npm -v): 查看npm 版本
11. npm search: 查找
五、fs文件操作
增删改查
以下方法都要用到fs,所以导入fs模块
- 文件操作
const fs = require("fs")
fs可以修改任何后缀名的文件
1. 文件写入
fs.writeFile("1.txt","hello world you and me111", {flag: "a"},function (err){
if(err){
throw err
}
console.log("successfully")
})
tips: a:追加写入。 w: 覆盖写入。 r: 读取
2. 文件读取
fs.readFile('1.txt','utf8',(err,data)=> {
if(err){
throw err
}
console.log(data)
})
// 或者
fs.readFile('1.txt',(err,data)=>{
if(err){
throw err
}
// 直接打印data就是buffer,二进制形式,toString转换成字符串类型
console.log(data.toString())
})
3. 修改文件名称
fs.rename('1.txt', '2.txt', err => {
if(err){
throw err
}
console.log('successfully')
})
4. 删除文件
fs.unlink('2.txt', err => {
if(err){
throw err
}
console.log('delete successfully')
})
5. 复制文件
fs.copyFile('index.js','myIndex.js',err => {
if(err){
throw err
}
console.log('copy successfully')
})
5.1 自己封装copy函数
function mycopy(origin, target){
origintext = fs.readFileSync(origin,'utf8')
fs.writeFileSync(target, origintext,err => {
if(err){
throw err
}
console.log('copy successfully')
})
}
mycopy('index.js', 'newIndex.js')
6. 所有文件操作,没有加Sync都是异步的,否则就是同步的
let data = fs.readFileSync('1.txt')
console.log(data.toString())
- 目录操作
1. 创建目录
fs.mkdir('mydir', err=> {
if(err){
throw err
}
console.log('create successfully')
})
2. 修改目录名称
fs.rename('mydir', 'newdir', err=> {
if(err){
throw err
}
console.log('rename successfully')
})
3. 读取目录
传参都是文件路径地址
fs.readdir('./newdir',(err, data) => {
if(err){
throw err
}
console.log(data)
})
4. 删除目录(必须是空文件夹)
fs.rmdir('empty', err => {
if(err){
throw err
}
console.log('delete successfully')
})
5. 判断文件或者目录是否存在
fs.exists('index.js', exists => {
console.log(exists)
})
6. 获取文件或者目录的详细信息
fs.stat('index.js', (err, stat) => {
if(err){
throw err
}
// 判断index.js是不是一个文件
// let res = stat.isFile()
// 判断index.js是不是一个目录
let res = stat.isDirectory()
console.log(res)
})
stat.isFile(): 判断是不是一个文件
stat.isDirectory(): 判断是不是一个目录
7. 自定义删除非空目录
function removeDir(path){
let datas = fs.readdirSync(path)
for(let i = 0; i < datas.length; i++){
let fulPath = path + '/' + datas[i]
let stat = fs.statSync(fulPath)
//console.log(stat)
if(stat.isFile()){
fs.unlinkSync(fulPath)
}
if(stat.isDirectory()){
removeDir(fulPath)
}
}
fs.rmdirSync(path)(path)
}
removeDir('./newdir')
六、buffer
1. 创建buffer方法一
let buffer = Buffer.alloc(10)
// 默认buffer(00,00,...00)十个00的字节,根据自定义创建
//<Buffer 00 00 00 00 00 00 00 00 00 00>
console.log(buffer)
2. 创建buffer方法二
let buffer = Buffer.from('hello world')
//hello world
console.log(buffer.toString())
3. buffer的每个字节实际是四位数的,只是被处理成了2位数显示
let buffer = Buffer.from([0x68,0x65,0x6c,0x6c,0x6f,0x20,0x77,0x6f,0x72,0x6c,0x64])
// <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>
console.log(buffer)
4. buffer乱码处理
let buffer = Buffer.from('你好吗')
let buffer1 = Buffer.from([0xe4,0xbd,0xa0,0xe5])
let buffer2 = Buffer.from([0xa5,0xbd,0xe5,0x90,0x97])
// 把字节截断会造成乱码
//console.log(buffer2.toString())
- 处理乱码方法一:Buffer.concat()
let newBuffer = Buffer.concat([buffer1, buffer2])
- 处理乱码方法二:通过string_decoder
let { StringDecoder } = require('string_decoder')
let decoder = new StringDecoder()
let res1 = decoder.write(buffer1)
let res2 = decoder.write(buffer2)
// 你好吗
console.log(res1 + res2)
七、stream 流
当资源过大,而用户的带宽不足以传输该资源,这个时候就要用到stream,stream可以把数据拆分成n个chunk来进行传输,每个chunk是64kb,虽然时间增加,但是不会占用许多带宽资源,提高了效率。
1.txt
hello world
stream.js
const fs = require('fs')
let res = fs.createReadStream('1.txt')
// res.on 是一个循环操作
res.on('data', chunk => {
// hello world
console.log(chunk.toString())
})
创建一个65kb大小的文件,命名为‘65kb’
let buffer = Buffer.alloc(65*1024)
console.log(buffer)
fs.writeFile('65kb', buffer, err=> {
if(err){
throw err
}
})
const fs = require('fs')
// 用读取流处理65kb文件
let res = fs.createReadStream('65kb')
let num = 0
// res.on 是一个循环操作
res.on('data', chunk => {
num++
// 1 2
console.log(num)
})
65kb的文件,res.on执行了2次
const fs = require('fs')
let rs = fs.createReadStream('1.txt')
let ws = fs.createWriteStream('2.txt')
rs.pipe(ws)
- createReadStream,read流来来读文件
- createWriteStream,write流来写文件
- pipe,通过管道写入到ws文件里