# node 如何获取命令行传来的参数
process
是一个全局变量,它提供当前 Node.js 进程的有关信息,而 process.argv
属性则返回一个数组,数组中的信息包括启动 Node.js 进程时的命令行参数
// {
// "scripts": {
// "serve": "node test.js arg1 arg2",
// }
// }
// test.js
const arguments = process.argv.splice(2); // ['arg1', 'arg2']
其他参数
- process.argv[0] 启动 Node.js 进程的可执行文件所在的绝对路径
- process.argv[1] 当前执行的文件的 JS 文件路径
- process.argv.splice(2) 命令行参数
关于获取命令行传来的参数还可以结合 commander 的
commander.parse(process.argv);
# node 有哪些相关的文件路径
__dirname
被执行的 js 所在文件夹的绝对路径__filename
返回被执行的 js 的绝对路径process.cwd()
node 命令时所在的文件夹的绝对路径./
当前目录../
相对路径,上级目录
# node 相关的 path API
path.dirname()
: 返回 path 的目录名path.join()
:所有给定的 path 片段连接到一起,然后规范化生成的路径path.resolve()
:方法会将路径或路径片段的序列解析为绝对路径,解析为相对于当前目录的绝对路径,相当于 cwd 命令
join 是直接拼接 path 片段, resolve 是解析路径并返回
# node 文件如何读取
代码语言:javascript复制const fs = require('fs');
// 同步
try {
fs.unlinkSync('文件');
console.log('已成功删除文件');
} catch (err) {
// 处理错误
}
// 异步回调
fs.unlink('文件', (err) => {
if (err) throw err;
console.log('已成功地删除文件');
});
// promisify
const fs = require('fs/promises');
(async function(path) {
try {
await fs.unlink(path);
console.log(`已成功地删除文件 ${path}`);
} catch (error) {
console.error('出错:', error.message);
}
})('文件');
# node 的 URL 模块是用来干嘛的?
对 url 的字符串解析、url 拼接等
url.parse
可以将一个 url 的字符串解析并返回一个 url 的对象url.format
将传入的 url 对象编程一个 url 字符串并返回
# node 的 http 模块创建服务与 Express 或 Koa 框架有何不同?
express = http 模块 中间件 路由
http 实现
代码语言:javascript复制const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, {
'content-type': 'text/plain'
});
res.write('hello node');
res.end();
});
server.listen(3000);
express 实现
代码语言:javascript复制const express = require('express');
const app = express();
app.use(middleware1);
app.use(middleware2);
app.get('/', (req, res) => {
res.send('hello express');
});
app.listen(3000, () => {
console.log('listen at 3000');
})
function middleware1(req, res, next) {
// before next()
next();
// after next()
}
function middleware2(req, res, next) {
// before next()
next();
// after next()
}
# Express 和 Koa 框架中间件有什么不同
express 中间件:通过 next 的机制,即上一个中间件会通过 next 触发下一个中间件(层层递归)
koa2 中间件:通过 async/await 实现,中间件执行顺序是 “洋葱圈模型”(精简彪悍)
- koa compose,利用闭包和递归
const Koa = require('koa');
const app = new Koa();
app.use(middleware1);
app.use(middleware2);
app.listen(3000);
async function middleware1(ctx, next) {
// before next()
await next();
// after next()
}
async function middleware2(ctx, next) {
// before next()
await next();
// after next()
}
# 什么是模板引擎
模板引擎是一个通过结合页面模板、要展示的数据生成HTML页面的工具,本质上是后端渲染(SSR)的需求,加上Node渲染页面本身是纯静态的,当我们需要页面多样化、更灵活,我们就需要使用模板引擎来强化页面,更好的凸显服务端渲染的优势
常见模板引擎
- art-templat 号称效率最高的,模版引擎
- ejs 是一个 JavaScript 模板库,用来从 JSON 数据中生成 HTML 字符串
- pug 是一款健壮、灵活、功能丰富的模板引擎,专门为 Node.js 平台开发
# node 如何利用多核 CPU 以及创建集群
代码语言:javascript复制nodejs 是基于 V8 引擎构建的,一个 nodejs 进程只能使用一个 CPU(一个 CPU 运行一个 node 实例),如果有多核 CPU,可以启动多个进程来利用多核 CPU
const cluster = require('cluster');
const os = require('os');
const express = require('express');
const path = require('path');
const ejs = require('ejs');
const app = express();
const numCPUs = os.cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
for (let i = 0; i < numCPUs; i) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.get('/', (req, res, next) => {
res.render('index.ejs', { title: 'ejs' });
});
app.listen(3000, () => {
console.log(`Worker ${process.pid} started`);
})
}
cluster.fork()
的本质上还是使用 child_process.fork()
,虽然 1 个 Master 和 多个 Worker 进程会对端口监听自动进行负载均衡。