前言
记录 nodejs 学习进程。
基础
nodejs
是运行在服务端的基于 ChromeV8 引擎服务端脚本语言,这些基础的概念就不谈了,进入正题;
认识全局变量
__filename
:当前运行脚本文件所在位置;__dirname
:当前运行脚本的目录;process
:进程对象;kill
:杀进程的函数方法;exit
:退出脚本的方法;cpuUsage
:脚本占用的 cpu 使用率;memoryUsage
:内存使用率;env
:脚本运行的环境变量;argv
:脚本启动时,用户输入的命令;
commonJS 模块规范
exports
:一个对象,在这个对象上添加属性,就可以让外部模块引用到该属性;注意不要去修改这个对象本身;module.exports
:对这个属性直接赋值,会覆盖上面的exports
,并且在外部引用时,不需要用属性的方式,而直接是导出的对象(或者是任意的基本类型和其他引用类型),类似 ES6 里面的export default
;require
:引入模块的方法,语法上可以当成是一个函数,返回值是导出的内容,参数是引用的文件路径。
1
2
3
4
5
6
7
8
9
// inner.js
module.exports = function test() {
console.log('test)
};
// outer.js
const fun = require('inner.js');
fun();
// test
webpack 实现模块化的方式
在 JS 中,为了要创建作用域,一般都会通过声明函数的方式来创建一个块级作用域,在 webpack 中,打包过程为每个文件模块都创建了一个函数,从而实现每个文件的内部作用域。
webpack 会为每个文件都执行一次webpack_require
这么一个函数,接收文件路径作为参数;
在函数体内,首先会去 check 这个文件是否已经引入过了(相当于做了模块的缓存),如果没有被引入过,则创建一个对象,并在installedModules
这个全局变量上添加这个对象作为一个属性,该对象的 key 就是路径;
再来说说创建的这个对象,这个对象在函数内部命名为module
,有三个属性,其中有一个属性是exports
,初始时它是一个空对象;随后 webpack 就执行模块代码;
这里要解释一下什么是执行模块代码,webpack 会把模块内部的代码,封装成一个函数,函数接收两个参数,module, exports
,正好对应了我们在子模块代码里用到的两个变量,其中,module
是上面提到的创建的对象,exports
是创建的对象内部的一个属性,所以其实exports
相当于一个module.exports
的引用;
这个函数还没讲完,在函数体内部,是一个eval
函数,我在编译后的代码中看到webpack
把子模块里的代码都转换成了字符串,该字符串作为eval
函数的参数,执行了一遍模块代码(也有通过call
方法去执行的);
所以我们如果在子模块里改变了module.exports
这个对象的引用,那么这个对象指向的内存地址就是新的可以被外部模块接收的;而exports
这个变量指向的对象就还是原来的内存地址,就不会被外部所接收了;
总结来说,外部模块引用的始终是module.exports
这个对象指向的内存地址;
从命令行接收和输出到命令行
前面提到过在全局变量进程process
里有一个argv
的参数,就表示了用户在命令行输入的全部参数,它是一个数组,前两个元素是固定的,第一个是node
命令的完整路径,第二个参数是正在被执行的文件的完整路径;后续的元素就是用户输入的参数列表;另外 nodejs 提供了minimist
库,调用这个库可以让程序更简单的获取到具体key
对应的value
,与普通方式不同的是要求命令行输入用--
符号来标识一对key-value
;
常用实例:
1
2
3
4
5
6
7
8
9
10
// node app.js arg1
const args = process.argv.slice(2);
console.log(args[0]);
// arg1
// 用minimist库
// node app.js --arg1=10
const args = require('minimist')(process.argv.slice(2));
console.log(args['arg1']);
// 10
非阻塞 I/O
- I/O 即输入输出;
- 阻塞 I/O 和非阻塞 I/O 的区别在于,系统接收输入再到输出期间,能不能接收其他输入;
理解要点:
- 确定一个进行 I/O 的系统;
- 思考在 I/O 过程中,能不能进行其他的 I/O。