node自定义模块与npm包基础知识笔记1.2

本文介绍了如何使用app.js创建web服务,涉及模块缓存、内置和第三方模块加载,npm包的安装、管理与使用,自定义模块m1.js的开发,以及HTTP服务与时间格式处理。还展示了如何使用npm包如moment和i5ting_toc,以及部署和调试web服务的过程。
摘要由CSDN通过智能技术生成

1,web服务app.js

//模块在第一次加载后会被缓存。这也意味着多次调用 require()不会导致模块的代码被执行多次。
//注意:不论是内置模块、用户自定义模块、还是第三方模块,它们都会优先从缓存中加载,从而提高模块的加载效率
//内置模块优先级级最高,比如自定义模块或者第三方模块和内置模块相同时且同时调用时内置模块优先
//导入需要的模块
// 声明一个变量接收了http处理web服务模块
const http = require("http");

// 声明一个变量接收了fs处理文件系统模块
const fs = require("fs");

// 声明一个变量接收了path处理路径模块
const path = require("path");

//npm第三方模块安装命令
//项目包安装:在cmd命令窗口输入npm install 模块完整名称,简约代码:npm i 模块完整名称,如果需要安装指定的版本则需要在模块名称后面使用@版本号即可
//项目包分两种安装方式,命令npm i 名称   则安装为项目核心依赖包,命令npm i 名称 -D  则安装为项目开发依赖包意思是只在开发时需要
//第三方包都会安装到node_modules文件夹中

//全局包:在cmd命令窗口输入npm i 名称 -g    则安装为全局包,只有工具性质的包才有必要安装为全局包,可以参考这个包的官方说明决定安装为什么包
//全局包会被安装到C:\Users\用户目录\AppData\Roaming\npm\node _modules目录下。这些文件在电脑在是隐藏起来的查找是需要查看隐藏的文件
//卸载全局包:命令npm uninstall 包名 -g

//在cmd命令中输入npm init -y就可以安装package.json文件他可以记录项目所有使用的第三方包的信息
//在新的项目如果同样需要一样的包,在项目目录下使用cmd命令npm i后面不要写任何,则下载所有同样的包,前提是新的项目中有需要的package.json包管理文件信息
//有些包在开发时用到但是上线后不需要用到我们可以把这种包放devDependencies节点中cmd命令为:npm i 包名称 - D  与npm install 包名称 --save-dev
//卸载指定的某个第三方包可以在cmd命令窗口输入npm uninstall 包名称,即可这个命令没有简写模式卸载成功则在package.json文件的信息也会消失
//卸载当前项目所有的第三方包可以在cmd命令窗口输入npm uninstall即可这个命令没有简写模式卸载成功则在package.json文件的信息也会消失

//查看当前的下包镜像源npm config get registry
//将下包的镜像源切换为淘宝镜像源npm config set registry=https://registry.npm.taobao.org/
//检查镜像源是否下载成功 npm config get registry

// nrm全局包
//使用命令npm i nrm -g 将nrm安装为全局可用的工具,使用命令nrm ls 可以查看所有可用的npm包下载镜像地址与简称,地址前面带*号的代表当前使用的地址
//使用命令nrm use 镜像简称   来更加方便的切换npm包下载镜像地址

//i5ting_toc全局包
//安装命令:npm i -g i5ting_toc   i5ting_toc工具可以轻松实现md文件转换为html文件的功能
//转换方法命令:i5ting_toc -f md文件路径 -o   后面的-o意思为转换成功后自动在浏览器打开转换成功的html文件

//上传自己的npm包:
//需要去npm网站上面注册npm账号在cmd命令窗口输入npm login回车,依次输入账号和密码即可,注意密码是隐藏的输入时回车即可
//将终端切换到包的根目录之后,运行npm publish 命令,即可将包发布到npm 上(注意:包名不能雷同),
//运行 npm unpublish 包名--force 命令,即可从npm 删除已发布的包删除成功的24小时内不可重新发布同一个包。如果npm发布超过了72小时则无法再删除

//加载第三方模块机制:如果不是./开头也不是内置模块,node则从当前模块的父目录开始查找,尝试找到./node.modules文件夹从中查找第三方模块如果没有找到则到上一级目录查找直到文件系统根目录为止
//当我们导入的是文件夹而不是包名时,则先找这个文件夹中是否有package.js文件并且是否有main入口没有则找当前文件夹中的index.js文件没有则报错
//声明一个变量导入下载好的第三方moment时间模块
const moment = require("moment");
//自定义模块就是自己定义的js文件,在node调用,自定义模块在调用的时候需要写路径,js后缀名可以省略
//当忽略后缀名时node会根据确却自定义的包名按顺序查找,确却的文件名没有则找.js没有则找.json没有则找.node还是没有则报错
//声明一个变量接收了自定义模块,接收过来的是自定义模块中通过module.exports指向的对象{}
// 我们导入的自定义模块永远以模块内部module.exports指向的对象为准
//加载自定义模块时需要写路径./或者../这些没有则当做第三方模块或内置模块进行加载则会报错
var m1 = require("./m1.js");
console.log(m1);
//调用js内置时间格式
const dt = new Date();
console.log(`js内置时间为:${dt}`);
// 调用导入的自定义模块中的格式化时间
var newDT = m1.dT(dt);
console.log(`自定义模块时间为:${newDT}`);

//导入时间格式化转义mthl字符的包
const ytxx_tools = require("./ytxx_tools");
//测试模块格式化时间是否正常
const dtStr_1 = ytxx_tools.dateFormat(new Date()); //接收格式化后的时间
console.log(`ytxx_tools提供的时间:${dtStr_1}`); //打印
//测试转义html字符是否正常
//console.log(ytxx_tools.htmlEscape);
const htmlStr = '<h1 title="abc">这是h1标签<span>123&nbst;</span></h1>'; //声明变量接收html标签
const str = ytxx_tools.htmlEscape(htmlStr); //传入需要转义的html标签并且接收返回处理的结果
console.log(`转义过的字符${str}`);
//测试还原转义的html字符
const str_1 = ytxx_tools.htmlUnEscape(str); //传入被转义过的字符进行处理,然后接收结果
console.log(`还原转义过的字符${str_1}\n`);

//调用导入的第三方模块moment之中的时间格式化
//详细说明请查看npm网站中的moment文档
//console.log(moment);
const dt_1 = moment().format("YYYY-MM-DD HH:mm:ss");
const dt_10 = `第三方moment时间模块提供的时间:${dt_1}\n`;
console.log(dt_10);

//http操作创建web服务
//声明变量server接收http模块方法中的web服务器实例
const server = http.createServer();
//为web服务器实例的on对象绑定一个request事件,然后设置一个处理函数可以拿到参数:req,res
//req是客户端请求的对象的形参,里面包含客户端相关的属性和数据
//res是响应对象,在客户端请求后服务器通过res响应数据或属性给客户端
server.on("request", (req, res) => {
  //接收用户端请求req中的url地址
  const url = req.url;

  //把客户端请求过来的URL地址映射为具体文件的存放路径
  //原理就是拼接用户请求过来的req里的url地址
  //const fpath = path.join(__dirname, url);

  // 优化客户端请求的url路径,原理就是解决用户请求的url地址太长这样很不方便,我们需要优化减短
  //先定义一个空的变量
  let fpath = "";
  // 如果客户端请求的url地址是/,那么就拼接我们想要优化的url地址
  //这样客户端请求的url地址是/,实际上我们在/前面拼接了url地址,实现了客户端只需要请求/就可以访问到设置好的路径
  if (url === "/") {
    //判断用户请求的url地址为/,则拼接想让用户访问的路径
    fpath = path.join(__dirname, "./clock/index.html");
  } else {
    // 判断用户请求的url不是/,则拼接用户请求的url地址到需要优化的路径
    fpath = path.join(__dirname, "./clock", url);
  }

  // 然后调用fs文件处理模块根据上面拼接的url获取文件判断是否获取成功则响应到客户端
  //根据映射过来的文件路径读取文件内容
  fs.readFile(
    fpath,
    /*"utf8", 发现取消utf8后图片才能正常显示*/ (err, dataStr) => {
      //判断是否读取失败,失败则通过res响应错误的信息404
      if (err) return res.end("404 请求的页面不存在...");
      //判断没有读取失败则响应读取的内容到客户端
      res.end(dataStr);
    }
  );

  //设置默认的响应内容为:404 没有找到请求的内容
  //let content = "<h1>404 没有找到请求的内容...</h1>";

  //页面判断操作
  //判断用户请求的url是否为/或index.html首页
  //判断用户请求的url是否为about.html首页
  //if (url === "/" || url === "/index.html") {
  // content = "<h1>首页</h1>";
  //} else if (url === "/about.html") {
  //  content = "<h1>关于页</h1>";
  //}

  //响应操作
  //接收客户端请求req中的method类型
  const method = req.method;
  //接收客户端请求过来的url地址与method类型
  //${}是一种占位符
  const str_url = `正在请求的url地址是:${url}`;
  const str_method = `\n正在请求的method类型是: ${method}`;

  //调用res中的setHeader方法解决响应中文数据到客户端乱码的问题
  //第一个参数为响应头:"Content-Type"值是:"text/html;charset=utf-8"
  //但是在响应html文件时使用后丢失html里的css与js
  //res.setHeader("Content-Type", "text/html; charset=utf-8");

  //在控制台输出客户端请求的url地址和method类型
  console.log(
    str_url,
    "\n时间:",
    (newDT = m1.dT(dt)),
    dt_10,
    str_method,
    "\n时间:",
    (newDT = m1.dT(dt)),
    dt_10
  );
  console.log(`本次响应到客户端的路径:${fpath}\n时间:${newDT}${dt_10}`);
  //调用res.end()方法:向客户端发送指定的数据内容,并结束这次请求的处理过程
  //向客户端发送str的文本内容
  //根据客户端请求的数据响应对应的html内容
  //res.end(`服务器响应过来的数据:<br>${str_url}<br>${str_method}<br>${content}`);

  console.log("服务器运行正常... \n时间:", newDT, dt_10);
});

//启动服务器
//cmd路径命令:cd空格加当前文件路径回车切换
//node空格加当前文件名回车启动服务器
server.listen(9999, () => {
  console.log("web服务器已启动... \n时间:", newDT, dt_10);
  //在控制台输出可以访问当前wbe服务的域名IP和端口
  console.log(
    "访问该服务器的IP域名和端口为: http://*********.com:9999 \n时间:",
    newDT,
    dt_10
  );
});

2,自定义模块m1.js

//这是一个自定义的模块,为node提供
//作用域:模块内定义的成员(这里指变量等等...)无法被外界访问,只能在模块内使用
console.log("加载自定义模块:m1");
const age = 20;

//module对象可以让外界访问到当前模块内的成员
//模块化遵循的是CommonJS规范,每个模块的module变量是一个对象代表当前模块,module里的exports属性是一个对外接口
// Node加载模块时其实都是加载module.exports属性
//下方输出module对象到在cmd命令窗口可以看见module对象详细
console.log(module);

//因为module.exports的写法比较复杂,官方优化后我们只需要写后面的exports即可
console.log(exports === module.exports); //打印到控制台查看两者默认的状态下是否相同,相同则结果为真
//下面使用module.exports向外界提供模块内的变量成员使用,默认是空的对象{}
//相当是挂载一个属性
exports.username = "大哥大";
//下面使用module.exports向外界提供模块内的处理函数方法成员使用
//下方单独使用了exports其实还是module.exports只是写法简单化而言
exports.sayHello = function () {
  console.log("二狗子");
};
//下面使用module.exports定义一个属性接收模块内的成员向外界提供模块内已经定义过的成员
exports.age = age;
//下方让module.exports指向新的对象,之前指向的旧对象会消失
//发现单独使用exports无法实现指向全新的对象,需要加全module.exports
//因为node导入模块时永远以module.exports指向的对象为准
//下面module.exports指向了新的的空间,之前的所有旧指向都被掐断了
//但是单独使用exports玩法覆盖module.exports开辟新的空间,所以已经有一个空间的情况下单独使用exports无法实现指向全新的对象
//因为不管是谁开辟了新的空间,node导入模块时永远以module.exports开辟的空间为准
exports = {
  nickname: "二哥",
  sayHi() {
    console.log("你好");
  },
};
//既然都以module.exports指向为准,那我们用module.exports指向exports那么exports就都能被指向
module.exports = exports;
//我们在当前module.exports指向的空间挂载一个成员
module.exports.age = "红楼梦";
//我们在当前module.exports指向的空间使用exports挂载一个成员
//在一个模块中module.exports和exports建议只使用一个,这样防止带来很多的痛苦混乱
exports.age_1 = "西游记";

//定义格式化时间方法
function dateFormat(dtStr) {
  // 声明变量dt接收时间
  // 使用new调用一个时间的对象Date出来返回给形参dtStr
  var dt = new Date(dtStr);
  //下方的padZero是自定义的补零函数,给不是两个数字的时间前面加个0为了让时间看起来更加好看
  var y = dt.getFullYear(); //声明变量接收时间对象里的年份
  var m = padZero(dt.getMonth() + 1); //声明变量接收时间对象里的月份
  var d = padZero(dt.getDate()); //声明变量接收时间对象里的日期

  var hh = padZero(dt.getHours()); //声明变量接收时间对象里的小时
  var mm = padZero(dt.getMinutes()); //声明变量接收时间对象里的分
  var ss = padZero(dt.getSeconds()); //声明变量接收时间对象里的秒
  //拼接时间和日期动态
  return `${y}-${m}-${d} ${hh}:${mm}:${ss}\n`;
}
//给上面时间补零
function padZero(n) {
  return n > 9 ? n : "0" + n; //如果n大于9则不操作直接返回n,否则在n的前面加字符串0,最后return结束当前函数并且返回函数的结果出去
}
setInterval(function () {
  //定时器每秒调用一次dateFormat(),实现实时更新时间
  dateFormat();
}, 1000);
//使用module .exports对外暴露我们定义的时间
module.exports.dT = dateFormat;

3,启动cmd命令启动 web服务app.js图

 

4,上面使用的npm包已经上传到npm网站,只需要根据1,web服务app.js文件中的指引,到npm网站上面下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值