浏览器中的javascript运行
- v8引擎负责解析和执行JS代码
- 内置API是由运行环境提供的特殊接口,只能在所属的运行环境中被调用(XMLHttpRequest等)
Node.js可以做什么
- 基于Express框架(http://www.expressjs.com.cn)可以快速构建Web应用
- 基于Electron框架(http://electrongjs.org),可以构建跨平台的桌面应用
- 基于restify框架(http://restify.com),可以快速构建API接口项目
- 读写和操作数据库、创建实用的命令行工具辅助前端开发、etc…
fs模块
const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const pathToFile = path.resolve(__dirname, 'text.txt');
//Error first 异步回调
/* fs.readFile(pathToFile,'utf-8',(err,result)=>{
if(err){
console.log("Error::",err)
return err;
}
console.log("result::",result)
}) */
//同步读取
/* const content = fs.readFileSync(pathToFile,"utf-8");
console.log("SyncContent::",content) */
//将异步回调封装为promise
function promisfy(func){
return function (){
return new Promise((resolve,reject) =>{
[].push.call(arguments,function(err,result){
if(err) return reject(err);
return resolve(result);
});
//由于参数是个类数组
return func.apply(func,arguments);
})
}
}
const readFileAsync = promisfy(fs.readFile);
console.log( readFileAsync(pathToFile,"utf-8").__proto__);
// readFileAsync(pathToFile,"utf-8")
// .then(content =>{
// console.log(content)
// })
// .catch(err => {
// console.log("err::",err)
// })
// ==========================================================
// ==========================================================
// ==========================================================
//读取文件
//异步
// console.log("1");
// fs.readFile("./docs/blog.txt",(err,data)=>{
// if(err){
// console.log(err);
// return;
// }
// console.log(data.toString())
// });
// console.log("3");
//写入文件 不覆盖追加
fs.appendFile("./docs/blog.txt","董志伟yes",()=>{
console.log("success");
});
//文件夹创建和删除
// if(!fs.existsSync("./assets")){
// fs.mkdir("./assets",err=>{
// if (err){
// console.log(err);
// return;
// }
// console.log("文件夹创建成功");
// });
// }else{
// fs.rmdir("./assets",err=>{
// if (err){
// console.log(err);
// return;
// }
// console.log("文件夹删除成功")
// });
// }
//文件删除
// if (fs.existsSync("./docs/blog2.txt")){
// fs.unlink("./docs/blog2.txt",err=>{
// if(err){
// console.log(err);
// return;
// }
// console.log("文件删除成功");
// });
// }
path模块
const path = require('path');
//绝对路径
const resolvePath = path.resolve("a","b","c");
//拼接路径
const joinPath = path.join("a","b","c");
console.log("resolvepath::",resolvePath)
console.log("joinPath::",joinPath)
console.log("filename::",__filename)
console.log("拓展名extname::",path.extname(__filename))
console.log("文件全名basename::",path.basename(__filename))
console.log("文件夹名dirname(路径)",path.dirname(__filename))
http模块
const http = require('http');
const proxy = http.createServer((req, res)=>{
res.writeHead(200, {"dzw":"hello"})
res.setHeader('Content-Type','text/html;charset=utf-8')
res.end("hello world");
})
proxy.listen(8888,()=>{
console.log(`服务器运行中...`)
})
将资源的请求url地址映射为文件的存放地址
// 获取客户端请求的url地址
const url = req.url
// 把请求的 url 地址,映射为本地文件的存放路径
const fpath = path.join(__dirname,url)
请求路径优化
const fpath = path.join(__dirname,"./clock",url)
时间格式化包
// 导入moment包
const dt = moment().format('YYYY-MM-DD HH:mm:ss')
nrm 切换镜像源
# 通过npm包管理器,将rm安装为全局可用工具
npm i nrm -g
# 查看所有可用镜像源
nrm ls
# 将下包的镜像源切换为taobao镜像
nrm use taobao
包的分类
- 项目包
- 开发依赖包(记录到devDependencies节点中的包,只在开发期间会用到)
- 核心依赖包(记录到dependencies节点中的包,在开发环境和生产环境用到)
- 全局包
i5ting_toc
i5ting_toc是一个可以把md文档转为html页面的小工具:
# 将i5ting_toc 安装为全局包
npm i -g i5ting_toc
# 调用, 实现md转html
i5ting_toc -f 需要转换的md文件路径 -o
规范的包结构
一个规范的包,它的组成结构,必须符合以下3点要求:
- 包必须以单独的目录存在
- 包的顶级目录下要必须包含 package.json这个包管理配置文件
- package.json中必须包含 name,version,main 这三个属性,分别代表包的名字、版本号、包的入口
初始化package.json 文件
// 初始化package.json 文件
{
"name":'包名字全球唯一',
"version":"发布的版本",
"main":"入口文件",
"description":"搜索时的一些描述",
"keywords":["一些","关键字"],
"license":"开源协议"
}
发布包到npm
将终端切换到包的根目录之后,运行 npm publish 命令,即可将包发布到npm上
删除已发布的包
运行 npm unpublish 包名 --force 命令,即可从npm删除已发布的包
- npm unpublish 只能删除72小时以内发布的包
- npm unpublish 删除的包,在24小时内不允许重复发布
- 发布的时候要慎重,尽量不要往npm上发布没有意义的包
模块的加载机制
模块在第一次加载后会被缓存。这也意味着多次调用 require() 不会导致模块的代码被执行多次。
- 不论是内置模块、用户自定义模块、还是第三方模块,它们都会优先从缓存中加载,从而提高模块的加载效率。
自定义模块加载机制
不加后缀: 寻找拓展名 (.js) —> (.json) —> (.node)
第三方模块加载机制
从 /ndoe_modules 文件夹中加载第三方模块。
- 如果没有找到,则移动到再上一层父目录中,进行加载,直到文件系统的根目录
目录作为模块
当把目录作为模块标识符,传递给require() 进行加载的时候,有三种加载方式:
- 在被加载的目录下查找一个叫做package.json 的文件,并寻找main属性,作为require()加载的入口
- 如果目录里没有 package.json 文件,或者main入口不存在或无法解析,则Node.js 将会试图加载目录下的index.js文件
- 如果以上两步都失败了,则Node.js 会在终端打印错误消息,报告模块的确实:Error:Connot find module ‘xxx’