目录
2、http、url模块的简单例子以及supervisor的使用
lianxi.js---fs的简但使用,使用前先执行npm i fs --save安装fs模块
待续
运行命令:node 指定文件名称.js ---例node app.js或者node lianxi.js
1、nodejs的安装与配置
下载地址:https://nodejs.org/zh-cn/download/
根据自己运行的平台,选择合适的安装包,下载完成后就一直下一步就可以
我在安装的过程中,自定义了node的安装路径,这时需要做环境配置,
因为我已经安装完成,所以这里截了个网上的示例,在这一步确定自己的安装路径
我自己的node安装路径:D:\softInstall\node
修改NPM的缓存目录和全局目录路径,使nodejs正确地调用对应的模块:
在D:\softInstall\node目录下创建两个目录,分别是node_cache和node_global,这是用来放安装过程的缓存文件以及最终的模块配置位置。配置完成后,执行下面这两个命令:
npm config set prefix "D:\softInstall\node\node_global"
npm config set cache "D:\softInstall\node\node_cache"
将npm的全局模块目录和缓存目录配置到我们刚才创建的那两个目录
配置环境变量:
同时按WIN+R键,打开“运行”对话框,输入sysdm.cpl,高级->环境变量,打开环境变量的配置,将D:\softInstall\node\node_global添加到用户变量的Path中,如图
在系统变量里边添加NODE_PATH=>D:\softInstall\node\node_modules,如图
至此nodejs安装配置完毕,打开cmd,输入node -v,npm -v(node中自带的)
2、http、url模块的简单例子以及supervisor的使用
//app.js
const http = require("http");
const url = require("url");
http.createServer((req,res) => {
// 设置响应头
res.writeHead(200,{ 'Content-Type':'text-plain','charset':'utf-8' }); //设置响应地字符集类型
res.write(`<head><meta charset="utf-8" /></head>`); //保证浏览器中的字符集与响应地一致,确保不会出现中文乱码
if("/favicon.ico" === req.url) return //排除多余的响应
// http://localhost:3000/?name=zhangsan&age=60
let query = url.parse(req.url,true,true).query //传统的API
console.log(query) //{ name: 'zhangsan', age: '60' } ,获取传入的参数
// console.log(new URL("http://localhost:3000/?name=zhangsan&age=60")) //whatwg标准
res.end("hello,world!你好世界.") //结束响应
}).listen(3000);
console.log('server is running at http:127.0.0.1:3000')
未安装supervisor,启动命令:进入应用的根目录执行----node app.js
安装supervisor:npm i -g supervisor
执行:supervisor app.js
supervisor会不停的监听应用下的所有文件,发现有文件被修改,就重新载入程序文件从而实现部署,修改了程序文件后马上就能看到变更后的结果。就不用在每次修改后都重新执行node app.js
3、commonJs、nodeJs模块、自定义模块
**commonJs: 详解
Node 应用由模块组成,采用 CommonJS 模块规范。
每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
如果想在多个文件分享变量,必须定义为
global
对象的属性。例如:global.name = "zhangsan"
CommonJS规范规定,每个模块内部,
module
变量代表当前模块。这个变量是一个对象,它的exports
属性(即module.exports
)是对外的接口。加载某个模块,其实是加载该模块的module.exports
属性。/* exports:首先对于本身来讲是一个变量(对象),它不是module的引用,它是{}的引用,它指向module.exports的{}模块 module.exports:首先,module是一个变量,指向一块内存,exports是module中的一个属性,存储在内存中,然后exports属性指向{}模块 exports只能使用.语法向外暴露内部变量 例 exports.xxx=xxx module.exports既可以通过点语法,也可以直接赋值一个对象 例 module.exports.xxx=xxx => module.exports=xxx 如果一个模块的对外接口,就是一个单一的值,不能使用exports输出,只能使用module.exports输出。 如果你觉得,exports与module.exports之间的区别很难分清,一个简单的处理方法,就是放弃使用exports,只使用module.exports。 */ module.exports = { serve:"http:127.0.0.1", } // exports.serevr = "http:127.0.0.1"
require
方法用于加载模块,例如 const serve = require("./modules/config")commonJs的特点:
- 所有代码都运行在模块作用域,不会污染全局作用域。
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
- 模块加载的顺序,按照其在代码中出现的顺序。
**nodeJs模块:核心模块、文件模块(用户编写的模块)
核心模块:全局对象、全局变量、process、console、util、Events、EventEmitter、error、fs、http、url、path等
文件模块:
config.js
/*
exports:首先对于本身来讲是一个变量(对象),它不是module的引用,它是{}的引用,它指向module.exports的{}模块
module.exports:首先,module是一个变量,指向一块内存,exports是module中的一个属性,存储在内存中,然后exports属性指向{}模块
exports只能使用.语法向外暴露内部变量 例 exports.xxx=xxx
module.exports既可以通过点语法,也可以直接赋值一个对象 例 module.exports.xxx=xxx => module.exports=xxx
*/
module.exports = {
serve:"http:127.0.0.1",
}
// exports.serevr = "http:127.0.0.1"
db.js
exports.db = "我的入口文件需要通过package.json配置,否则识别不到"
/* node默认加载 node_modules/文件夹/index.js 如果想其它名称的文件也被默认加载,需要配置入口文件 */
执行 npm init --yes
test/index.js
exports.test = "我是test文件,我位于node_modules文件下,可以直接通过‘require('test')’获取"
在app.js中引入模块:
const http = require("http");
const url = require("url");
const serve = require("./modules/config")
const db = require("db")
const test = require("test")
http.createServer((req,res) => {
// 设置响应头
res.writeHead(200,{ 'Content-Type':'text-plain','charset':'utf-8' }); //设置响应地字符集类型
res.write(`<head><meta charset="utf-8" /></head>`); //保证浏览器中的字符集与响应地一致,确保不会出现中文乱码
if("/favicon.ico" === req.url) return //排除多余的响应
// http://localhost:3000/?name=zhangsan&age=60
let query = url.parse(req.url,true,true).query //传统的API
console.log(query) //{ name: 'zhangsan', age: '60' } ,获取传入的参数
// console.log(new URL("http://localhost:3000/?name=zhangsan&age=60")) //whatwg标准
console.log(serve) //{ serve: 'http:127.0.0.1' }
console.log(db) //{ db: '我的入口文件需要通过package.json配置,否则识别不到' }
console.log(test) //{ test: "我是test文件,我位于node_modules文件下,可以直接通过‘require('test')’获取" }
res.end("hello,world!你好世界.") //结束响应
}).listen(3000);
console.log('server is running at http:127.0.0.1:3000')
4、fs模块以及async和await的使用
lianxi.js---fs的简但使用,使用前先执行npm i fs --save安装fs模块
/*
fs模块,async、await
fs.stat(path--文件路径,callback--回调函数(参数为,err和stats--当前文件的信息)) 检测是文件还是目录
fs.mkdir(path--路径,mode--目录权限,默认0777,callback--回调函数(参数-err)) 创建目录
fs.writeFile(path--路径,data--写入数据,callback--回调(参数-err)) 创建写入文件
fs.appendFile(path--路径,data--追加数据,callback--回调(参数-err)) 追加文件
fs.readFile(path--路径,callback(err,data)) 读取文件
fs.readdir(path--路径,callback(err,files)) 读取目录
fs.rename(oldPath,newPath,callback(err)) 重命名
fs.rmdir(path,callback(err)) 删除目录
fs.unlink(path,callback(err)) 删除文件
*/
const fs = require("fs")
let path = "./www/"
/*
//检测是文件还是目录
fs.stat(path,(err,stats) => {
if(err) return
console.log(stats.isDirectory()) //判断当前文件是否为目录
console.log(stats.isFile()) //判断当前文件是否为文件
})
*/
/*
// 创建目录
fs.mkdir(path+"test",(err) => {
if(err) return
console.log("创建成功")
})
*/
/*
// 创建写入文件,新的内容会覆盖旧的内容
fs.writeFile(path+"testW.html","ahahah1",(err) => {
if(err) return
console.log("写入成功")
})
*/
/*
//追加文件,不会覆盖之前的文件
fs.appendFile(path+"testW.html","asghagsh",(err) => {
if(err) return
console.log("追加成功")
})
*/
/*
// 读取文件
fs.readFile(path+"testW.html",(err,data) => {
if(err) return
console.log(data.toString())
})
*/
/*
//读取目录
fs.readdir(path,(err,files) => {
if(err) return false
console.log(files)
})
*/
/*
// 重命名
fs.rename(path+"/testW.html",path+"/testw.html",(err) => {
if(err) return
console.log("重命名成功")
})
*/
/*
// fs.rmdir 删除目录
fs.rmdir(path+"/test",(err) => {
if(err) return
console.log("删除成功")
})
*/
/*
// fs.unlink 删除文件
fs.unlink(path+"/testw.html",(err) => {
if(err) return
console.log("删除成功")
})
*/
fs流文件的使用
lianxi1.js
// 以流的方式读取数据
const fs = require("fs")
let path = "./www/text",count = 0,str="",path1 = "./www/out"
let readStream = fs.createReadStream(path)
// readStream.on("data",(data) => {
// count ++
// str += data
// })
// readStream.on("end",() => {
// console.log(str,count)
// })
// readStream.on("error",(err) => {
// console.log(err)
// })
// 以流的方式写入文件
// for(let i=0;i<100;i++) {
// str +="ahahahahahahahahaha哈归属感\n"
// }
let writeStream = fs.createWriteStream(path1)
// writeStream.write(str)
// // 想要监听写入完成的状态,必须加上下方部分
// writeStream.end()
// writeStream.on("finish",() => {
// console.log("写入完成")
// })
// 管道流--用于文件的复制
readStream.pipe(writeStream)
console.log("程序执行完毕")
使用案例:
1)上传图片时判断服务端是否含有upload目录
const fs = require("fs")
let path = "./www/upload"
const mkdirp = require("mkdirp")
// 创建目录的方法
// let mkdirF = (dir) => {
// fs.mkdir(dir,(err) => {
// if(err) throw new Error(err)
// console.log("创建和成功")
// })
// }
// fs.stat(path,(err,data) => {
// if(err) { //如果地址不存在,则创建
// mkdirF(path)
// }else {
// if(data.isDirectory()) {
// console.log("当前目录存在")
// }else { //如果为文件,删除文件,创建目录
// fs.unlink(path,(err) => {
// if(err) throw new Error(err)
// mkdirF(path)
// })
// }
// }
// })
// 使用npm的模块--mkdirp npm i mkdirp --save
// https://www.npmjs.com/package/mkdirp
mkdirp('./www/upload').then(made => {
console.log(made) //创建路径--新创建的文件才会输出,已存在会输出undefined
})
2)实现获取指定文件夹里的目录--async+await(用于处理异步数据)
async
函数返回一个 Promise 对象,可以使用then
方法添加回调函数。当函数执行的时候,一旦遇到await
就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
const fs = require('fs')
// 判断传入的地址是目录还是文件
let isDirectory = async (ele) => {
return new Promise((resolve, reject) => {
fs.stat(ele, (err, data) => {
if (err) {
reject(err);
return;
} else {
if (data.isDirectory()) {
resolve(true)
} else {
resolve(false)
}
}
})
})
}
let path = './www'
let getDir = (path) => {
let dirArr = []
return new Promise((resolve, reject) => {
fs.readdir(path, async (err, data) => {
if (err) throw new Error(err);
for (let i = 0; i < data.length; i++) {
if (await isDirectory(path + "/" + data[i])) {
dirArr.push(data[i]);
}
}
resolve(dirArr)
})
})
}
getDir(path).then(res => console.log(res)) //[ 'test', 'upload' ]