nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块

nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块

  • 1.什么是CommonJs
  • 2.Nodejs中的模块化
    • 2.1 核心模块
    • 2.2 文件模块
  • 3.自定义模块
    • 3.1 CommonJs(Nodejs)中自定义模块的定义
    • 3.2 自定义模块的使用
      • 3.2.1 定义和暴露单个函数:
      • 3.2.2 定义和暴露多个函数:
    • 3.3 node_modules文件夹和其他文件夹的区别
      • 3.3.1 一般使用情况
      • 3.3.2 node_modules的省略写法
      • 3.3.3 如何自定义默认模块入口

1.什么是CommonJs

JavaScript 是一个强大面向对象语言,它有很多快速高效的解释器。然而, JavaScript 标准定义的 API 是为了构建基于浏览器的应用程序。并没有制定一个用于更广泛的应用程序的标准库。CommonJS 规范的提出,主要是为了弥补当前 JavaScript 没有标准库的缺陷。它的终极目标就是:提供一个类Python,Ruby 和 Java 语言的标准库,而不只是让 JavaScript 停 留在小脚本程序的阶段。用 CommonJS API 编写出的应用,不仅可以利用 JavaScript 开发客户端应用,而且还可以编写以下应用。
1、服务器端 JavaScript 应用程序(比如nodejs)
2、命令行工具
3、桌面图形界面应用程序

CommonJS 就是模块化的标准,nodejs 就是 CommonJS(模块化)的实现。

希望了解模块化发展历程的同学可以参考下《理解前端模块概念:CommonJs与ES6Module》这篇文章。

2.Nodejs中的模块化

Node应用由模块化组成,采用CommonJs模块规范。在Node中模块分为两类:一类是核心模块,一类是文件模块

2.1 核心模块

核心模块就是Node提供的模块,比如HTTP模块、URL模块、Fs模块就是nodejs内置的核心模块。这类模块是可以直接引入使用的,因为核心模块在Node源代码的编译过程中,编译进了二进制文件,在node进程启动时,核心模块就直接加载进了内存中,所以在核心模块引入时,文件定位和编译执行这两个步骤是可以省略的,并且在路径中优先判断,所以加载速度也是最快的。

2.2 文件模块

文件模块,就是用户自己编写的模块,因此在运行时需要动态加载,所以需要完整的路径分析、文件定位、编译执行过程,所以速度比核心模块会慢一些,但是使用的情况是非常多的。

3.自定义模块

3.1 CommonJs(Nodejs)中自定义模块的定义

(1)我们可以把公共的功能抽离成为一个单独的 js 文件作为一个模块,默认情况下面这 个模块里面的方法或者属性,外面是没法访问的。如果要让外部可以访问模块里面的方法或者属性,就必须在模块里面通过 exports 或者 module.exports 暴露属性或者方法。
(2)在需要使用这些模块的文件中,通过 require 的方式引入这个模块。这个时候就可 以使用模块里面暴露的属性和方法。

3.2 自定义模块的使用

3.2.1 定义和暴露单个函数:

(1)单独定义和暴露模块函数
tools.js:

// 定义tools模块的函数formatApi
function formatApi(api){
  return 'http://www.sheldon.com/' + api
}

// 暴露模块函数
exports.formatApi = formatApi

(2)使用模块函数
common01.js:

var http = require('http');
// 引入tools模块
var tools = require('./module/tools.js')
console.log(tools)
http.createServer((req, res)=> {
  res.writeHead(200,{"Content-Type":"text/html;charset=utf-8"});  // 解决乱码
  // 使用tools模块中的formatApi
  var api = tools.formatApi('userlist/1')
  res.write(api)
  res.end();
}).listen(3001);

console.log('Server running at http://127.0.0.1:3001/');

在终端:
nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第1张图片
在浏览器中:
在这里插入图片描述

3.2.2 定义和暴露多个函数:

(1)将多个函数放到同一个对象中进行暴露:
request.js:

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

exports.xxx = obj

(2)使用模块函数
common02.js:

var request = require('./module/request')
console.log(request)  // { xxx: { get: [Function: get], post: [Function: post] } }
console.log(request.xxx.get())

nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第2张图片
可以看到此时多个函数封装在一个对象中,并且作为模块的一个属性(属性名称随意,使用时能对上即可,大多数情况下和对象名称相同,方便记忆)提供使用。

(3)更加推荐的写法——对象直接作为模块暴露
request.js:

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

// exports.xxx = obj

module.exports = obj

common02.js:

var request = require('./module/request')
console.log(request)  // { get: [Function: get], post: [Function: post] }
console.log(request.get())

nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第3张图片

(4)等价写法——定义和暴露同时进行
request.js:

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

// exports.xxx = obj

// module.exports = obj

exports.get = function(){
  console.log('从服务器获取数据')
}
exports.post = function(){
  console.log('提交数据')
}

common.js:

var request = require('./module/request')
console.log(request)  // { get: [Function: get], post: [Function: post] }
console.log(request.get())

nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第4张图片

3.3 node_modules文件夹和其他文件夹的区别

3.3.1 一般使用情况

(1)定义模块
node_modules/axios/index.js:

exports.get = function(){
  console.log('从服务器获取数据')
}
exports.post = function(){
  console.log('提交数据')
}

(2)使用模块
common03.js:

const axios = require('./node_modules/axios/index.js')
axios.get()
axios.post()

nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第5张图片

3.3.2 node_modules的省略写法

(1)省略node_modules:
nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第6张图片
(2)省略index.js:
nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第7张图片
可以看到省略了node_modules和index.js,common03.js中仍然能够找到axios,这是因为Nodejs在定义模块时会默认寻找node_modules文件夹下的对应文件夹下的index.js文件作为输出模块文件。

3.3.3 如何自定义默认模块入口

如果定义模块文件不是index.js会发生什么呢?
(1)定义模块
node_modules/db/db.js:

exports.add = function(){
  console.log('添加数据')
}
exports.search = function(){
  console.log('查询数据')
}

(2)使用模块
common04.js:

const db = require('db')

nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第8张图片
可以看到common04.js根本找不到模块db,这是因为db文件夹下根本没有index.js文件

(3)自定义模块入口
进入db文件夹,执行命令npm init --yes,即可生成package.json文件(有时候会看不到,刷新下文件夹即可),并且自定义默认入口为db.js
nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第9张图片
nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第10张图片
此时再执行common04.js:

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

nodejs项目实战教程03——CommonJs、Nodejs模块和自定义模块_第11张图片

下一章 nodejs项目实战教程04——npm相关概念及其使用

你可能感兴趣的:(nodejs项目实战,javascript,前端,node.js,模块化,nodejs模块化)