node误区
nodejs的用途有被很多前端开发者误解,觉得node就是写后端的,但实际去找工作,node开发工程师的岗位非常少,少数是招一个前端然后让你维护一个node后端完成增删改查工作,但仍然非常非常非常少,国内后端更多的是java。
node改变了前端的开发方式
1. 为前端提供开发工具(vue-cli weboack等)
比如我的环境变量文章里有提到对于node的依赖,如果没有node,就没有vue-cli,前端开发会倒退很多,初始化项目会很麻烦,再比如没有webpack,那前端要怎么打包项目呢,还有babel被用来转译 ECMAScript 2015+ 至可兼容浏览器的版本,如果没有node,就没办法用更优雅的js语法来编码。
2.提供线上环境模拟(开发服务)
模拟网络环境,运行前端本地开发服务,方便调试,npm run serve/dev
3.提供中间层服务器渲染(ssr,高流量项目)
与java纯后端服务不同,前端服务负责页面的渲染,高流量项目都需要前端服务中间层,不去做数据和业务逻辑,这个服务只是单纯为了渲染页面。
4.做后端(很少)
极少数项目才会用mode做后端,所以不要以做后端为目的去学node。
node核心操作
- 读写文件
- 开启服务
一、path-路径处理工具
node中global类似于js中window
1. basename:路径最后一部分
2. dirname:目录名,即路径出去最后
js
let path = require("path");
let demo = "./src/a/b/c.js"
console.log(path.basename(demo));
console.log(path.dirname(demo));
输出结果为:
js
c.js
./src/a/b
3. parse:解析路径为对象
js
let demo = "./src/a/b/c.js"
console.log(path.parse(demo));
输出结果为:
js
{ root: '', dir: './src/a/b', base: 'c.js', ext: '.js', name: 'c' }
root为空,因为没有设置根地址,如果把demo增加根路径C:
js
let demo = "C:/src/a/b/c.js"
那么输出结果为:
js
{ root: 'C:/', dir: 'C:/src/a/b', base: 'c.js', ext: '.js', name: 'c' }
4. format:对象解析为路径,与parse相对
js
path.format({ root: 'C:/', dir: 'C:/src/a/b', base: 'c.js', ext: '.js', name: 'c' })
输出结果为:'C:/src/a/b\c.js'
5. resolve:把一个路径解析为绝对路径,常用方法
js
let demo = "C:/src/a/b/c.js"
console.log(path.resolve(__dirname, "./a));
输出结果:
js
C:\learn\code\nodeStudy\nodeTest\a
也可以不传,直接使用:
js
console.log(path.resolve(__dirname));
输出结果:
js
C:\learn\code\nodeStudy\nodeTest
也可以拼接上级目录:
js
console.log(path.resolve("../", "./a"));
输出结果:
js
C:\learn\code\nodeStudy\a
所以第一个参数,既可以给绝对路径,也可以给相对路径。
6. join:路径拼接,单纯拼接路径,用的很少
path模块还有很多方法,其他的可以查文档。
二、process-进程相关
包含了进程相关的信息,本次程序执行会创建一个进程,其相关的信息都存在process中,是全局的,不需要引入。
属性:
1. argv:启动node时的命令行参数
2. execArgv:node命令后的直接参数
js
console.log(process.argv);
console.log(process.execArgv);
然后运行"node node1.js -a -b -c" 输出结果:
js
[
// node程序所在位置
'C:\\software\\node\\node.exe',
// 文件所在位置
'C:\\learn\\code\\nodeStudy\\nodeTest\\node1.js',
// 携带参数
'-a',
'-b',
'-c'
]
[]
比如当我们执行webpack -help时,实际上就是把'--help'放到了process.argv数组中携带参数的位置,webpack在处理时就看这个地方有没有--help,输出用户需要的帮助。 那第二个数组为什么为空?这个地方是执行"node node1.js -a -b -c"时,"node"和"node1.js"之间位置插入的,node本身自带的指令,比如可以执行"node --help"查看node有哪些指令,如果执行时,node携带了指令,那么就会添加到process.execArgv这个数组中。
3. env:用户环境信息
process.env包含了node进程执行时相关的环境信息,这个有在【前端工程与配置】专栏下的【# 前端环境变量的使用与原理】中提到很多,最重要的使用是用来区分环境。
4. stdout和stdin:屏幕输出和输入
js
console.log(process.stdout.write("请输入一个数字"));
// 监听data事件,如果有数据更新,就获取然后打印
process.stdin.on("data", (res) => {
console.log(res);
})
控制台中:
js
$ node node1.js
请输入一个数字true
111
<Buffer 31 31 31 0d 0a>
当然输出Buffer很奇怪,只要改成String就好了:
js
console.log(process.stdout.write("请输入一个数字"));
// 监听data事件,如果有数据更新,就获取然后打印
process.stdin.on("data", (res) => {
console.log(res.toString());
})
但这个仍然存在问题,就会让你一直输入,所以需要退出进程方法:
js
console.log(process.stdout.write("请输入一个数字"));
// 监听data事件,如果有数据更新,就获取然后打印
process.stdin.on("data", (res) => {
console.log(res.toString());
process.exit();
})
这样输入完就直接退出了。 其实比如说创建脚手架,或者一些需要第二步第三步输入的命令,最底层都依赖于这个,实际开发前端工具会有对应的库来解决,所以node对于前端工具真的非常重要。
5. 监听:process是一个可监听队形
在exit()中展示。
方法:
1.cwd():获取当前进程工作目录
js
console.log(process.cwd());
如果当前路径没有改变,那么这个输出与的__dirname 没有区别。
但如果通过cd ../ 命令,跳转到其他的路径,再执行,发现cwd()的路径没有改变,这就是区别。
2.exit():退出进程
js
let num = 0
setInterval(() => {
console.log(num++);
if (num == 5) {
process.exit()
}
}, 500)
每500ms输出一个数字,从0开始递增,当数字等于5时就退出,当然我们还可以结合监听,当num==5时输出"计数完成":
js
let num = 0
setInterval(() => {
console.log(num++);
if (num == 5) {
process.exit()
}
}, 500)
process.on("exit", () =>{
console.log("计数完成")
})
3.memoryUsage():内存使用情况
输出当前内存的使用情况,单位byte。
三、util-工具函数
promisify:把异步回调函数包装为promise形式
allbackify:将一个返回值为Promise的函数改为回调
node几乎所有的异步操作都是通过回调获取结果,第一个参数都是错误,后边的是结果.
js
let util = require("util");
let fs = require("fs");
function f1(n) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(10)
}, 1000)
})
}
const callbackf1 = util.callbackify(f1);
callbackf1(function(errr, num) {
console.log(num);
})
promisify可以把node原生方法变成promise方法,比如js.readFile
js
fs.readFile("./test.txt", (err, content) => {
console.log(content);
})
const promiseReadFile = util.promisify(fs.readFile);
promiseReadFile("./test.txt").then((res) => {
console.log(res);
)}
执行成功会输出buff代码.