node module system
- 如何创建模块
- 如果使用node核心内建的模块,比如操作系统、文件系统、http请求等
global object和模块的导入导出
- nodejs中对应window的是global
- node核心概念是module。node应用中的每个文件都被看作是一个模块。
我们可以把module打印出来(它看来起来是个全局对象,似乎可以用global.module来打印,但实际上不是)
console.log(module)
console.log(global.module) // undefined
打印出的module中有一个属性是exports,这里它是空的。
- 导出导入模块
假设我们建立一个模块叫做logger。这个模块负责向一个url发出请求,从而获得日志信息。可以看到我们用module.exports.log = log将它导出后,打印module,exports不再为空。
let url = 'http://logger.com'
function log(msg) {
// send an HTTP request
console.log(msg)
}
module.exports.log = log
console.log(module) // exports: { log: [Function: log] },
在app.js中,我们用require将它导入
require('./logger.js') // 用require函数导入模块
// require函数的返回值是:作为参数的模块所导出的对象
console.log(require('./logger.js')) // { log: [Function: log] }
而要使用导出的对象,需要先将require的返回值取一个名字
const logger = require('./logger.js') // require返回的是一个对象,我们需要的函数或变量都在其对象属性上,
// 所以需要先给这个对象命名,再访问其属性
logger.log('message')
在这个例子中,我们只导出一个函数,用对象来访问反而变得很麻烦。所以我们可以直接让exports的值变成我们要导出的函数。
module.exports = log
----
const log = require('./logger.js')
log('message')
path模块
const path = require('path')
const pathObj = path.parse(__dirname)
console.log(pathObj)
/**
// 可以根据打印结果得出一些有用的信息字符串
{
root: '/',
dir: '/Users/.......()',
base: 'nodejs课程',
ext: '',
name: nodejs课程'
}
*/
const pathObj2 = path.parse(__filename)
console.log(pathObj2)
/**
{
root: '/',
dir: '/Users/wangjingjie/Documents/各类图书/1111/alex/1111/11月22日nodejs课程',
base: 'app.js',
ext: '.js',
name: 'app'
}
*/
os模块
const os = require('os')
console.log(os.totalmem()) // 17179869184
console.log(os.freemem()) // 17179869184
// 在node之前,js是无法获取这些信息的,因为之前js只能在浏览器中运行
// 所以就只能操作window或document对象
file system模块
fs中几乎所有方法都是成对出现的,有同步(堵塞)/异步(非堵塞)两种(例如下面的access方法)。我们应该永远使用异步的。因为node是单线程的,如果用node来创建应用后端。同步方法会造成堵塞。
const fs = require('fs')
// 返回参数路径下的所有文件名
let files = fs.readdirSync('./') // [ 'app.js', 'logger.js' ]
console.log(files) // [ 'app.js', 'logger.js' ]
// 这里我和mosh的示例不太一样,mosh这里有错误会输入我们定的内容,而我这里是直接报错,不会输出我想要console输出的信息
fs.readdirSync('$', function(err, files) {
if (err) console.log('Error', err)
else console.log('Result', files)
})
event模块
事件就是提示程序中发生了什么的信号
const EventEmitter = require('events')
const emmiter = new EventEmitter()
// listener的注册必须在emit事件之前,因为事件在emit时会先遍历所有监听者。
// register a listener
emmiter.on('messageLogged', function() {
console.log('listener called')
})
// raise an event
// 参数是事件名
emmiter.emit('messageLogged')
emit事件时,也可以发送参数
// 这里的arg名字随意
// 这里的addListener和on是一样的
emmiter.addListener('logging', (arg) => {
console.log(arg.id) // 1
console.log(arg.msg) // message
})
emmiter.emit('logging', { id: 1, msg: 'message' })
拓展EventEmitter
实际中一般会创建一个类去拓展自带的EventEmitter。