从零开始学Node.js(三):CommonJS和Nodejs模块、自定义模块

从零开始学Node.js(三):CommonJS和Nodejs模块、自定义模块

CommonJS是什么

​ ​ ​ ​ ​ JavaScript是个面向对象的语言,其标准的API是为了构建基于浏览器的应用程序,没有标准库,CommonJS规范的提出主要为了弥补当前JavaScript没有标准库的缺陷,终极目标时为了提供类似Python、Java这样的标准库。CommonJS写出来的应用除了可以利用JavaScript开发客户端应用之外,还可以写服务端应用程序、命令行工具、桌面图形界面应用程序

​ ​ ​ ​ ​ 叭叭到现在,可能对上面说的还云里雾里的,简单一句话那就是CommonJS是模块化的标准,哪这个Node.js就是CommonJS模块化的实现。

Node.js中的模块化

​ ​ ​ ​ ​ Node应用由模块组成,采用CommonJS模块规范。在Node.js中由两类模块:

  • 核心模块:Node本身提供的模块,该模块在Node源码的编译过程中,编译进了二进制执行文件。在Node进程启动的时候,部分核心模块就已经被加载到内存中,所以这部分核心模块引入的时候,文件定位和编译执行两个步骤可以省略,并且在路径分析中优先判断,所以它的加载速度嗖嗖的。核心模块如在本系列博客的第二篇中介绍的URL模块。
  • 文件模块:用户自定义的模块。运行时动态加载,需要完整的路径分析、文件定位、编译执行过程、速度比核心模块慢。

​ ​ ​ ​ ​ 核心模块不多说,关键是如何自定义模块,以及如果自定义模块,有没有什么需要注意的呢?显然是有的,下面先来唠一下自定义模块的一些规范。

Node.js中自定义模块的规定
  • 可以把公共的功能抽离成为一个单独的js文件作为一个模块,默认情况下该模块的方法/属性外部无法访问。如果要让外部可以访问模块里面的方法或者属性,就必须在模块里通过exports或者module.exports暴露属性或者方法。
  • 在需要使用这些模块的文件中,通过require的方式引入该模块。

如何自定义一个模块

​ ​ ​ ​ ​ 下面我们来自己自定义一个模块,实现这样一个功能,写一个formatApi方法,将参数拼接到指定网址后面。

const http=require('http');
const url=require('url');

function  formatApi(api){
    return "http://www.baidu.com/"+api;
}

http.createServer((req,res)=>{
    res.writeHead(200,"Content-type:text/html;charset:'utf-8'");
    res.write("<head><meta charset='utf-8'></head>");
    res.write("<h2>hello,welcome to nayelya’s blog!</h2>");
    var api=formatApi("helloworld");
    console.log(api);
    res.end();
}).listen(8081);

​ ​ ​ ​ ​ ​ 在当前文件夹下新建一个commonjs01.js,然后新建一个文件夹module,在该路径下命名一个文件叫做tools.js,文件目录如下所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K2H9XCNw-1587044725679)(C:\Users\NayelyA\AppData\Roaming\Typora\typora-user-images\image-20200416204357528.png)]

​​ ​ ​ ​ ​ ​ 首先在tools.js中写入功能代码,然后通过exports或者module方法进行暴露,在common01.js中进行导入即可实现。

const http=require('http');
const tools=require('./module/tools.js');


http.createServer((req,res)=>{
    res.writeHead(200,"Content-type:text/html;charset:'utf-8'");
    res.write("<head><meta charset='utf-8'></head>");
    res.write("<h2>hello,welcome to nayelya’s blog!</h2>");
    var api=tools.formatApi("helloword v2!");
    console.log(api);
    res.end();
}).listen(8081);

​ ​ ​ ​ ​ ​ tools.js代码如下。

function  formatApi(api){
    return "http://www.baidu.com/"+api;
}

exports.formatApi=formatApi;
module和exports的一个比较

​ ​ ​ ​ ​ ​ 在module文件夹下新建一个request.js,这个模块主要用于获取和提交数据。

var obj={
    get:function(){
        console.log("从服务器获取数据...");
    },
    post:function(){
        console.log("提交数据");
    }
}

//你也可以将handwrite替换成其他的东西...
exports.handwrite=obj;

​ ​ ​ ​ ​ ​ 新建commonjs02.js,其中代码如下所示:

const request=require('./module/request.js');

console.log(request);
console.log(request.handwrite);
console.log(request.handwrite.get);

​​ ​ ​ ​ ​ ​ 运行node commonjs02.js,打印结果如下:

{ handwrite: { get: [Function: get], post: [Function: post] } }
{ get: [Function: get], post: [Function: post] }
[Function: get]

​ ​ ​ ​ ​ ​ 暴露模块刚刚也说到了还有module的方式,下面我们来看看咋用,对request.js将暴露方式改成module.exports=obj;

​ ​ ​ ​ ​ ​ 然后再次运行commonjs02.js,不过这次需要修改一下代码。

const request=require('./module/request.js');

console.log(request);
console.log(request.get);
console.log(request.post);

​ ​ ​ ​ ​ ​ 打印结果如下所示。

{ get: [Function: get], post: [Function: post] }
[Function: get]
[Function: post]

​​ ​ ​ ​ ​ ​ 通过打印console.log(request);结果的对比,可以体会一下两者的区别,根据这样的一个区别给出一个使用建议:所有的方法都封装在一个对象里面,建议使用module去暴露,如果方法是独立的,可以使用exports去暴露。下面的代码是用exports去暴露一个独立的方法。

exports.put=function(){
    console.log("put function...");
}

简化自定义模块路径之路

​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 在当前路径下新建一个commonjs03.js,以及新建一个文件夹node_modules,在该文件夹中继续新建一个文件下axios,然后新建一个文件叫做index.js。
在这里插入图片描述
​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 在index.js中写点代码。

exports.put=function(){
    console.log("put function...");
}
exports.delete=function(){
    console.log("delete function...");
}

​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 那么现在我们想要在commonjs03.js中引入node_modules里面对用的axios这个模块。

const axios=require('./node_modules/axios/index');
axios.put();

​ ​ ​ ​ ​ ​ 接着我们换两种别的访问方式,依然可以正常调用!

const axios=require('axios/index');
const axios=require('axios');//这种引入方式就很类似我们引入http模块一样

​ ​ ​ ​ ​ ​ 那接下来再换一种玩法,我们根据下面这个目录创建几个文件/文件夹。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rrA1TXf1-1587044725683)(C:\Users\NayelyA\AppData\Roaming\Typora\typora-user-images\image-20200416213046317.png)]
​ ​ ​ ​ ​ ​ db.js代码如下:

exports.find=function(){
    console.log("find data...");
}
exports.add=function(){
    console.log("add data...");
}

​ ​ ​ ​ ​ ​ 我们想要在commonjs04.js中引入db这个模块。

const db=require('db');
db.add();

​ ​ ​ ​ ​ ​ 运行发现这样写是错误的,报错大意是说找不到这个模块,咦?这是为什么呢?虽然我们在node_modules中定义了db这个模块,但是呢Node.js默认找的是db模块下的index.js,然鹅我们定义的名称是db.js自然找不到了。

​ ​ ​ ​ ​ ​ 那怎么解决这个问题呢?使用package.json去配置模块入口。

package.json

​ ​ ​ ​ ​ ​ 命令行进入db.js所在的文件路径,然后缓缓地输入一行npm init --yes,然后我们就会发现当前db.js的这个路径下多了个东东——package.json。

​ ​ ​ ​ ​ ​ 然后重新运行刚刚的程序,聪明的你就会发现此时add方法成功运行啦!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值