什么是CommonJs?
CommonJs就是模块化的标准,nodejs就是CommonJs(模块化)的实现
//app.js中
const obj = {
getTime: () => {
return new Date()
},
getName: () => {
return "kk"
}
}
const obj2 = {
getValue(){
return 666
}
}
exports.obj = obj
// { obj: { getTime: [Function: getTime], getName: [Function: getName] } }
exports.obj = obj
exports.obj2 = obj2
//{
// obj: { getTime: [Function: getTime], getName: [Function: getName] },
// obj2: { getValue: [Function: getValue] }
//}
module.exports = obj
// { getTime: [Function: getTime], getName: [Function: getName] }
module.exports = {obj,obj2}
//{
// obj: { getTime: [Function: getTime], getName: [Function: getName] },
// obj2: { getValue: [Function: getValue] }
//}
// app2.js
const app = require('./app.js')
console.log(app)
Nodejs中的模块化
Node应用由模块组成,采用CommonJs模块规范
在node中,模块有两大类
核心模块:由Node提供的模块
文件模块:由用户编写的模块
-
核心模块部分在Node源代码的编译过程中,编译进了二进制执行文件,在Node进程启动时,部分核心模块就被直接加载进内存中,所以这部分核心模块引入时,文件定位和编译执行这两个步骤可以省略掉,并且在路径分析中优先判断,所以它的加载速度是最快的。如HTTP模块、URL模块、FS模块都是nodejs内置的核心模块,可以直接引入使用。
-
文件模块则是在运行时动态加载,需要完整的路径分析、文件定位、编译执行过程。速度相比核心模块稍微慢一些,但是用的非常多
包与NPM
npm:是世界上最大的开放源代码的生态系统,我们可以通过npm下载各种各样的包,这些源代码(包)我们可以在https://www.npmjs.com中找到
npm 命令详解
- npm i 根据package.json文件的dependencies安装项目依赖模块
npm i
- npm -v 查看npm版本
npm -v
- 使用npm命令安装模块
npm install 模块名(如jquery) --save
- 使用npm命令卸载模块
npm uninstall 模块名
- npm list 查看当前目录下已安装的node包
npm list
- npm info 查看模块的版本
npm info jquery 查看jquery的版本
- 指定版本安装
npm install jquery@3.4.1
包使用步骤
/**
* 1.https://www.npmjs.com 查找需要的包
* 2.npm i 包名 --save (运行时依赖)
* 3.const bar = require('包名')
* 4.查看文档使用
* 5.指定版本安装 npm install jquery@版本号 --save
*/
package.json
package.json 定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证的元数据)
创建package.json
npm init 或者 npm init --yes
package.json文件
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
dependencies: 配置当前程序所依赖的其他包
devDependencies: 配置当前程序所依赖的其他包,比如一些工具之类的配置在这里
^: 表示第一位版本号不变,后面两位取最新的
~: 表示前两位不变,最后一个取最新的
*: 表示全部取最新的
fs模块的使用
/**
* 1. fs.stat 检测是文件还是目录
* 2. fs.mkdir 创建目录
* 3. fs.writeFile 创建写入文件
* 4. fs.appendFile 追加文件
* 5. fs.readFile 读取文件
* 6. fs.readdir 读取目录
* 7. fs.rename 重命名/移动文件
* 8. fs.rmdir 删除目录
* 9. fs.unlink 删除文件
*/
具体使用
const fs = require("fs")
//1. fs.stat 检测是文件还是目录
fs.stat('./html',(err,data)=>{
if(err){
console(err)
return
}
console.log(`是文件${data.isFile}`)
console.log(`是文件${data.isDirectory}`)
})
//2. fs.mkdir 创建目录
/**
* path: 将创建的目录路径
* mode: 目录权限(读写权限), 默认777
* callback 回调,传递异常参数err
*/
//如果已存在,会报错
fs.mkdir('./css',(err)=>{
if(err){
console(err)
return
}
console("创建成功")
})
//3. fs.writeFile 创建写入文件
//如果已存在,会替换
fs.writeFile('./html/index.html','你好,nodejs',(err)=>{
if(err){
console(err)
return
}
console("创建写入文件成功")
})
//4. fs.appendFile 追加文件
//如果文件已存在,内容会追加在已有内容后面,不会覆盖
fs.appendFile('./css/base.css','body{color:red}',(err)=>{
if(err){
console(err)
return
}
console("追加文件成功")
})
//5. fs.readFile 读取文件
fs.readFile('./html/index.html',(err,data)=>{
if(err){
console(err)
return
}
console(data.toString()) //把Buffer转换成string类型
})
//6. fs.readdir 读取目录 (返回文件名和文件夹名的数组)
fs.readdir('./html',(err,data)=>{
if(err){
console(err)
return
}
console(data) //[index.html,demo.css]
})
//7. fs.rename 重命名/移动文件
//功能 1. 表示重命名 2.移动文件
//旧目录:./css/aaa.css 新目录: ./css/index.css
//如果文件路径不存在,会报错
fs.rename('./css/aaa.css','./css/index.css',(err)=>{
if(err){
console(err)
return
}
console("重命名或移动成功")
})
//8. fs.rmdir 删除目录
//如果有该目录有子文件,不能删除
fs.rmdir('./aaaa',(err)=>{
if(err){
console(err)
return
}
console("删除目录成功")
})
//9. fs.unlink 删除文件
fs.unlink('./aaaa/index.html',(err)=>{
if(err){
console(err)
return
}
console("删除文件成功")
})
fs模块练习题
- 判断服务器上面有没有upload目录,如果没有,创建这个目录,如有的话不做操作(图片上传)
- wwwroot文件夹下面有images css js 以及index.html,找出wwwroot目录下面的所有的目录,然后把它们放在一个数组中
//判断服务器上面有没有upload目录,如果没有,创建这个目录,如有的话不做操作(图片上传)
const fs = require('fs')
let path = './upload'
fs.stat(path,(err,data)=>{
if(err){
// 创建目录
mkdir(path)
return
}
if(!data.isDirectory()){
// 删除文件
fs.unlink(path,(err)=>{
if(!err){
// 执行创建目录
mkdir(path)
}else{
console.log("请检查传入的路径是否正确")
}
})
}
})
function mkdir(dir){
fs.mkdir(dir,(err) =>{
if(err){
console.log(err)
return
}
})
}
//wwwroot文件夹下面有images css js 以及index.html,找出wwwroot目录下面的所有的目录,然后把它们放在一个数组中
/**
* 错误的写法 注意:fs里面的方法是异步的
*/
let dirArr = []
let path = './wwwroot'
fs.readdir(path,(err,data)=>{
if(err){
console.log(err)
return
}
console.log(data)
for(let i = 0; i < data.length; i++){
fs.stat(path+'/'+data[i],(error,stats) =>{
if(err){
console(err)
return
}
if(stats.isDirectory()){
dirArr.push(data[i])
}
})
}
})
/**
* 递归 + 自执行 实现
*/
let dirArr = []
let path = './wwwroot'
fs.readdir(path,(err,data)=>{
if(err){
console.log(err)
return
}
(function getDir(i){
fs.stat(path+'/'+data[i],(error,stats) =>{
if(i == data.length){
//执行完成
console.log(dirArr)
return
}
if(error){
console(error)
return
}
if(stats.isDirectory()){
dirArr.push(data[i])
}
getDir(i+1)
})
})(0)
})
mkdirp的使用
生成指定目录,可一次创建多级目录
npm i mkdirp --save
const mkdirp = require('mkdirp')
mkdirp('/tem/foo/bar/baz',(err)=>{
if(err){
console.log(err)
return
}
})
mkdirp("./upload")
Nodejs新特性
- async await 的使用
- 使用 async await 处理异步
简单理解
async 是让方法变成异步
await 是等待异步方法执行完成 await必须得用在async的方法里面
//普通方法
function test(){
return '你好nodejs'
}
console.log(test()) // 你好nodejs
//异步方法
async function test(){
return '你好nodejs'
}
console.log(test()) // Promise{'你好nodejs'}
console.log(await test()) // 错误写法: await必须得用在async的方法里面
//*****************************************
async function test(){
return '你好nodejs'
}
async function main(){
//获取异步方法里面的数据
let data = await test()
console.log(data) // 你好nodejs
}
main()
//*****************************************
async function test(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
let name = "张三"
resolve(name)
},1000)
})
}
async function main(){
// 获取异步方法里面的数据
let data = await test() // 张三
console.log(data)
}
main()
使用 **async await **解决实际问题
const fs = require('fs')
//1.定义一个isDir方法判断一个资源到底是目录还是文件
async function isDir(path){
return new Promise((resolve,reject)=>{
fs.stat(path,(err,data)=>{
if(err){
console.log(err)
reject(err)
return
}
if(data.isDirectory()){
resolve(true)
}else{
resolve(false)
}
})
}).catch(err => {
// console.log(err)
})
}
//2.获取wwwroot里面的所有资源 循环遍历
const path = './wwwroot'
let dirArr = []
function main(){
fs.readdir(path, async (err,data)=>{
if(err){
console.log(err)
return
}
for(let i = 0; i < data.length; i++){
if(await isDir(path + '/' + data[i])){
dirArr.push(data[i])
}
}
console.log(dirArr)
})
}
fs以流的方式读取文件和写入文件
- fs.createReadStream 从文件中读取数据
- fs.createWriteStream 写入文件
- 管道流 复制文件
fs.createReadStream 从文件中读取数据
const fs = require('fs')
let readStream = fs.createReadStream('./data/input.txt')
let count = 0
let str = ''
// 监听读取过程
readStream.on('data',(data)=>{
str += data
count++
})
// 监听读取完成
readStream.on('end',()=>{
console.log(str)
console.log(count)
})
// 监听错误信息
readStream.on('error',(err)=>{
console.log(err)
})
fs.createWriteStream 写入文件 会覆盖
const fs require('fs')
let data = '我是很多很多数据'
let writeStream = fs.createWriteStream('./data/output.tex')
//写入文件
writeStream.write(data)
//标记写入完成
writeStream.end()
//监听写入完成
writeStream.on('finish',()=>{
console.log('写入完成')
})
//监听写入完成
writeStream.on('error',(err)=>{
console.log(err)
})
管道流 主要用于复制文件
const fs = require('fs')
let readStream = fs.createReadStream('./aaa.jpg')
let writeStream = fs.createWriteStream('./data/aaa.jpg')
readStream.pipe(writeStream)
END
网友评论